xref: /AOO41X/main/sd/source/filter/eppt/epptso.cxx (revision 24c56ab9f1bd1305754aa2f564704f38ff57627e)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 #include <osl/endian.h>
27 #include <eppt.hxx>
28 #include "epptdef.hxx"
29 #ifndef _PptEscherEx_HXX
30 #include "escherex.hxx"
31 #endif
32 #include <tools/poly.hxx>
33 #include <vcl/bmpacc.hxx>
34 #include <vcl/gradient.hxx>
35 #include <vcl/gfxlink.hxx>
36 #include <tools/stream.hxx>
37 #include <sot/storage.hxx>
38 #include <vcl/outdev.hxx>
39 #include <vcl/virdev.hxx>
40 #include <vcl/gradient.hxx>
41 #include <sfx2/app.hxx>
42 #include <svl/languageoptions.hxx>
43 //#ifndef _SVX_XIT_HXX
44 //#include <svx/xit.hxx>
45 //#endif
46 #include <editeng/svxenum.hxx>
47 #include <svx/unoapi.hxx>
48 #include <svx/svdoashp.hxx>
49 #include <com/sun/star/style/VerticalAlignment.hpp>
50 #include <com/sun/star/container/XIndexReplace.hpp>
51 #include <com/sun/star/presentation/XPresentationPage.hpp>
52 #include <com/sun/star/awt/XFont.hpp>
53 #ifndef _COM_SUN_STAR_AWT_XFONTWEIGHT_HPP_
54 #include <com/sun/star/awt/FontWeight.hpp>
55 #endif
56 #ifndef _COM_SUN_STAR_AWT_XFONTUNDERLINE_HPP_
57 #include <com/sun/star/awt/FontUnderline.hpp>
58 #endif
59 #include <com/sun/star/style/ParagraphAdjust.hpp>
60 #include <com/sun/star/style/LineSpacing.hpp>
61 #include <com/sun/star/style/LineSpacingMode.hpp>
62 #ifndef _COM_SUN_STAR_STYLE_XSTYLEFAMILIESSUPPLIER_PP_
63 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
64 #endif
65 #include <com/sun/star/style/XStyle.hpp>
66 #include <com/sun/star/drawing/PointSequence.hpp>
67 #include <com/sun/star/drawing/FlagSequence.hpp>
68 #include <com/sun/star/drawing/PolygonFlags.hpp>
69 #include <com/sun/star/beans/PropertyValue.hpp>
70 #include <com/sun/star/drawing/XControlShape.hpp>
71 #include <comphelper/processfactory.hxx>
72 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
73 #include <com/sun/star/i18n/XBreakIterator.hpp>
74 #include <com/sun/star/i18n/XScriptTypeDetector.hpp>
75 #include <com/sun/star/i18n/ScriptType.hpp>
76 #include <com/sun/star/i18n/ScriptDirection.hpp>
77 #include <com/sun/star/embed/Aspects.hpp>
78 #include <vcl/cvtgrf.hxx>
79 #include <tools/urlobj.hxx>
80 #ifndef _CPPUHELPER_EXTRACT_HXX_
81 #include <comphelper/extract.hxx>
82 #endif
83 #ifndef _CPPUHELPER_PROPTYPEHLP_HXX_
84 #include <cppuhelper/proptypehlp.hxx>
85 #endif
86 #ifndef _UCBHELPER_CONTENT_HXX_
87 #include <ucbhelper/content.hxx>
88 #endif
89 #ifndef _UCBHELPER_CONTENTBROKER_HXX_
90 #include <ucbhelper/contentbroker.hxx>
91 #endif
92 #ifndef _TOOLKIT_UNOHLP_HXX
93 #include <toolkit/unohlp.hxx>
94 #endif
95 #include <rtl/crc.h>
96 #include <sot/clsids.hxx>
97 #include <unotools/ucbstreamhelper.hxx>
98 #include <com/sun/star/text/FontRelief.hpp>
99 #include <editeng/frmdiritem.hxx>
100 /*
101 #include <editeng/outliner.hxx>
102 #include <editeng/outlobj.hxx>
103 #include <svx/svdmodel.hxx>
104 */
105 #include <svtools/fltcall.hxx>
106 #include <com/sun/star/table/XTable.hpp>
107 #include <com/sun/star/table/XMergeableCell.hpp>
108 #include <com/sun/star/table/BorderLine.hpp>
109 #include <set>
110 
111 //#include <svx/xbtmpit.hxx>
112 
113 #include "i18npool/mslangid.hxx"
114 
115 #include <vos/xception.hxx>
116 using namespace vos;
117 
118 using namespace ::com::sun::star;
119 
120 ////////////////////////////////////////////////////////////////////////////////////////////////////
121 
122 #define ANSI_CHARSET            0
123 #define DEFAULT_CHARSET         1
124 #define SYMBOL_CHARSET          2
125 #define SHIFTJIS_CHARSET        128
126 #define HANGEUL_CHARSET         129
127 #define CHINESEBIG5_CHARSET     136
128 #define OEM_CHARSET             255
129 
130 ////////////////////////////////////////////////////////////////////////////////////////////////////
131 
132 /* Font Families */
133 #define FF_DONTCARE             0x00
134 #define FF_ROMAN                0x10
135 #define FF_SWISS                0x20
136 #define FF_MODERN               0x30
137 #define FF_SCRIPT               0x40
138 #define FF_DECORATIVE           0x50
139 
140 ////////////////////////////////////////////////////////////////////////////////////////////////////
141 
142 #define DEFAULT_PITCH           0x00
143 #define FIXED_PITCH             0x01
144 #define VARIABLE_PITCH          0x02
145 
146 // ---------------------------------------------------------------------------------------------
147 
148 com::sun::star::uno::Reference< com::sun::star::i18n::XBreakIterator > xPPTBreakIter;
149 com::sun::star::uno::Reference< com::sun::star::i18n::XScriptTypeDetector > xScriptTypeDetector;
150 
PPTExBulletProvider()151 PPTExBulletProvider::PPTExBulletProvider()
152 {
153     pGraphicProv = new EscherGraphicProvider( _E_GRAPH_PROV_USE_INSTANCES  | _E_GRAPH_PROV_DO_NOT_ROTATE_METAFILES );
154 }
155 
~PPTExBulletProvider()156 PPTExBulletProvider::~PPTExBulletProvider()
157 {
158     delete pGraphicProv;
159 }
160 
GetId(const ByteString & rUniqueId,Size & rGraphicSize)161 sal_uInt16 PPTExBulletProvider::GetId( const ByteString& rUniqueId, Size& rGraphicSize )
162 {
163     sal_uInt16 nRetValue = 0xffff;
164     sal_uInt32 nId = 0;
165 
166     if ( rUniqueId.Len() )
167     {
168         Rectangle       aRect;
169         GraphicObject   aGraphicObject( rUniqueId );
170         Graphic         aMappedGraphic, aGraphic( aGraphicObject.GetGraphic() );
171         Size            aPrefSize( aGraphic.GetPrefSize() );
172         BitmapEx        aBmpEx( aGraphic.GetBitmapEx() );
173 
174         if ( rGraphicSize.Width() && rGraphicSize.Height() )
175         {
176             double          fQ1 = ( (double)aPrefSize.Width() / (double)aPrefSize.Height() );
177             double          fQ2 = ( (double)rGraphicSize.Width() / (double)rGraphicSize.Height() );
178             double          fXScale = 1;
179             double          fYScale = 1;
180 
181             if ( fQ1 > fQ2 )
182                 fYScale = fQ1 / fQ2;
183             else if ( fQ1 < fQ2 )
184                 fXScale = fQ2 / fQ1;
185 
186             if ( ( fXScale != 1.0 ) || ( fYScale != 1.0 ) )
187             {
188                 aBmpEx.Scale( fXScale, fYScale );
189                 Size aNewSize( (sal_Int32)((double)rGraphicSize.Width() / fXScale + 0.5 ),
190                                 (sal_Int32)((double)rGraphicSize.Height() / fYScale + 0.5 ) );
191 
192                 rGraphicSize = aNewSize;
193 
194                 aMappedGraphic = Graphic( aBmpEx );
195                 aGraphicObject = GraphicObject( aMappedGraphic );
196             }
197         }
198 
199         nId = pGraphicProv->GetBlibID( aBuExPictureStream, aGraphicObject.GetUniqueID(), aRect, NULL, NULL );
200 
201         if ( nId && ( nId < 0x10000 ) )
202             nRetValue = (sal_uInt16)nId - 1;
203     }
204     return nRetValue;
205 }
206 
207 // ---------------------------------------------------------------------------------------------
208 
GroupTable()209 GroupTable::GroupTable() :
210     mnCurrentGroupEntry ( 0 ),
211     mnMaxGroupEntry     ( 0 ),
212     mnGroupsClosed      ( 0 ),
213     mpGroupEntry        ( NULL )
214 {
215     ImplResizeGroupTable( 32 );
216 }
217 
218 // ---------------------------------------------------------------------------------------------
219 
~GroupTable()220 GroupTable::~GroupTable()
221 {
222     for ( sal_uInt32 i = 0; i < mnCurrentGroupEntry; delete mpGroupEntry[ i++ ] ) ;
223     delete[] mpGroupEntry;
224 }
225 
226 // ---------------------------------------------------------------------------------------------
227 
ImplResizeGroupTable(sal_uInt32 nEntrys)228 void GroupTable::ImplResizeGroupTable( sal_uInt32 nEntrys )
229 {
230     if ( nEntrys > mnMaxGroupEntry )
231     {
232         mnMaxGroupEntry         = nEntrys;
233         GroupEntry** pTemp = new GroupEntry*[ nEntrys ];
234         for ( sal_uInt32 i = 0; i < mnCurrentGroupEntry; i++ )
235             pTemp[ i ] = mpGroupEntry[ i ];
236         if ( mpGroupEntry )
237             delete[] mpGroupEntry;
238         mpGroupEntry = pTemp;
239     }
240 }
241 
242 // ---------------------------------------------------------------------------------------------
243 
EnterGroup(::com::sun::star::uno::Reference<::com::sun::star::container::XIndexAccess> & rXIndexAccessRef)244 sal_Bool GroupTable::EnterGroup( ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >& rXIndexAccessRef )
245 {
246     sal_Bool bRet = sal_False;
247     if ( rXIndexAccessRef.is() )
248     {
249         GroupEntry* pNewGroup = new GroupEntry( rXIndexAccessRef );
250         if ( pNewGroup->mnCount )
251         {
252             if ( mnMaxGroupEntry == mnCurrentGroupEntry )
253                 ImplResizeGroupTable( mnMaxGroupEntry + 8 );
254             mpGroupEntry[ mnCurrentGroupEntry++ ] = pNewGroup;
255             bRet = sal_True;
256         }
257         else
258             delete pNewGroup;
259     }
260     return bRet;
261 }
262 
263 // ---------------------------------------------------------------------------------------------
264 
GetGroupsClosed()265 sal_uInt32 GroupTable::GetGroupsClosed()
266 {
267     sal_uInt32 nRet = mnGroupsClosed;
268     mnGroupsClosed = 0;
269     return nRet;
270 }
271 
272 // ---------------------------------------------------------------------------------------------
273 
ClearGroupTable()274 void GroupTable::ClearGroupTable()
275 {
276     for ( sal_uInt32 i = 0; i < mnCurrentGroupEntry; i++, delete mpGroupEntry[ i ] ) ;
277     mnCurrentGroupEntry = 0;
278 }
279 
280 // ---------------------------------------------------------------------------------------------
281 
ResetGroupTable(sal_uInt32 nCount)282 void GroupTable::ResetGroupTable( sal_uInt32 nCount )
283 {
284     ClearGroupTable();
285     mpGroupEntry[ mnCurrentGroupEntry++ ] = new GroupEntry( nCount );
286 }
287 
288 // ---------------------------------------------------------------------------------------------
289 
GetNextGroupEntry()290 sal_Bool GroupTable::GetNextGroupEntry()
291 {
292     while ( mnCurrentGroupEntry )
293     {
294         mnIndex = mpGroupEntry[ mnCurrentGroupEntry - 1 ]->mnCurrentPos++;
295 
296         if ( mpGroupEntry[ mnCurrentGroupEntry - 1 ]->mnCount > mnIndex )
297             return sal_True;
298 
299         delete ( mpGroupEntry[ --mnCurrentGroupEntry ] );
300 
301         if ( mnCurrentGroupEntry )
302             mnGroupsClosed++;
303     }
304     return sal_False;
305 }
306 
307 // ---------------------------------------------------------------------------------------------
308 
~FontCollectionEntry()309 FontCollectionEntry::~FontCollectionEntry()
310 {
311 }
312 
313 // ---------------------------------------------------------------------------------------------
314 
ImplInit(const String & rName)315 void FontCollectionEntry::ImplInit( const String& rName )
316 {
317     String aSubstName( GetSubsFontName( rName, SUBSFONT_ONLYONE | SUBSFONT_MS ) );
318     if ( aSubstName.Len() )
319     {
320         Name = aSubstName;
321         bIsConverted = sal_True;
322     }
323     else
324     {
325         Name = rName;
326         bIsConverted = sal_False;
327     }
328 }
329 
~FontCollection()330 FontCollection::~FontCollection()
331 {
332     for( void* pStr = List::First(); pStr; pStr = List::Next() )
333         delete (FontCollectionEntry*)pStr;
334     delete pVDev;
335     xPPTBreakIter = NULL;
336     xScriptTypeDetector = NULL;
337 }
338 
FontCollection()339 FontCollection::FontCollection() :
340     pVDev ( NULL )
341 {
342     com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
343         xMSF = ::comphelper::getProcessServiceFactory();
344     com::sun::star::uno::Reference< com::sun::star::uno::XInterface >
345         xInterface = xMSF->createInstance( rtl::OUString::createFromAscii( "com.sun.star.i18n.BreakIterator" ) );
346     if ( xInterface.is() )
347         xPPTBreakIter = com::sun::star::uno::Reference< com::sun::star::i18n::XBreakIterator >
348             ( xInterface, com::sun::star::uno::UNO_QUERY );
349 
350     xInterface = xMSF->createInstance( rtl::OUString::createFromAscii( "com.sun.star.i18n.ScriptTypeDetector" ) );
351     if ( xInterface.is() )
352         xScriptTypeDetector = com::sun::star::uno::Reference< com::sun::star::i18n::XScriptTypeDetector >
353             ( xInterface, com::sun::star::uno::UNO_QUERY );
354 }
355 
GetScriptDirection(const String & rString) const356 short FontCollection::GetScriptDirection( const String& rString ) const
357 {
358     short nRet = com::sun::star::i18n::ScriptDirection::NEUTRAL;
359     if ( xScriptTypeDetector.is() )
360     {
361         const rtl::OUString sT( rString );
362         nRet = xScriptTypeDetector->getScriptDirection( sT, 0, com::sun::star::i18n::ScriptDirection::NEUTRAL );
363     }
364     return nRet;
365 }
366 
GetId(FontCollectionEntry & rEntry)367 sal_uInt32 FontCollection::GetId( FontCollectionEntry& rEntry )
368 {
369     if( rEntry.Name.Len() )
370     {
371         const sal_uInt32 nFonts = GetCount();
372 
373         for( sal_uInt32 i = 0; i < nFonts; i++ )
374         {
375             const FontCollectionEntry* pEntry = GetById( i );
376             if( pEntry->Name == rEntry.Name )
377                 return i;
378         }
379         Font aFont;
380         aFont.SetCharSet( rEntry.CharSet );
381         aFont.SetName( rEntry.Original );
382 //      aFont.SetFamily( rEntry.Family );
383 //      aFont.SetPitch( rEntry.Pitch );
384         aFont.SetHeight( 100 );
385 
386         if ( !pVDev )
387             pVDev = new VirtualDevice;
388 
389         pVDev->SetFont( aFont );
390         FontMetric aMetric( pVDev->GetFontMetric() );
391 
392         sal_uInt16 nTxtHeight = (sal_uInt16)aMetric.GetAscent() + (sal_uInt16)aMetric.GetDescent();
393 
394         if ( nTxtHeight )
395         {
396             double fScaling = (double)nTxtHeight / 120.0;
397             if ( ( fScaling > 0.50 ) && ( fScaling < 1.5 ) )
398                 rEntry.Scaling = fScaling;
399         }
400 
401         List::Insert( new FontCollectionEntry( rEntry ), LIST_APPEND );
402         return nFonts;
403     }
404     return 0;
405 }
406 
GetById(sal_uInt32 nId)407 const FontCollectionEntry* FontCollection::GetById( sal_uInt32 nId )
408 {
409     return (FontCollectionEntry*)List::GetObject( nId );
410 }
411 
412 // ---------------------------------------------------------------------------------------------
413 
ImplVBAInfoContainer(SvStream * pStrm)414 sal_uInt32 PPTWriter::ImplVBAInfoContainer( SvStream* pStrm )
415 {
416     sal_uInt32 nSize = 28;
417     if ( pStrm )
418     {
419         *pStrm << (sal_uInt32)( 0x1f | ( EPP_VBAInfo << 16 ) )
420                << (sal_uInt32)( nSize - 8 )
421                << (sal_uInt32)( 2 | ( EPP_VBAInfoAtom << 16 ) )
422                << (sal_uInt32)12;
423         mpPptEscherEx->InsertPersistOffset( EPP_Persist_VBAInfoAtom, pStrm->Tell() );
424         *pStrm << (sal_uInt32)0
425                << (sal_uInt32)0
426                << (sal_uInt32)1;
427     }
428     return nSize;
429 }
430 
431 // ---------------------------------------------------------------------------------------------
432 
ImplSlideViewInfoContainer(sal_uInt32 nInstance,SvStream * pStrm)433 sal_uInt32 PPTWriter::ImplSlideViewInfoContainer( sal_uInt32 nInstance, SvStream* pStrm )
434 {
435     sal_uInt32 nSize = 111;
436     if ( pStrm )
437     {
438         sal_uInt8 bShowGuides = 0;
439         sal_uInt8 bSnapToGrid = 1;
440         sal_uInt8 bSnapToShape = 0;
441 
442         sal_Int32 nScaling = 85;
443         sal_Int32 nMasterCoordinate = 0xdda;
444         sal_Int32 nXOrigin = -780;
445         sal_Int32 nYOrigin = -84;
446 
447         sal_Int32 nPosition1 = 0x870;
448         sal_Int32 nPosition2 = 0xb40;
449 
450         if ( nInstance )
451         {
452             bShowGuides = 1;
453             nScaling = 0x3b;
454             nMasterCoordinate = 0xf0c;
455             nXOrigin = -1752;
456             nYOrigin = -72;
457             nPosition1 = 0xb40;
458             nPosition2 = 0x870;
459         }
460         *pStrm << (sal_uInt32)( 0xf | ( EPP_SlideViewInfo << 16 ) | ( nInstance << 4 ) )
461                << (sal_uInt32)( nSize - 8 )
462                << (sal_uInt32)( EPP_SlideViewInfoAtom << 16 ) << (sal_uInt32)3
463                << bShowGuides << bSnapToGrid << bSnapToShape
464                << (sal_uInt32)( EPP_ViewInfoAtom << 16 ) << (sal_uInt32)52
465                << nScaling << (sal_Int32)100 << nScaling << (sal_Int32)100  // scaling atom - Keeps the current scale
466                << nScaling << (sal_Int32)100 << nScaling << (sal_Int32)100  // scaling atom - Keeps the previous scale
467                << (sal_Int32)0x17ac << nMasterCoordinate// Origin - Keeps the origin in master coordinates
468                << nXOrigin << nYOrigin              // Origin
469                << (sal_uInt8)1                          // Bool1 varScale - Set if zoom to fit is set
470                << (sal_uInt8)0                          // bool1 draftMode - Not used
471                << (sal_uInt16)0                         // padword
472                << (sal_uInt32)( ( 7 << 4 ) | ( EPP_GuideAtom << 16 ) ) << (sal_uInt32)8
473                << (sal_uInt32)0     // Type of the guide. If the guide is horizontal this value is zero. If it's vertical, it's one.
474                << nPosition1    // Position of the guide in master coordinates. X coordinate if it's vertical, and Y coordinate if it's horizontal.
475                << (sal_uInt32)( ( 7 << 4 ) | ( EPP_GuideAtom << 16 ) ) << (sal_uInt32)8
476                << (sal_Int32)1      // Type of the guide. If the guide is horizontal this value is zero. If it's vertical, it's one.
477                << nPosition2;   // Position of the guide in master coordinates. X coordinate if it's vertical, and Y coordinate if it's horizontal.
478     }
479     return nSize;
480 }
481 
482 // ---------------------------------------------------------------------------------------------
483 
ImplOutlineViewInfoContainer(SvStream * pStrm)484 sal_uInt32 PPTWriter::ImplOutlineViewInfoContainer( SvStream* pStrm )
485 {
486     sal_uInt32 nSize = 68;
487     if ( pStrm )
488     {
489         *pStrm << (sal_uInt32)( 0xf | ( EPP_OutlineViewInfo << 16 ) ) << (sal_uInt32)( nSize - 8 )
490                << (sal_uInt32)( EPP_ViewInfoAtom << 16 ) << (sal_uInt32)52
491                << (sal_Int32)170 << (sal_Int32)200 << (sal_Int32)170 << (sal_Int32)200  // scaling atom - Keeps the current scale
492                << (sal_Int32)170 << (sal_Int32)200 << (sal_Int32)170 << (sal_Int32)200  // scaling atom - Keeps the previous scale
493                << (sal_Int32)0x17ac << 0xdda    // Origin - Keeps the origin in master coordinates
494                << (sal_Int32)-780 << (sal_Int32)-84 // Origin
495                << (sal_uInt8)1                  // bool1 varScale - Set if zoom to fit is set
496                << (sal_uInt8)0                  // bool1 draftMode - Not used
497                << (sal_uInt16)0;                // padword
498     }
499     return nSize;
500 }
501 
502 // ---------------------------------------------------------------------------------------------
503 
ImplProgBinaryTag(SvStream * pStrm)504 sal_uInt32 PPTWriter::ImplProgBinaryTag( SvStream* pStrm )
505 {
506     sal_uInt32 nPictureStreamSize, nOutlineStreamSize, nSize = 8;
507 
508     nPictureStreamSize = aBuExPictureStream.Tell();
509     if ( nPictureStreamSize )
510         nSize += nPictureStreamSize + 8;
511 
512     nOutlineStreamSize = aBuExOutlineStream.Tell();
513     if ( nOutlineStreamSize )
514         nSize += nOutlineStreamSize + 8;
515 
516     if ( pStrm )
517     {
518         *pStrm << (sal_uInt32)( EPP_BinaryTagData << 16 ) << (sal_uInt32)( nSize - 8 );
519         if ( nPictureStreamSize )
520         {
521             *pStrm << (sal_uInt32)( 0xf | ( EPP_PST_ExtendedBuGraContainer << 16 ) ) << nPictureStreamSize;
522             pStrm->Write( aBuExPictureStream.GetData(), nPictureStreamSize );
523         }
524         if ( nOutlineStreamSize )
525         {
526             *pStrm << (sal_uInt32)( 0xf | ( EPP_PST_ExtendedPresRuleContainer << 16 ) ) << nOutlineStreamSize;
527             pStrm->Write( aBuExOutlineStream.GetData(), nOutlineStreamSize );
528         }
529     }
530     return nSize;
531 }
532 
533 // ---------------------------------------------------------------------------------------------
534 
ImplProgBinaryTagContainer(SvStream * pStrm,SvMemoryStream * pBinTagStrm)535 sal_uInt32 PPTWriter::ImplProgBinaryTagContainer( SvStream* pStrm, SvMemoryStream* pBinTagStrm )
536 {
537     sal_uInt32 nSize = 8 + 8 + 14;
538     if ( pStrm )
539     {
540         *pStrm << (sal_uInt32)( 0xf | ( EPP_ProgBinaryTag << 16 ) ) << (sal_uInt32)0
541                << (sal_uInt32)( EPP_CString << 16 ) << (sal_uInt32)14
542                << (sal_uInt32)0x5f005f << (sal_uInt32)0x50005f
543                << (sal_uInt32)0x540050 << (sal_uInt16)0x39;
544     }
545     if ( pBinTagStrm )
546     {
547         sal_uInt32 nLen = pBinTagStrm->Tell();
548         nSize += nLen + 8;
549         *pStrm << (sal_uInt32)( EPP_BinaryTagData << 16 ) << nLen;
550         pStrm->Write( pBinTagStrm->GetData(), nLen );
551     }
552     else
553         nSize += ImplProgBinaryTag( pStrm );
554 
555     if ( pStrm )
556     {
557         pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) );
558         *pStrm << (sal_uInt32)( nSize - 8 );
559         pStrm->SeekRel( nSize - 8 );
560     }
561     return nSize;
562 }
563 
564 // ---------------------------------------------------------------------------------------------
565 
ImplProgTagContainer(SvStream * pStrm,SvMemoryStream * pBinTagStrm)566 sal_uInt32 PPTWriter::ImplProgTagContainer( SvStream* pStrm, SvMemoryStream* pBinTagStrm )
567 {
568     sal_uInt32 nSize = 0;
569     if ( aBuExPictureStream.Tell() || aBuExOutlineStream.Tell() || pBinTagStrm )
570     {
571         nSize = 8;
572         if ( pStrm )
573         {
574             *pStrm << (sal_uInt32)( 0xf | ( EPP_ProgTags << 16 ) ) << (sal_uInt32)0;
575         }
576         nSize += ImplProgBinaryTagContainer( pStrm, pBinTagStrm );
577         if ( pStrm )
578         {
579             pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) );
580             *pStrm << (sal_uInt32)( nSize - 8 );
581             pStrm->SeekRel( nSize - 8 );
582         }
583     }
584     return nSize;
585 }
586 
587 // ---------------------------------------------------------------------------------------------
588 
ImplDocumentListContainer(SvStream * pStrm)589 sal_uInt32 PPTWriter::ImplDocumentListContainer( SvStream* pStrm )
590 {
591     sal_uInt32 nSize = 8;
592     if ( pStrm )
593     {
594         *pStrm << (sal_uInt32)( ( EPP_List << 16 ) | 0xf ) << (sal_uInt32)0;
595     }
596 
597     nSize += ImplVBAInfoContainer( pStrm );
598     nSize += ImplSlideViewInfoContainer( 0, pStrm );
599     nSize += ImplOutlineViewInfoContainer( pStrm );
600     nSize += ImplSlideViewInfoContainer( 1, pStrm );
601     nSize += ImplProgTagContainer( pStrm );
602 
603     if ( pStrm )
604     {
605         pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) );
606         *pStrm << (sal_uInt32)( nSize - 8 );
607         pStrm->SeekRel( nSize - 8 );
608     }
609     return nSize;
610 }
611 
612 // ---------------------------------------------------------------------------------------------
613 
ImplMasterSlideListContainer(SvStream * pStrm)614 sal_uInt32 PPTWriter::ImplMasterSlideListContainer( SvStream* pStrm )
615 {
616     sal_uInt32 i, nSize = 28 * mnMasterPages + 8;
617     if ( pStrm )
618     {
619         *pStrm << (sal_uInt32)( 0x1f | ( EPP_SlideListWithText << 16 ) ) << (sal_uInt32)( nSize - 8 );
620 
621         for ( i = 0; i < mnMasterPages; i++ )
622         {
623             *pStrm << (sal_uInt32)( EPP_SlidePersistAtom << 16 ) << (sal_uInt32)20;
624             mpPptEscherEx->InsertPersistOffset( EPP_MAINMASTER_PERSIST_KEY | i, pStrm->Tell() );
625             *pStrm << (sal_uInt32)0                 // psrReference - logical reference to the slide persist object ( EPP_MAINMASTER_PERSIST_KEY )
626                    << (sal_uInt32)0                 // flags - only bit 3 used, if set then slide contains shapes other than placeholders
627                    << (sal_Int32)0                  // numberTexts - number of placeholder texts stored with the persist object. Allows to display outline view without loading the slide persist objects
628                    << (sal_Int32)( 0x80000000 | i ) // slideId - Unique slide identifier, used for OLE link monikers for example
629                    << (sal_uInt32)0;                // reserved, usualy 0
630         }
631     }
632     return nSize;
633 }
634 
635 // ---------------------------------------------------------------------------------------------
636 
ImplInsertBookmarkURL(const String & rBookmarkURL,const sal_uInt32 nType,const String & rStringVer0,const String & rStringVer1,const String & rStringVer2,const String & rStringVer3)637 sal_uInt32 PPTWriter::ImplInsertBookmarkURL( const String& rBookmarkURL, const sal_uInt32 nType,
638     const String& rStringVer0, const String& rStringVer1, const String& rStringVer2, const String& rStringVer3 )
639 {
640     sal_uInt32 nHyperId = ++mnExEmbed;
641 
642     rtl::OUString sBookmarkURL( rBookmarkURL );
643     INetURLObject aBaseURI( maBaseURI );
644     INetURLObject aBookmarkURI( rBookmarkURL );
645     if( aBaseURI.GetProtocol() == aBookmarkURI.GetProtocol() )
646     {
647         rtl::OUString aRelUrl( INetURLObject::GetRelURL( maBaseURI, rBookmarkURL,
648             INetURLObject::WAS_ENCODED, INetURLObject::DECODE_TO_IURI, RTL_TEXTENCODING_UTF8, INetURLObject::FSYS_DETECT ) );
649         if ( aRelUrl.getLength() )
650             sBookmarkURL = aRelUrl;
651     }
652     maHyperlink.Insert( new EPPTHyperlink( sBookmarkURL, nType ), LIST_APPEND );
653 
654     *mpExEmbed  << (sal_uInt16)0xf
655                 << (sal_uInt16)EPP_ExHyperlink
656                 << (sal_uInt32)0;
657     sal_uInt32 nHyperSize, nHyperStart = mpExEmbed->Tell();
658     *mpExEmbed  << (sal_uInt16)0
659                 << (sal_uInt16)EPP_ExHyperlinkAtom
660                 << (sal_uInt32)4
661                 << nHyperId;
662 
663     sal_uInt16 i, nStringLen;
664     nStringLen = rStringVer0.Len();
665     if ( nStringLen )
666     {
667         *mpExEmbed << (sal_uInt32)( EPP_CString << 16 ) << (sal_uInt32)( nStringLen * 2 );
668         for ( i = 0; i < nStringLen; i++ )
669         {
670             *mpExEmbed << rStringVer0.GetChar( i );
671         }
672     }
673     nStringLen = rStringVer1.Len();
674     if ( nStringLen )
675     {
676         *mpExEmbed << (sal_uInt32)( ( EPP_CString << 16 ) | 0x10 ) << (sal_uInt32)( nStringLen * 2 );
677         for ( i = 0; i < nStringLen; i++ )
678         {
679             *mpExEmbed << rStringVer1.GetChar( i );
680         }
681     }
682     nStringLen = rStringVer2.Len();
683     if ( nStringLen )
684     {
685         *mpExEmbed << (sal_uInt32)( ( EPP_CString << 16 ) | 0x20 ) << (sal_uInt32)( nStringLen * 2 );
686         for ( i = 0; i < nStringLen; i++ )
687         {
688             *mpExEmbed << rStringVer2.GetChar( i );
689         }
690     }
691     nStringLen = rStringVer3.Len();
692     if ( nStringLen )
693     {
694         *mpExEmbed << (sal_uInt32)( ( EPP_CString << 16 ) | 0x30 ) << (sal_uInt32)( nStringLen * 2 );
695         for ( i = 0; i < nStringLen; i++ )
696         {
697             *mpExEmbed << rStringVer3.GetChar( i );
698         }
699     }
700     nHyperSize = mpExEmbed->Tell() - nHyperStart;
701     mpExEmbed->SeekRel( - ( (sal_Int32)nHyperSize + 4 ) );
702     *mpExEmbed  << nHyperSize;
703     mpExEmbed->SeekRel( nHyperSize );
704     return nHyperId;
705 }
706 
707 // ---------------------------------------------------------------------------------------------
708 
ImplCloseDocument()709 sal_Bool PPTWriter::ImplCloseDocument()
710 {
711     sal_uInt32 nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_Document );
712     if ( nOfs )
713     {
714         mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_CurrentPos, mpStrm->Tell() );
715         mpStrm->Seek( nOfs );
716 
717         // creating the TxMasterStyleAtom
718         SvMemoryStream aTxMasterStyleAtomStrm( 0x200, 0x200 );
719         {
720             EscherExAtom aTxMasterStyleAtom( aTxMasterStyleAtomStrm, EPP_TxMasterStyleAtom, EPP_TEXTTYPE_Other );
721             aTxMasterStyleAtomStrm << (sal_uInt16)5;        // paragraph count
722             sal_uInt16 nLev;
723             sal_Bool bFirst = sal_True;
724             for ( nLev = 0; nLev < 5; nLev++ )
725             {
726                 mpStyleSheet->mpParaSheet[ EPP_TEXTTYPE_Other ]->Write( aTxMasterStyleAtomStrm, mpPptEscherEx, nLev, bFirst, sal_False, mXPagePropSet );
727                 mpStyleSheet->mpCharSheet[ EPP_TEXTTYPE_Other ]->Write( aTxMasterStyleAtomStrm, mpPptEscherEx, nLev, bFirst, sal_False, mXPagePropSet );
728                 bFirst = sal_False;
729             }
730         }
731 
732         mpExEmbed->Seek( STREAM_SEEK_TO_END );
733         sal_uInt32 nExEmbedSize = mpExEmbed->Tell();
734 
735         // nEnviroment : Gesamtgroesse des Environment Containers
736         sal_uInt32 nEnvironment = maFontCollection.GetCount() * 76      // 68 bytes pro Fontenityatom und je 8 Bytes fuer die Header
737                                 + 8                                     // 1 FontCollection Container
738                                 + 20                                    // SrKinsoku Container
739                                 + 18                                    // 1 TxSiStyleAtom
740                                 + aTxMasterStyleAtomStrm.Tell()         // 1 TxMasterStyleAtom;
741                                 + mpStyleSheet->SizeOfTxCFStyleAtom();
742 
743         sal_uInt32 nBytesToInsert = nEnvironment + 8;
744 
745         if ( nExEmbedSize )
746             nBytesToInsert += nExEmbedSize + 8 + 12;
747 
748         nBytesToInsert += maSoundCollection.GetSize();
749         nBytesToInsert += mpPptEscherEx->DrawingGroupContainerSize();
750         nBytesToInsert += ImplMasterSlideListContainer( NULL );
751         nBytesToInsert += ImplDocumentListContainer( NULL );
752 
753         // nBytes im Stream einfuegen, und abhaengige Container anpassen
754         mpPptEscherEx->InsertAtCurrentPos( nBytesToInsert, false );
755 
756         // CREATE HYPERLINK CONTAINER
757         if ( nExEmbedSize )
758         {
759             *mpStrm << (sal_uInt16)0xf
760                     << (sal_uInt16)EPP_ExObjList
761                     << (sal_uInt32)( nExEmbedSize + 12 )
762                     << (sal_uInt16)0
763                     << (sal_uInt16)EPP_ExObjListAtom
764                     << (sal_uInt32)4
765                     << (sal_uInt32)mnExEmbed;
766             mpPptEscherEx->InsertPersistOffset( EPP_Persist_ExObj, mpStrm->Tell() );
767             mpStrm->Write( mpExEmbed->GetData(), nExEmbedSize );
768         }
769 
770         // CREATE ENVIRONMENT
771         *mpStrm << (sal_uInt16)0xf << (sal_uInt16)EPP_Environment << (sal_uInt32)nEnvironment;
772 
773         // Open Container ( EPP_SrKinsoku )
774         *mpStrm << (sal_uInt16)0x2f << (sal_uInt16)EPP_SrKinsoku << (sal_uInt32)12;
775         mpPptEscherEx->AddAtom( 4, EPP_SrKinsokuAtom, 0, 3 );
776         *mpStrm << (sal_Int32)0;                        // SrKinsoku Level 0
777 
778         // Open Container ( EPP_FontCollection )
779         *mpStrm << (sal_uInt16)0xf << (sal_uInt16)EPP_FontCollection << (sal_uInt32)maFontCollection.GetCount() * 76;
780 
781         for ( sal_uInt32 i = 0; i < maFontCollection.GetCount(); i++ )
782         {
783             mpPptEscherEx->AddAtom( 68, EPP_FontEnityAtom, 0, i );
784             const FontCollectionEntry* pDesc = maFontCollection.GetById( i );
785             sal_uInt32 nFontLen = pDesc->Name.Len();
786             if ( nFontLen > 31 )
787                 nFontLen = 31;
788             for ( sal_uInt16 n = 0; n < 32; n++ )
789             {
790                 sal_Unicode nUniCode = 0;
791                 if ( n < nFontLen )
792                     nUniCode = pDesc->Name.GetChar( n );
793                 *mpStrm << nUniCode;
794             }
795             sal_uInt8   lfCharSet = ANSI_CHARSET;
796             sal_uInt8   lfClipPrecision = 0;
797             sal_uInt8   lfQuality = 6;
798             sal_uInt8   lfPitchAndFamily = 0;
799 
800             if ( pDesc->CharSet == RTL_TEXTENCODING_SYMBOL )
801                 lfCharSet = SYMBOL_CHARSET;
802 
803             switch( pDesc->Family )
804             {
805                 case ::com::sun::star::awt::FontFamily::ROMAN :
806                     lfPitchAndFamily |= FF_ROMAN;
807                 break;
808 
809                 case ::com::sun::star::awt::FontFamily::SWISS :
810                     lfPitchAndFamily |= FF_SWISS;
811                 break;
812 
813                 case ::com::sun::star::awt::FontFamily::MODERN :
814                     lfPitchAndFamily |= FF_MODERN;
815                 break;
816 
817                 case ::com::sun::star::awt::FontFamily::SCRIPT:
818                     lfPitchAndFamily |= FF_SCRIPT;
819                 break;
820 
821                 case ::com::sun::star::awt::FontFamily::DECORATIVE:
822                      lfPitchAndFamily |= FF_DECORATIVE;
823                 break;
824 
825                 default:
826                     lfPitchAndFamily |= FAMILY_DONTKNOW;
827                 break;
828             }
829             switch( pDesc->Pitch )
830             {
831                 case ::com::sun::star::awt::FontPitch::FIXED:
832                     lfPitchAndFamily |= FIXED_PITCH;
833                 break;
834 
835                 default:
836                     lfPitchAndFamily |= DEFAULT_PITCH;
837                 break;
838             }
839             *mpStrm << lfCharSet
840                     << lfClipPrecision
841                     << lfQuality
842                     << lfPitchAndFamily;
843         }
844         mpStyleSheet->WriteTxCFStyleAtom( *mpStrm );        // create style that is used for new standard objects
845         mpPptEscherEx->AddAtom( 10, EPP_TxSIStyleAtom );
846         *mpStrm << (sal_uInt32)7                        // ?
847                 << (sal_Int16)2                         // ?
848                 << (sal_uInt8)9                         // ?
849                 << (sal_uInt8)8                         // ?
850                 << (sal_Int16)0;                        // ?
851 
852         mpStrm->Write( aTxMasterStyleAtomStrm.GetData(), aTxMasterStyleAtomStrm.Tell() );
853         maSoundCollection.Write( *mpStrm );
854         mpPptEscherEx->WriteDrawingGroupContainer( *mpStrm );
855         ImplMasterSlideListContainer( mpStrm );
856         ImplDocumentListContainer( mpStrm );
857 
858         sal_uInt32 nOldPos = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_CurrentPos );
859         if ( nOldPos )
860         {
861             mpStrm->Seek( nOldPos );
862             return sal_True;
863         }
864     }
865     return sal_False;
866 }
867 
868 // ---------------------------------------------------------------------------------------------
869 
GetPropertyValue(::com::sun::star::uno::Any & rAny,const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPropSet,const String & rString,sal_Bool bTestPropertyAvailability)870 sal_Bool PropValue::GetPropertyValue(
871     ::com::sun::star::uno::Any& rAny,
872         const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
873             const String& rString,
874                     sal_Bool bTestPropertyAvailability )
875 {
876     sal_Bool bRetValue = sal_True;
877     if ( bTestPropertyAvailability )
878     {
879         bRetValue = sal_False;
880         try
881         {
882             ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
883                 aXPropSetInfo( rXPropSet->getPropertySetInfo() );
884             if ( aXPropSetInfo.is() )
885                 bRetValue = aXPropSetInfo->hasPropertyByName( rString );
886         }
887         catch( ::com::sun::star::uno::Exception& )
888         {
889             bRetValue = sal_False;
890         }
891     }
892     if ( bRetValue )
893     {
894         try
895         {
896             rAny = rXPropSet->getPropertyValue( rString );
897             if ( !rAny.hasValue() )
898                 bRetValue = sal_False;
899         }
900         catch( ::com::sun::star::uno::Exception& )
901         {
902             bRetValue = sal_False;
903         }
904     }
905     return bRetValue;
906 }
907 
908 // ---------------------------------------------------------------------------------------------
909 
GetPropertyState(const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPropSet,const String & rPropertyName)910 ::com::sun::star::beans::PropertyState PropValue::GetPropertyState(
911     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
912         const String& rPropertyName )
913 {
914     ::com::sun::star::beans::PropertyState eRetValue = ::com::sun::star::beans::PropertyState_AMBIGUOUS_VALUE;
915     try
916     {
917         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState > aXPropState
918                 ( rXPropSet, ::com::sun::star::uno::UNO_QUERY );
919         if ( aXPropState.is() )
920             eRetValue = aXPropState->getPropertyState( rPropertyName );
921     }
922     catch( ::com::sun::star::uno::Exception& )
923     {
924         //...
925     }
926     return eRetValue;
927 }
928 
929 // ---------------------------------------------------------------------------------------------
930 
ImplGetPropertyValue(const String & rString)931 sal_Bool PropValue::ImplGetPropertyValue( const String& rString )
932 {
933     return GetPropertyValue( mAny, mXPropSet, rString );
934 }
935 
936 // ---------------------------------------------------------------------------------------------
937 
ImplGetPropertyValue(const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & aXPropSet,const String & rString)938 sal_Bool PropValue::ImplGetPropertyValue( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & aXPropSet, const String& rString )
939 {
940     return GetPropertyValue( mAny, aXPropSet, rString );
941 }
942 
943 // ---------------------------------------------------------------------------------------------
944 
ImplGetPropertyValue(const String & rString,sal_Bool bGetPropertyState)945 sal_Bool PropStateValue::ImplGetPropertyValue( const String& rString, sal_Bool bGetPropertyState )
946 {
947     ePropState = ::com::sun::star::beans::PropertyState_AMBIGUOUS_VALUE;
948     sal_Bool bRetValue = sal_True;
949 #ifdef UNX
950         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
951             aXPropSetInfo( mXPropSet->getPropertySetInfo() );
952         if ( !aXPropSetInfo.is() )
953             return sal_False;
954 #endif
955     try
956     {
957         mAny = mXPropSet->getPropertyValue( rString );
958         if ( !mAny.hasValue() )
959             bRetValue = sal_False;
960         else if ( bGetPropertyState )
961             ePropState = mXPropState->getPropertyState( rString );
962         else
963             ePropState = ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
964     }
965     catch( ::com::sun::star::uno::Exception& )
966     {
967         bRetValue = sal_False;
968     }
969     return bRetValue;
970 }
971 
972 // ---------------------------------------------------------------------------------------------
973 
ImplInitSOIface()974 sal_Bool PPTWriter::ImplInitSOIface()
975 {
976     while( sal_True )
977     {
978         mXDrawPagesSupplier = ::com::sun::star::uno::Reference<
979             ::com::sun::star::drawing::XDrawPagesSupplier >
980                 ( mXModel, ::com::sun::star::uno::UNO_QUERY );
981         if ( !mXDrawPagesSupplier.is() )
982             break;
983 
984         mXMasterPagesSupplier = ::com::sun::star::uno::Reference<
985             ::com::sun::star::drawing::XMasterPagesSupplier >
986                 ( mXModel, ::com::sun::star::uno::UNO_QUERY );
987         if ( !mXMasterPagesSupplier.is() )
988             break;
989         mXDrawPages = mXMasterPagesSupplier->getMasterPages();
990         if ( !mXDrawPages.is() )
991             break;
992         mnMasterPages = mXDrawPages->getCount();
993         mXDrawPages = mXDrawPagesSupplier->getDrawPages();
994         if( !mXDrawPages.is() )
995             break;
996         mnPages =  mXDrawPages->getCount();
997         if ( !ImplGetPageByIndex( 0, NORMAL ) )
998             break;
999 
1000         return sal_True;
1001     }
1002     return sal_False;
1003 }
1004 
1005 // ---------------------------------------------------------------------------------------------
1006 
ImplSetCurrentStyleSheet(sal_uInt32 nPageNum)1007 sal_Bool PPTWriter::ImplSetCurrentStyleSheet( sal_uInt32 nPageNum )
1008 {
1009     sal_Bool bRet = sal_False;
1010     if ( nPageNum >= maStyleSheetList.size() )
1011         nPageNum = 0;
1012     else
1013         bRet = sal_True;
1014     mpStyleSheet = maStyleSheetList[ nPageNum ];
1015     return bRet;
1016 }
1017 
1018 // ---------------------------------------------------------------------------------------------
1019 
ImplGetPageByIndex(sal_uInt32 nIndex,PageType ePageType)1020 sal_Bool PPTWriter::ImplGetPageByIndex( sal_uInt32 nIndex, PageType ePageType )
1021 {
1022     while( sal_True )
1023     {
1024         if ( ePageType != meLatestPageType )
1025         {
1026             switch( ePageType )
1027             {
1028                 case NORMAL :
1029                 case NOTICE :
1030                 {
1031                     mXDrawPages = mXDrawPagesSupplier->getDrawPages();
1032                     if( !mXDrawPages.is() )
1033                         return sal_False;
1034                 }
1035                 break;
1036 
1037                 case MASTER :
1038                 {
1039                     mXDrawPages = mXMasterPagesSupplier->getMasterPages();
1040                     if( !mXDrawPages.is() )
1041                         return sal_False;
1042                 }
1043                 break;
1044                 default:
1045                     break;
1046             }
1047             meLatestPageType = ePageType;
1048         }
1049         ::com::sun::star::uno::Any aAny( mXDrawPages->getByIndex( nIndex ) );
1050         aAny >>= mXDrawPage;
1051         if ( !mXDrawPage.is() )
1052             break;
1053         if ( ePageType == NOTICE )
1054         {
1055             ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XPresentationPage >
1056                 aXPresentationPage( mXDrawPage, ::com::sun::star::uno::UNO_QUERY );
1057             if ( !aXPresentationPage.is() )
1058                 break;
1059             mXDrawPage = aXPresentationPage->getNotesPage();
1060             if ( !mXDrawPage.is() )
1061                 break;
1062         }
1063         mXPagePropSet = ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
1064             ( mXDrawPage, ::com::sun::star::uno::UNO_QUERY );
1065         if ( !mXPagePropSet.is() )
1066             break;
1067 
1068         mXShapes = ::com::sun::star::uno::Reference<
1069             ::com::sun::star::drawing::XShapes >
1070                 ( mXDrawPage, ::com::sun::star::uno::UNO_QUERY );
1071         if ( !mXShapes.is() )
1072             break;
1073 
1074         /* try to get the "real" background PropertySet. If the normal page is not supporting this property, it is
1075            taken the property from the master */
1076         sal_Bool bHasBackground = GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Background" ) ), sal_True );
1077         if ( bHasBackground )
1078             bHasBackground = ( aAny >>= mXBackgroundPropSet );
1079         if ( !bHasBackground )
1080         {
1081             ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XMasterPageTarget >
1082                 aXMasterPageTarget( mXDrawPage, ::com::sun::star::uno::UNO_QUERY );
1083             if ( aXMasterPageTarget.is() )
1084             {
1085                 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > aXMasterDrawPage;
1086                 aXMasterDrawPage = aXMasterPageTarget->getMasterPage();
1087                 if ( aXMasterDrawPage.is() )
1088                 {
1089                     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXMasterPagePropSet;
1090                     aXMasterPagePropSet = ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
1091                         ( aXMasterDrawPage, ::com::sun::star::uno::UNO_QUERY );
1092                     if ( aXMasterPagePropSet.is() )
1093                     {
1094                         sal_Bool bBackground = GetPropertyValue( aAny, aXMasterPagePropSet,
1095                                 String( RTL_CONSTASCII_USTRINGPARAM( "Background" ) ) );
1096                         if ( bBackground )
1097                         {
1098                             aAny >>= mXBackgroundPropSet;
1099                         }
1100                     }
1101                 }
1102             }
1103         }
1104         return sal_True;
1105     }
1106     return sal_False;
1107 }
1108 
1109 // ---------------------------------------------------------------------------------------------
1110 
ImplGetShapeByIndex(sal_uInt32 nIndex,sal_Bool bGroup)1111 sal_Bool PPTWriter::ImplGetShapeByIndex( sal_uInt32 nIndex, sal_Bool bGroup )
1112 {
1113     while(sal_True)
1114     {
1115         if (  ( bGroup == sal_False ) || ( GetCurrentGroupLevel() == 0 ) )
1116         {
1117             ::com::sun::star::uno::Any aAny( mXShapes->getByIndex( nIndex ) );
1118             aAny >>= mXShape;
1119         }
1120         else
1121         {
1122             ::com::sun::star::uno::Any aAny( GetCurrentGroupAccess()->getByIndex( GetCurrentGroupIndex() ) );
1123             aAny >>= mXShape;
1124         }
1125         if ( !mXShape.is() )
1126             break;
1127 
1128         ::com::sun::star::uno::Any aAny( mXShape->queryInterface( ::getCppuType( (const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >*) 0 ) ));
1129         aAny >>= mXPropSet;
1130 
1131         if ( !mXPropSet.is() )
1132             break;
1133         maPosition = ImplMapPoint( mXShape->getPosition() );
1134         maSize = ImplMapSize( mXShape->getSize() );
1135         maRect = Rectangle( Point( maPosition.X, maPosition.Y ), Size( maSize.Width, maSize.Height ) );
1136         mType = ByteString( String( mXShape->getShapeType() ), RTL_TEXTENCODING_UTF8 );
1137         mType.Erase( 0, 13 );                                   // "com.sun.star." entfernen
1138         sal_uInt16 nPos = mType.Search( (const char*)"Shape" );
1139         mType.Erase( nPos, 5 );
1140 
1141         mbPresObj = mbEmptyPresObj = sal_False;
1142         if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsPresentationObject" ) ) ) )
1143             mAny >>= mbPresObj;
1144 
1145         if ( mbPresObj && ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsEmptyPresentationObject" ) ) ) )
1146             mAny >>= mbEmptyPresObj;
1147 
1148         mnAngle = ( PropValue::GetPropertyValue( aAny,
1149             mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True ) )
1150                 ? *((sal_Int32*)aAny.getValue() )
1151                 : 0;
1152 
1153         return sal_True;
1154     }
1155     return sal_False;
1156 }
1157 
1158 //  -----------------------------------------------------------------------
1159 
ImplGetMasterIndex(PageType ePageType)1160 sal_uInt32 PPTWriter::ImplGetMasterIndex( PageType ePageType )
1161 {
1162     sal_uInt32 nRetValue = 0;
1163     ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XMasterPageTarget >
1164         aXMasterPageTarget( mXDrawPage, ::com::sun::star::uno::UNO_QUERY );
1165 
1166     if ( aXMasterPageTarget.is() )
1167     {
1168         ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >
1169             aXDrawPage = aXMasterPageTarget->getMasterPage();
1170         if ( aXDrawPage.is() )
1171         {
1172             ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
1173                 aXPropertySet( aXDrawPage, ::com::sun::star::uno::UNO_QUERY );
1174 
1175             if ( aXPropertySet.is() )
1176             {
1177                 if ( ImplGetPropertyValue( aXPropertySet, String( RTL_CONSTASCII_USTRINGPARAM( "Number" ) ) ) )
1178                     nRetValue |= *(sal_Int16*)mAny.getValue();
1179                 if ( nRetValue & 0xffff )           // ueberlauf vermeiden
1180                     nRetValue--;
1181             }
1182         }
1183     }
1184     if ( ePageType == NOTICE )
1185         nRetValue += mnMasterPages;
1186     return nRetValue;
1187 }
1188 
1189 //  -----------------------------------------------------------------------
1190 
ImplGetStyleSheets()1191 sal_Bool PPTWriter::ImplGetStyleSheets()
1192 {
1193     int             nInstance, nLevel;
1194     sal_Bool        bRetValue = sal_False;
1195     sal_uInt32      nPageNum;
1196 
1197     for ( nPageNum = 0; nPageNum < mnMasterPages; nPageNum++ )
1198     {
1199         ::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed >
1200             aXNamed;
1201 
1202         ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
1203             aXNameAccess;
1204 
1205         ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyleFamiliesSupplier >
1206             aXStyleFamiliesSupplier( mXModel, ::com::sun::star::uno::UNO_QUERY );
1207 
1208         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
1209             aXPropSet( mXModel, ::com::sun::star::uno::UNO_QUERY );
1210 
1211         sal_uInt16 nDefaultTab = ( aXPropSet.is() && ImplGetPropertyValue( aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TabStop" ) ) ) )
1212             ? (sal_uInt16)( *(sal_Int32*)mAny.getValue() / 4.40972 )
1213             : 1250;
1214 
1215         maStyleSheetList.push_back( new PPTExStyleSheet( nDefaultTab, (PPTExBulletProvider&)*this ) );
1216         ImplSetCurrentStyleSheet( nPageNum );
1217         if ( ImplGetPageByIndex( nPageNum, MASTER ) )
1218             aXNamed = ::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed >
1219                         ( mXDrawPage, ::com::sun::star::uno::UNO_QUERY );
1220 
1221         if ( aXStyleFamiliesSupplier.is() )
1222             aXNameAccess = aXStyleFamiliesSupplier->getStyleFamilies();
1223 
1224         bRetValue = aXNamed.is() && aXNameAccess.is() && aXStyleFamiliesSupplier.is();
1225         if  ( bRetValue )
1226         {
1227             for ( nInstance = EPP_TEXTTYPE_Title; nInstance <= EPP_TEXTTYPE_CenterTitle; nInstance++ )
1228             {
1229                 String aStyle;
1230                 String aFamily;
1231                 switch ( nInstance )
1232                 {
1233                     case EPP_TEXTTYPE_CenterTitle :
1234                     case EPP_TEXTTYPE_Title :
1235                     {
1236                         aStyle = String( RTL_CONSTASCII_USTRINGPARAM( "title" ) );
1237                         aFamily = aXNamed->getName();
1238                     }
1239                     break;
1240                     case EPP_TEXTTYPE_Body :
1241                     {
1242                         aStyle = String( RTL_CONSTASCII_USTRINGPARAM( "outline1" ) );      // SD_LT_SEPARATOR
1243                         aFamily = aXNamed->getName();
1244                     }
1245                     break;
1246                     case EPP_TEXTTYPE_Other :
1247                     {
1248                         aStyle = String( RTL_CONSTASCII_USTRINGPARAM( "standard" ) );
1249                         aFamily = String( RTL_CONSTASCII_USTRINGPARAM( "graphics" ) );
1250                     }
1251                     break;
1252                     case EPP_TEXTTYPE_CenterBody :
1253                     {
1254                         aStyle = String( RTL_CONSTASCII_USTRINGPARAM( "subtitle" ) );
1255                         aFamily = aXNamed->getName();
1256                     }
1257                     break;
1258                 }
1259                 if ( aStyle.Len() && aFamily.Len() )
1260                 {
1261                     try
1262                     {
1263                         ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >xNameAccess;
1264                         if ( aXNameAccess->hasByName( aFamily ) )
1265                         {
1266                             ::com::sun::star::uno::Any aAny( aXNameAccess->getByName( aFamily ) );
1267                             if( aAny.getValue() && ::cppu::extractInterface( xNameAccess, aAny ) )
1268                             {
1269                                 ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > aXFamily;
1270                                 if ( aAny >>= aXFamily )
1271                                 {
1272                                     if ( aXFamily->hasByName( aStyle ) )
1273                                     {
1274                                         ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle > xStyle;
1275                                         aAny = aXFamily->getByName( aStyle );
1276                                         if( aAny.getValue() && ::cppu::extractInterface( xStyle, aAny ) )
1277                                         {
1278                                             ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle > aXStyle;
1279                                             aAny >>= aXStyle;
1280                                             ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
1281                                                 xPropSet( aXStyle, ::com::sun::star::uno::UNO_QUERY );
1282                                             if( xPropSet.is() )
1283                                                 mpStyleSheet->SetStyleSheet( xPropSet, maFontCollection, nInstance, 0 );
1284                                             for ( nLevel = 1; nLevel < 5; nLevel++ )
1285                                             {
1286                                                 if ( nInstance == EPP_TEXTTYPE_Body )
1287                                                 {
1288                                                     sal_Unicode cTemp = aStyle.GetChar( aStyle.Len() - 1 );
1289                                                     aStyle.SetChar( aStyle.Len() - 1, ++cTemp );
1290                                                     if ( aXFamily->hasByName( aStyle ) )
1291                                                     {
1292                                                         aXFamily->getByName( aStyle ) >>= xStyle;
1293                                                         if( xStyle.is() )
1294                                                         {
1295                                                             ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
1296                                                                 xPropertySet( xStyle, ::com::sun::star::uno::UNO_QUERY );
1297                                                             if ( xPropertySet.is() )
1298                                                                 mpStyleSheet->SetStyleSheet( xPropertySet, maFontCollection, nInstance, nLevel );
1299                                                         }
1300                                                     }
1301                                                 }
1302                                                 else
1303                                                     mpStyleSheet->SetStyleSheet( xPropSet, maFontCollection, nInstance, nLevel );
1304                                             }
1305                                         }
1306                                     }
1307                                 }
1308                             }
1309                         }
1310                     }
1311                     catch( ::com::sun::star::uno::Exception& )
1312                     {
1313                     //
1314                     }
1315                 }
1316             }
1317             for ( ; nInstance <= EPP_TEXTTYPE_QuarterBody; nInstance++ )
1318             {
1319 
1320             }
1321         }
1322     }
1323     return bRetValue;
1324 }
1325 
1326 //  -----------------------------------------------------------------------
1327 
ImplWriteParagraphs(SvStream & rOut,TextObj & rTextObj)1328 void PPTWriter::ImplWriteParagraphs( SvStream& rOut, TextObj& rTextObj )
1329 {
1330     sal_Bool            bFirstParagraph = sal_True;
1331     sal_uInt32          nCharCount;
1332     sal_uInt32          nPropertyFlags = 0;
1333     sal_uInt16          nDepth = 0;
1334     sal_Int16           nLineSpacing;
1335     int                 nInstance = rTextObj.GetInstance();
1336 
1337     for ( ParagraphObj* pPara = rTextObj.First() ; pPara; pPara = rTextObj.Next(), bFirstParagraph = sal_False )
1338     {
1339         PortionObj* pPortion = (PortionObj*)pPara->First();
1340         nCharCount = pPara->Count();
1341 
1342         nDepth = pPara->nDepth;
1343         if ( nDepth > 4)
1344             nDepth = 4;
1345 
1346         if ( ( pPara->meTextAdjust == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1347             ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_Adjust, pPara->mnTextAdjust ) ) )
1348             nPropertyFlags |= 0x00000800;
1349         nLineSpacing = pPara->mnLineSpacing;
1350 
1351         const FontCollectionEntry* pDesc = maFontCollection.GetById( pPortion->mnFont );
1352         sal_Int16 nNormalSpacing = 100;
1353         if ( !mbFontIndependentLineSpacing && pDesc )
1354         {
1355             double fN = 100.0;
1356             fN *= pDesc->Scaling;
1357             nNormalSpacing = (sal_Int16)( fN + 0.5 );
1358         }
1359         if ( !mbFontIndependentLineSpacing && bFirstParagraph && ( nLineSpacing > nNormalSpacing ) )    // sj: i28747, no replacement for fixed linespacing
1360         {
1361             nLineSpacing = nNormalSpacing;
1362             nPropertyFlags |= 0x00001000;
1363         }
1364         else
1365         {
1366             if ( nLineSpacing > 0 )
1367             {
1368                 if ( !mbFontIndependentLineSpacing && pDesc )
1369                      nLineSpacing = (sal_Int16)( (double)nLineSpacing * pDesc->Scaling + 0.5 );
1370             }
1371             else
1372             {
1373                 if ( pPortion && pPortion->mnCharHeight > (sal_uInt16)( ((double)-nLineSpacing) * 0.001 * 72.0 / 2.54 ) ) // 1/100mm to point
1374                     nLineSpacing = nNormalSpacing;
1375                 else
1376                     nLineSpacing = (sal_Int16)( (double)nLineSpacing / 4.40972 );
1377             }
1378             if ( ( pPara->meLineSpacing == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1379                 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_LineFeed, nLineSpacing ) ) )
1380                 nPropertyFlags |= 0x00001000;
1381         }
1382         if ( ( pPara->meLineSpacingTop == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1383             ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_UpperDist, pPara->mnLineSpacingTop ) ) )
1384             nPropertyFlags |= 0x00002000;
1385         if ( ( pPara->meLineSpacingBottom == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1386             ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_LowerDist, pPara->mnLineSpacingBottom ) ) )
1387             nPropertyFlags |= 0x00004000;
1388         if ( ( pPara->meForbiddenRules == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1389             ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_UpperDist, pPara->mbForbiddenRules ) ) )
1390             nPropertyFlags |= 0x00020000;
1391         if ( ( pPara->meParagraphPunctation == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1392             ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_UpperDist, pPara->mbParagraphPunctation ) ) )
1393             nPropertyFlags |= 0x00080000;
1394         if ( ( pPara->meBiDi == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1395             ( mpStyleSheet->IsHardAttribute( nInstance, nDepth, ParaAttr_BiDi, pPara->mnBiDi ) ) )
1396             nPropertyFlags |= 0x00200000;
1397 
1398 
1399         sal_Int32 nBuRealSize = pPara->nBulletRealSize;
1400         sal_Int16 nBulletFlags = pPara->nBulletFlags;
1401 
1402         if ( pPara->bExtendedParameters )
1403             nPropertyFlags |= pPara->nParaFlags;
1404         else
1405         {
1406             nPropertyFlags |= 1;            // turn off bullet explicit
1407             nBulletFlags = 0;
1408         }
1409 
1410         // Write nTextOfs and nBullets
1411         if ( mpStyleSheet->IsHardAttribute( nInstance, nDepth, ParaAttr_TextOfs, pPara->nTextOfs ) )
1412             nPropertyFlags |= 0x100;
1413         if ( mpStyleSheet->IsHardAttribute( nInstance, nDepth, ParaAttr_BulletOfs, pPara->nBulletOfs ))
1414             nPropertyFlags |= 0x400;
1415 
1416         FontCollectionEntry aFontDescEntry( pPara->aFontDesc.Name, pPara->aFontDesc.Family, pPara->aFontDesc.Pitch, pPara->aFontDesc.CharSet );
1417         sal_uInt16  nFontId = (sal_uInt16)maFontCollection.GetId( aFontDescEntry );
1418 
1419         rOut << nCharCount
1420              << nDepth                          // Level
1421              << (sal_uInt32)nPropertyFlags;     // Paragraph Attribut Set
1422 
1423         if ( nPropertyFlags & 0xf )
1424             rOut << nBulletFlags;
1425         if ( nPropertyFlags & 0x80 )
1426             rOut << (sal_uInt16)( pPara->cBulletId );
1427         if ( nPropertyFlags & 0x10 )
1428             rOut << nFontId;
1429         if ( nPropertyFlags & 0x40 )
1430             rOut << (sal_Int16)nBuRealSize;
1431         if ( nPropertyFlags & 0x20 )
1432         {
1433             sal_uInt32 nBulletColor = pPara->nBulletColor;
1434             if ( nBulletColor == COL_AUTO )
1435             {
1436                 sal_Bool bIsDark = sal_False;
1437                 ::com::sun::star::uno::Any aAny;
1438                 if ( PropValue::GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundDark" ) ), sal_True ) )
1439                     aAny >>= bIsDark;
1440                 nBulletColor = bIsDark ? 0xffffff : 0x000000;
1441             }
1442             nBulletColor &= 0xffffff;
1443             nBulletColor |= 0xfe000000;
1444             rOut << nBulletColor;
1445         }
1446         if ( nPropertyFlags & 0x00000800 )
1447             rOut << (sal_uInt16)( pPara->mnTextAdjust );
1448         if ( nPropertyFlags & 0x00001000 )
1449             rOut << (sal_uInt16)( nLineSpacing );
1450         if ( nPropertyFlags & 0x00002000 )
1451             rOut << (sal_uInt16)( pPara->mnLineSpacingTop );
1452         if ( nPropertyFlags & 0x00004000 )
1453             rOut << (sal_uInt16)( pPara->mnLineSpacingBottom );
1454         if ( nPropertyFlags & 0x100 )
1455             rOut << (sal_uInt16)(pPara->nTextOfs);
1456         if (  nPropertyFlags & 0x400 )
1457             rOut << (sal_uInt16)(pPara->nBulletOfs);
1458         if ( nPropertyFlags & 0x000e0000 )
1459         {
1460             sal_uInt16 nAsianSettings = 0;
1461             if ( pPara->mbForbiddenRules )
1462                 nAsianSettings |= 1;
1463             if ( pPara->mbParagraphPunctation )
1464                 nAsianSettings |= 4;
1465             rOut << nAsianSettings;
1466         }
1467         if ( nPropertyFlags & 0x200000 )
1468             rOut << pPara->mnBiDi;
1469     }
1470 }
1471 
1472 //  -----------------------------------------------------------------------
1473 
ImplWritePortions(SvStream & rOut,TextObj & rTextObj)1474 void PPTWriter::ImplWritePortions( SvStream& rOut, TextObj& rTextObj )
1475 {
1476     sal_uInt32  nPropertyFlags, i = 0;
1477     int nInstance = rTextObj.GetInstance();
1478 
1479     for ( ParagraphObj* pPara = rTextObj.First(); pPara; pPara = rTextObj.Next(), i++ )
1480     {
1481         for ( PortionObj* pPortion = (PortionObj*)pPara->First(); pPortion; pPortion = (PortionObj*)pPara->Next() )
1482         {
1483             nPropertyFlags = 0;
1484             sal_uInt32 nCharAttr = pPortion->mnCharAttr;
1485             sal_uInt32 nCharColor = pPortion->mnCharColor;
1486 
1487             if ( nCharColor == COL_AUTO )   // nCharColor depends to the background color
1488             {
1489                 sal_Bool bIsDark = sal_False;
1490                 ::com::sun::star::uno::Any aAny;
1491                 if ( PropValue::GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundDark" ) ), sal_True ) )
1492                     aAny >>= bIsDark;
1493                 nCharColor = bIsDark ? 0xffffff : 0x000000;
1494             }
1495 
1496             nCharColor &= 0xffffff;
1497 
1498             /* the portion is using the embossed or engraved attribute, which we want to map to the relief feature of PPT.
1499             Because the relief feature of PPT is dependent to the background color, such a mapping can not always be used. */
1500             if ( nCharAttr & 0x200 )
1501             {
1502                 sal_uInt32 nBackgroundColor = 0xffffff;
1503 
1504                 if ( !nCharColor )          // special threatment for
1505                     nCharColor = 0xffffff;  // black fontcolor
1506 
1507                 ::com::sun::star::uno::Any aAny;
1508                 ::com::sun::star::drawing::FillStyle aFS( ::com::sun::star::drawing::FillStyle_NONE );
1509                 if ( PropValue::GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) ) )
1510                     aAny >>= aFS;
1511                 switch( aFS )
1512                 {
1513                     case ::com::sun::star::drawing::FillStyle_GRADIENT :
1514                     {
1515                         Point aEmptyPoint = Point();
1516                         Rectangle aRect( aEmptyPoint, Size( 28000, 21000 ) );
1517                         EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect );
1518                         aPropOpt.CreateGradientProperties( mXPropSet );
1519                         aPropOpt.GetOpt( ESCHER_Prop_fillColor, nBackgroundColor );
1520                     }
1521                     break;
1522                     case ::com::sun::star::drawing::FillStyle_SOLID :
1523                     {
1524                         if ( PropValue::GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ) ) )
1525                             nBackgroundColor = mpPptEscherEx->GetColor( *((sal_uInt32*)aAny.getValue()) );
1526                     }
1527                     break;
1528                     case ::com::sun::star::drawing::FillStyle_NONE :
1529                     {
1530                         ::com::sun::star::uno::Any aBackAny;
1531                         ::com::sun::star::drawing::FillStyle aBackFS( ::com::sun::star::drawing::FillStyle_NONE );
1532                         if ( PropValue::GetPropertyValue( aBackAny, mXBackgroundPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) ) )
1533                             aBackAny >>= aBackFS;
1534                         switch( aBackFS )
1535                         {
1536                             case ::com::sun::star::drawing::FillStyle_GRADIENT :
1537                             {
1538                                 Point aEmptyPoint = Point();
1539                                 Rectangle aRect( aEmptyPoint, Size( 28000, 21000 ) );
1540                                 EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect );
1541                                 aPropOpt.CreateGradientProperties( mXBackgroundPropSet );
1542                                 aPropOpt.GetOpt( ESCHER_Prop_fillColor, nBackgroundColor );
1543                             }
1544                             break;
1545                             case ::com::sun::star::drawing::FillStyle_SOLID :
1546                             {
1547                                 if ( PropValue::GetPropertyValue( aAny, mXBackgroundPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ) ) )
1548                                     nBackgroundColor = mpPptEscherEx->GetColor( *((sal_uInt32*)aAny.getValue()) );
1549                             }
1550                             break;
1551                             default:
1552                                 break;
1553                         }
1554                     }
1555                     break;
1556                     default:
1557                         break;
1558                 }
1559 
1560                 sal_Int32 nB = nBackgroundColor & 0xff;
1561                 nB += (sal_uInt8)( nBackgroundColor >> 8  );
1562                 nB += (sal_uInt8)( nBackgroundColor >> 16 );
1563                 // if the background color is nearly black, relief can't been used, because the text would not be visible
1564                 if ( nB < 0x60 || ( nBackgroundColor != nCharColor ) )
1565                 {
1566                     nCharAttr &=~ 0x200;
1567 
1568                     // now check if the text is part of a group, and if the previous object has the same color than the fontcolor
1569                     // ( and if fillcolor is not available the background color ), it is sometimes
1570                     // not possible to export the 'embossed' flag
1571                     if ( ( GetCurrentGroupLevel() > 0 ) && ( GetCurrentGroupIndex() >= 1 ) )
1572                     {
1573                         ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > aGroupedShape( GetCurrentGroupAccess()->getByIndex( GetCurrentGroupIndex() - 1 ), uno::UNO_QUERY );
1574                         if( aGroupedShape.is() )
1575                         {
1576                             ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aPropSetOfNextShape
1577                                 ( aGroupedShape, ::com::sun::star::uno::UNO_QUERY );
1578                             if ( aPropSetOfNextShape.is() )
1579                             {
1580                                 if ( PropValue::GetPropertyValue( aAny, aPropSetOfNextShape,
1581                                                     String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ), sal_True ) )
1582                                 {
1583                                     if ( nCharColor == mpPptEscherEx->GetColor( *((sal_uInt32*)aAny.getValue()) ) )
1584                                     {
1585                                         nCharAttr |= 0x200;
1586                                     }
1587                                 }
1588                             }
1589                         }
1590                     }
1591                 }
1592             }
1593             nCharColor |= 0xfe000000;
1594             if ( nInstance == 4 )                       // special handling for normal textobjects:
1595                 nPropertyFlags |= nCharAttr & 0x217;    // not all attributes ar inherited
1596             else
1597             {
1598                 if ( /* ( pPortion->mnCharAttrHard & 1 ) || */
1599                     ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Bold, nCharAttr ) ) )
1600                     nPropertyFlags |= 1;
1601                 if ( /* ( pPortion->mnCharAttrHard & 2 ) || */
1602                     ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Italic, nCharAttr ) ) )
1603                     nPropertyFlags |= 2;
1604                 if ( /* ( pPortion->mnCharAttrHard & 4 ) || */
1605                     ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Underline, nCharAttr ) ) )
1606                     nPropertyFlags |= 4;
1607                 if ( /* ( pPortion->mnCharAttrHard & 0x10 ) || */
1608                     ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Shadow, nCharAttr ) ) )
1609                     nPropertyFlags |= 0x10;
1610                 if ( /* ( pPortion->mnCharAttrHard & 0x200 ) || */
1611                     ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Embossed, nCharAttr ) ) )
1612                     nPropertyFlags |= 512;
1613             }
1614             if ( rTextObj.HasExtendedBullets() )
1615             {
1616                 nPropertyFlags |= ( i & 0x3f ) << 10 ;
1617                 nCharAttr  |= ( i & 0x3f ) << 10;
1618             }
1619             if ( ( pPortion->meFontName == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1620                 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Font, pPortion->mnFont ) ) )
1621                 nPropertyFlags |= 0x00010000;
1622             if ( ( pPortion->meAsianOrComplexFont == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1623                 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_AsianOrComplexFont, pPortion->mnAsianOrComplexFont ) ) )
1624                 nPropertyFlags |= 0x00200000;
1625             if ( ( pPortion->meCharHeight == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1626                 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_FontHeight, pPortion->mnCharHeight ) ) )
1627                 nPropertyFlags |= 0x00020000;
1628             if ( ( pPortion->meCharColor == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1629                 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_FontColor, nCharColor & 0xffffff ) ) )
1630                 nPropertyFlags |= 0x00040000;
1631             if ( ( pPortion->meCharEscapement == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1632                 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Escapement, pPortion->mnCharEscapement ) ) )
1633                 nPropertyFlags |= 0x00080000;
1634 
1635             sal_uInt32 nCharCount = pPortion->Count();
1636 
1637             rOut << nCharCount
1638                  << nPropertyFlags;          //PropertyFlags
1639 
1640             if ( nPropertyFlags & 0xffff )
1641                 rOut << (sal_uInt16)( nCharAttr );
1642             if ( nPropertyFlags & 0x00010000 )
1643                 rOut << pPortion->mnFont;
1644             if ( nPropertyFlags & 0x00200000 )
1645                 rOut << pPortion->mnAsianOrComplexFont;
1646             if ( nPropertyFlags & 0x00020000 )
1647                 rOut << (sal_uInt16)( pPortion->mnCharHeight );
1648             if ( nPropertyFlags & 0x00040000 )
1649                 rOut << (sal_uInt32)nCharColor;
1650             if ( nPropertyFlags & 0x00080000 )
1651                 rOut << pPortion->mnCharEscapement;
1652         }
1653     }
1654 }
1655 
1656 //  ----------------------------------------------------------------------------------------
1657 //  laedt und konvertiert text aus shape, ergebnis ist mnTextSize gespeichert;
ImplGetText()1658 sal_Bool PPTWriter::ImplGetText()
1659 {
1660     mnTextSize = 0;
1661     mbFontIndependentLineSpacing = sal_False;
1662     mXText = ::com::sun::star::uno::Reference<
1663         ::com::sun::star::text::XSimpleText >
1664             ( mXShape, ::com::sun::star::uno::UNO_QUERY );
1665 
1666     if ( mXText.is() )
1667     {
1668         mnTextSize = mXText->getString().getLength();
1669         ::com::sun::star::uno::Any aAny;
1670         if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FontIndependentLineSpacing" ) ) ), sal_True )
1671             aAny >>= mbFontIndependentLineSpacing;
1672     }
1673     return ( mnTextSize != 0 );
1674 }
1675 
1676 //  -----------------------------------------------------------------------
1677 
ImplFlipBoundingBox(EscherPropertyContainer & rPropOpt)1678 void PPTWriter::ImplFlipBoundingBox( EscherPropertyContainer& rPropOpt )
1679 {
1680     if ( mnAngle < 0 )
1681         mnAngle = ( 36000 + mnAngle ) % 36000;
1682     else
1683         mnAngle = ( 36000 - ( mnAngle % 36000 ) );
1684 
1685     double  fCos = cos( (double)mnAngle * F_PI18000 );
1686     double  fSin = sin( (double)mnAngle * F_PI18000 );
1687 
1688     double  fWidthHalf = maRect.GetWidth() / 2;
1689     double  fHeightHalf = maRect.GetHeight() / 2;
1690 
1691     double  fXDiff = fCos * fWidthHalf + fSin * (-fHeightHalf);
1692     double  fYDiff = - ( fSin * fWidthHalf - fCos * ( -fHeightHalf ) );
1693 
1694     maRect.Move( (sal_Int32)( -( fWidthHalf - fXDiff ) ), (sal_Int32)(  - ( fHeightHalf + fYDiff ) ) );
1695     mnAngle *= 655;
1696     mnAngle += 0x8000;
1697     mnAngle &=~0xffff;                                  // nAngle auf volle Gradzahl runden
1698     rPropOpt.AddOpt( ESCHER_Prop_Rotation, mnAngle );
1699 
1700     if ( ( mnAngle >= ( 45 << 16 ) && mnAngle < ( 135 << 16 ) ) ||
1701             ( mnAngle >= ( 225 << 16 ) && mnAngle < ( 315 << 16 ) ) )
1702     {
1703         // In diesen beiden Bereichen steht in PPT gemeinerweise die
1704         // BoundingBox bereits senkrecht. Daher muss diese VOR
1705         // DER ROTATION flachgelegt werden.
1706         ::com::sun::star::awt::Point
1707             aTopLeft( (sal_Int32)( maRect.Left() + fWidthHalf - fHeightHalf ), (sal_Int32)( maRect.Top() + fHeightHalf - fWidthHalf ) );
1708         Size    aNewSize( maRect.GetHeight(), maRect.GetWidth() );
1709         maRect = Rectangle( Point( aTopLeft.X, aTopLeft.Y ), aNewSize );
1710     }
1711 }
1712 
1713 //  -----------------------------------------------------------------------
1714 
1715 struct FieldEntry
1716 {
1717     sal_uInt32  nFieldType;
1718     sal_uInt32  nFieldStartPos;
1719     sal_uInt32  nFieldEndPos;
1720     String      aRepresentation;
1721     String      aFieldUrl;
1722 
FieldEntryFieldEntry1723     FieldEntry( sal_uInt32 nType, sal_uInt32 nStart, sal_uInt32 nEnd )
1724     {
1725         nFieldType = nType;
1726         nFieldStartPos = nStart;
1727         nFieldEndPos = nEnd;
1728     }
1729 };
1730 
1731 //  -----------------------------------------------------------------------
1732 
PortionObj(const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPropSet,FontCollection & rFontCollection)1733 PortionObj::PortionObj( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
1734                 FontCollection& rFontCollection ) :
1735     mnCharAttrHard      ( 0 ),
1736     mnCharAttr          ( 0 ),
1737     mnFont              ( 0 ),
1738     mnAsianOrComplexFont( 0xffff ),
1739     mnTextSize          ( 0 ),
1740     mbLastPortion       ( sal_True ),
1741     mpText              ( NULL ),
1742     mpFieldEntry        ( NULL )
1743 {
1744     mXPropSet = rXPropSet;
1745 
1746     ImplGetPortionValues( rFontCollection, sal_False );
1747 }
1748 
PortionObj(::com::sun::star::uno::Reference<::com::sun::star::text::XTextRange> & rXTextRange,sal_Bool bLast,FontCollection & rFontCollection)1749 PortionObj::PortionObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & rXTextRange,
1750                             sal_Bool bLast, FontCollection& rFontCollection ) :
1751     mnCharAttrHard          ( 0 ),
1752     mnCharAttr              ( 0 ),
1753     mnFont                  ( 0 ),
1754     mnAsianOrComplexFont    ( 0xffff ),
1755     mbLastPortion           ( bLast ),
1756     mpText                  ( NULL ),
1757     mpFieldEntry            ( NULL )
1758 {
1759     String aString( rXTextRange->getString() );
1760     String aURL;
1761     sal_Bool bRTL_endingParen = sal_False;
1762 
1763     mnTextSize = aString.Len();
1764     if ( bLast )
1765         mnTextSize++;
1766 
1767     if ( mnTextSize )
1768     {
1769         mpFieldEntry = NULL;
1770         sal_uInt32 nFieldType = 0;
1771 
1772         mXPropSet = ::com::sun::star::uno::Reference<
1773             ::com::sun::star::beans::XPropertySet >
1774                 ( rXTextRange, ::com::sun::star::uno::UNO_QUERY );
1775         mXPropState = ::com::sun::star::uno::Reference<
1776             ::com::sun::star::beans::XPropertyState >
1777                 ( rXTextRange, ::com::sun::star::uno::UNO_QUERY );
1778 
1779         sal_Bool bPropSetsValid = ( mXPropSet.is() && mXPropState.is() );
1780         if ( bPropSetsValid )
1781             nFieldType = ImplGetTextField( rXTextRange, mXPropSet, aURL );
1782         if ( nFieldType )
1783         {
1784             mpFieldEntry = new FieldEntry( nFieldType, 0, mnTextSize );
1785             if ( ( nFieldType >> 28 == 4 ) )
1786             {
1787                 mpFieldEntry->aRepresentation = aString;
1788                 mpFieldEntry->aFieldUrl = aURL;
1789             }
1790         }
1791         sal_Bool bSymbol = sal_False;
1792 
1793         if ( bPropSetsValid && ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontCharSet" ) ), sal_False ) )
1794         {
1795             sal_Int16 nCharset;
1796             mAny >>= nCharset;
1797             if ( nCharset == ::com::sun::star::awt::CharSet::SYMBOL )
1798                 bSymbol = sal_True;
1799         }
1800         if ( mpFieldEntry && ( nFieldType & 0x800000 ) )    // placeholder ?
1801         {
1802             mnTextSize = 1;
1803             if ( bLast )
1804                 mnTextSize++;
1805             mpText = new sal_uInt16[ mnTextSize ];
1806             mpText[ 0 ] = 0x2a;
1807         }
1808         else
1809         {
1810             const sal_Unicode* pText = aString.GetBuffer();
1811             // For i39516 - a closing parenthesis that ends an RTL string is displayed backwards by PPT
1812             // Solution: add a Unicode Right-to-Left Mark, following the method described in i18024
1813             if ( bLast && pText[ aString.Len() - 1 ] == sal_Unicode(')') && rFontCollection.GetScriptDirection( aString ) == com::sun::star::i18n::ScriptDirection::RIGHT_TO_LEFT )
1814             {
1815                 mnTextSize++;
1816                 bRTL_endingParen = sal_True;
1817             }
1818             mpText = new sal_uInt16[ mnTextSize ];
1819             sal_uInt16 nChar;
1820             for ( int i = 0; i < aString.Len(); i++ )
1821             {
1822                 nChar = (sal_uInt16)pText[ i ];
1823                 if ( nChar == 0xa )
1824                     nChar++;
1825                 else if ( !bSymbol )
1826                 {
1827                     switch ( nChar )
1828                     {
1829                         // Currency
1830                         case 128:   nChar = 0x20AC; break;
1831                         // Punctuation and other
1832                         case 130:   nChar = 0x201A; break;// SINGLE LOW-9 QUOTATION MARK
1833                         case 131:   nChar = 0x0192; break;// LATIN SMALL LETTER F WITH HOOK
1834                         case 132:   nChar = 0x201E; break;// DOUBLE LOW-9 QUOTATION MARK
1835                                                               // LOW DOUBLE PRIME QUOTATION MARK
1836                         case 133:   nChar = 0x2026; break;// HORIZONTAL ELLIPSES
1837                         case 134:   nChar = 0x2020; break;// DAGGER
1838                         case 135:   nChar = 0x2021; break;// DOUBLE DAGGER
1839                         case 136:   nChar = 0x02C6; break;// MODIFIER LETTER CIRCUMFLEX ACCENT
1840                         case 137:   nChar = 0x2030; break;// PER MILLE SIGN
1841                         case 138:   nChar = 0x0160; break;// LATIN CAPITAL LETTER S WITH CARON
1842                         case 139:   nChar = 0x2039; break;// SINGLE LEFT-POINTING ANGLE QUOTATION MARK
1843                         case 140:   nChar = 0x0152; break;// LATIN CAPITAL LIGATURE OE
1844                         case 142:   nChar = 0x017D; break;// LATIN CAPITAL LETTER Z WITH CARON
1845                         case 145:   nChar = 0x2018; break;// LEFT SINGLE QUOTATION MARK
1846                                                               // MODIFIER LETTER TURNED COMMA
1847                         case 146:   nChar = 0x2019; break;// RIGHT SINGLE QUOTATION MARK
1848                                                               // MODIFIER LETTER APOSTROPHE
1849                         case 147:   nChar = 0x201C; break;// LEFT DOUBLE QUOTATION MARK
1850                                                               // REVERSED DOUBLE PRIME QUOTATION MARK
1851                         case 148:   nChar = 0x201D; break;// RIGHT DOUBLE QUOTATION MARK
1852                                                               // REVERSED DOUBLE PRIME QUOTATION MARK
1853                         case 149:   nChar = 0x2022; break;// BULLET
1854                         case 150:   nChar = 0x2013; break;// EN DASH
1855                         case 151:   nChar = 0x2014; break;// EM DASH
1856                         case 152:   nChar = 0x02DC; break;// SMALL TILDE
1857                         case 153:   nChar = 0x2122; break;// TRADE MARK SIGN
1858                         case 154:   nChar = 0x0161; break;// LATIN SMALL LETTER S WITH CARON
1859                         case 155:   nChar = 0x203A; break;// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
1860                         case 156:   nChar = 0x0153; break;// LATIN SMALL LIGATURE OE
1861                         case 158:   nChar = 0x017E; break;// LATIN SMALL LETTER Z WITH CARON
1862                         case 159:   nChar = 0x0178; break;// LATIN CAPITAL LETTER Y WITH DIAERESIS
1863 //                      case 222:   nChar = 0x00B6; break;// PILCROW SIGN / PARAGRAPH SIGN
1864                     }
1865                 }
1866                 mpText[ i ] = nChar;
1867             }
1868         }
1869         if ( bRTL_endingParen )
1870             mpText[ mnTextSize - 2 ] = 0x200F; // Unicode Right-to-Left mark
1871 
1872         if ( bLast )
1873             mpText[ mnTextSize - 1 ] = 0xd;
1874 
1875         if ( bPropSetsValid )
1876             ImplGetPortionValues( rFontCollection, sal_True );
1877     }
1878 }
1879 
PortionObj(const PortionObj & rPortionObj)1880 PortionObj::PortionObj( const PortionObj& rPortionObj )
1881 : PropStateValue( rPortionObj )
1882 {
1883     ImplConstruct( rPortionObj );
1884 }
1885 
~PortionObj()1886 PortionObj::~PortionObj()
1887 {
1888     ImplClear();
1889 }
1890 
Write(SvStream * pStrm,sal_Bool bLast)1891 void PortionObj::Write( SvStream* pStrm, sal_Bool bLast )
1892 {
1893     sal_uInt32 nCount = mnTextSize;
1894     if ( bLast && mbLastPortion )
1895         nCount--;
1896     for ( sal_uInt32 i = 0; i < nCount; i++ )
1897         *pStrm << (sal_uInt16)mpText[ i ];
1898 }
1899 
ImplGetPortionValues(FontCollection & rFontCollection,sal_Bool bGetPropStateValue)1900 void PortionObj::ImplGetPortionValues( FontCollection& rFontCollection, sal_Bool bGetPropStateValue )
1901 {
1902 
1903     sal_Bool bOk = ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontName" ) ), bGetPropStateValue );
1904     meFontName = ePropState;
1905     if ( bOk )
1906     {
1907         FontCollectionEntry aFontDesc( *(::rtl::OUString*)mAny.getValue() );
1908         sal_uInt32  nCount = rFontCollection.GetCount();
1909         mnFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
1910         if ( mnFont == nCount )
1911         {
1912             FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
1913             if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontCharSet" ) ), sal_False ) )
1914                 mAny >>= rFontDesc.CharSet;
1915             if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontFamily" ) ), sal_False ) )
1916                 mAny >>= rFontDesc.Family;
1917             if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontPitch" ) ), sal_False ) )
1918                 mAny >>= rFontDesc.Pitch;
1919         }
1920     }
1921 
1922     sal_Int16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() );
1923     if ( mpText && mnTextSize && xPPTBreakIter.is() )
1924     {
1925         rtl::OUString sT( mpText, mnTextSize );
1926         nScriptType = xPPTBreakIter->getScriptType( sT, 0 );
1927     }
1928     if ( nScriptType != com::sun::star::i18n::ScriptType::COMPLEX )
1929     {
1930         bOk = ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontNameAsian" ) ), bGetPropStateValue );
1931         meAsianOrComplexFont = ePropState;
1932         if ( bOk )
1933         {
1934             FontCollectionEntry aFontDesc( *(::rtl::OUString*)mAny.getValue() );
1935             sal_uInt32  nCount = rFontCollection.GetCount();
1936             mnAsianOrComplexFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
1937             if ( mnAsianOrComplexFont == nCount )
1938             {
1939                 FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
1940                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontCharSetAsian" ) ), sal_False ) )
1941                     mAny >>= rFontDesc.CharSet;
1942                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontFamilyAsian" ) ), sal_False ) )
1943                     mAny >>= rFontDesc.Family;
1944                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontPitchAsian" ) ), sal_False ) )
1945                     mAny >>= rFontDesc.Pitch;
1946             }
1947         }
1948     }
1949     else
1950     {
1951         bOk = ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontNameComplex" ) ), bGetPropStateValue );
1952         meAsianOrComplexFont = ePropState;
1953         if ( bOk )
1954         {
1955             FontCollectionEntry aFontDesc( *(::rtl::OUString*)mAny.getValue() );
1956             sal_uInt32  nCount = rFontCollection.GetCount();
1957             mnAsianOrComplexFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
1958             if ( mnAsianOrComplexFont == nCount )
1959             {
1960                 FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
1961                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontCharSetComplex" ) ), sal_False ) )
1962                     mAny >>= rFontDesc.CharSet;
1963                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontFamilyComplex" ) ), sal_False ) )
1964                     mAny >>= rFontDesc.Family;
1965                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontPitchComplex" ) ), sal_False ) )
1966                     mAny >>= rFontDesc.Pitch;
1967             }
1968         }
1969     }
1970 
1971     rtl::OUString aCharHeightName, aCharWeightName, aCharLocaleName, aCharPostureName;
1972     switch( nScriptType )
1973     {
1974         case com::sun::star::i18n::ScriptType::ASIAN :
1975         {
1976             aCharHeightName  = String( RTL_CONSTASCII_USTRINGPARAM( "CharHeightAsian" ) );
1977             aCharWeightName  = String( RTL_CONSTASCII_USTRINGPARAM( "CharWeightAsian" ) );
1978             aCharLocaleName  = String( RTL_CONSTASCII_USTRINGPARAM( "CharLocaleAsian" ) );
1979             aCharPostureName = String( RTL_CONSTASCII_USTRINGPARAM( "CharPostureAsian" ) );
1980             break;
1981         }
1982         case com::sun::star::i18n::ScriptType::COMPLEX :
1983         {
1984             aCharHeightName  = String( RTL_CONSTASCII_USTRINGPARAM( "CharHeightComplex" ) );
1985             aCharWeightName  = String( RTL_CONSTASCII_USTRINGPARAM( "CharWeightComplex" ) );
1986             aCharLocaleName  = String( RTL_CONSTASCII_USTRINGPARAM( "CharLocaleComplex" ) );
1987             aCharPostureName = String( RTL_CONSTASCII_USTRINGPARAM( "CharPostureComplex" ) );
1988             break;
1989         }
1990         default:
1991         {
1992             aCharHeightName  = String( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" ) );
1993             aCharWeightName  = String( RTL_CONSTASCII_USTRINGPARAM( "CharWeight" ) );
1994             aCharLocaleName  = String( RTL_CONSTASCII_USTRINGPARAM( "CharLocale" ) );
1995             aCharPostureName = String( RTL_CONSTASCII_USTRINGPARAM( "CharPosture" ) );
1996             break;
1997         }
1998     }
1999 
2000     mnCharHeight = 24;
2001     if ( GetPropertyValue( mAny, mXPropSet, aCharHeightName, sal_False ) )
2002     {
2003         float fVal(0.0);
2004         if ( mAny >>= fVal )
2005         {
2006             mnCharHeight = (sal_uInt16)( fVal + 0.5 );
2007             meCharHeight = GetPropertyState( mXPropSet, aCharHeightName );
2008         }
2009     }
2010     if ( GetPropertyValue( mAny, mXPropSet, aCharWeightName, sal_False ) )
2011     {
2012         float fFloat(0.0);
2013         if ( mAny >>= fFloat )
2014         {
2015             if ( fFloat >= ::com::sun::star::awt::FontWeight::SEMIBOLD )
2016                 mnCharAttr |= 1;
2017             if ( GetPropertyState( mXPropSet, aCharWeightName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2018                 mnCharAttrHard |= 1;
2019         }
2020     }
2021     if ( GetPropertyValue( mAny, mXPropSet, aCharLocaleName, sal_False ) )
2022     {
2023         com::sun::star::lang::Locale eLocale;
2024         if ( mAny >>= eLocale )
2025             meCharLocale = eLocale;
2026     }
2027     if ( GetPropertyValue( mAny, mXPropSet, aCharPostureName, sal_False ) )
2028     {
2029         ::com::sun::star::awt::FontSlant aFS;
2030         if ( mAny >>= aFS )
2031         {
2032             switch( aFS )
2033             {
2034                 case ::com::sun::star::awt::FontSlant_OBLIQUE :
2035                 case ::com::sun::star::awt::FontSlant_ITALIC :
2036                     mnCharAttr |= 2;
2037                     break;
2038                 default:
2039                     break;
2040             }
2041             if ( GetPropertyState( mXPropSet, aCharPostureName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2042                 mnCharAttrHard |= 2;
2043         }
2044     }
2045 
2046     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharUnderline" ) ), bGetPropStateValue ) )
2047     {
2048         sal_Int16 nVal(0);
2049         mAny >>= nVal;
2050         switch ( nVal )
2051         {
2052             case ::com::sun::star::awt::FontUnderline::SINGLE :
2053             case ::com::sun::star::awt::FontUnderline::DOUBLE :
2054             case ::com::sun::star::awt::FontUnderline::DOTTED :
2055                 mnCharAttr |= 4;
2056         }
2057     }
2058     if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2059         mnCharAttrHard |= 4;
2060 
2061     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharShadowed" ) ), bGetPropStateValue ) )
2062     {
2063         sal_Bool bBool(sal_False);
2064         mAny >>= bBool;
2065         if ( bBool )
2066             mnCharAttr |= 0x10;
2067     }
2068     if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2069         mnCharAttrHard |= 16;
2070 
2071     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharRelief" ) ), bGetPropStateValue ) )
2072     {
2073         sal_Int16 nVal(0);
2074         mAny >>= nVal;
2075         if ( nVal != ::com::sun::star::text::FontRelief::NONE )
2076             mnCharAttr |= 512;
2077     }
2078     if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2079         mnCharAttrHard |= 512;
2080 
2081     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharColor" ) ), bGetPropStateValue ) )
2082     {
2083         sal_uInt32 nSOColor = *( (sal_uInt32*)mAny.getValue() );
2084         mnCharColor = nSOColor & 0xff00ff00;                            // green and hibyte
2085         mnCharColor |= (sal_uInt8)( nSOColor ) << 16;                   // red and blue is switched
2086         mnCharColor |= (sal_uInt8)( nSOColor >> 16 );
2087     }
2088     meCharColor = ePropState;
2089 
2090     mnCharEscapement = 0;
2091     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ), bGetPropStateValue ) )
2092     {
2093         mAny >>= mnCharEscapement;
2094         if ( mnCharEscapement > 100 )
2095             mnCharEscapement = 33;
2096         else if ( mnCharEscapement < -100 )
2097             mnCharEscapement = -33;
2098     }
2099     meCharEscapement = ePropState;
2100 }
2101 
ImplClear()2102 void PortionObj::ImplClear()
2103 {
2104     delete (FieldEntry*)mpFieldEntry;
2105     delete[] mpText;
2106 }
2107 
ImplConstruct(const PortionObj & rPortionObj)2108 void PortionObj::ImplConstruct( const PortionObj& rPortionObj )
2109 {
2110     mbLastPortion = rPortionObj.mbLastPortion;
2111     mnTextSize = rPortionObj.mnTextSize;
2112     mnCharColor = rPortionObj.mnCharColor;
2113     mnCharEscapement = rPortionObj.mnCharEscapement;
2114     mnCharAttr = rPortionObj.mnCharAttr;
2115     mnCharHeight = rPortionObj.mnCharHeight;
2116     mnFont = rPortionObj.mnFont;
2117     mnAsianOrComplexFont = rPortionObj.mnAsianOrComplexFont;
2118 
2119     if ( rPortionObj.mpText )
2120     {
2121         mpText = new sal_uInt16[ mnTextSize ];
2122         memcpy( mpText, rPortionObj.mpText, mnTextSize << 1 );
2123     }
2124     else
2125         mpText = NULL;
2126 
2127     if ( rPortionObj.mpFieldEntry )
2128         mpFieldEntry = new FieldEntry( *( rPortionObj.mpFieldEntry ) );
2129     else
2130         mpFieldEntry = NULL;
2131 }
2132 
ImplCalculateTextPositions(sal_uInt32 nCurrentTextPosition)2133 sal_uInt32 PortionObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition )
2134 {
2135     if ( mpFieldEntry && ( !mpFieldEntry->nFieldStartPos ) )
2136     {
2137         mpFieldEntry->nFieldStartPos += nCurrentTextPosition;
2138         mpFieldEntry->nFieldEndPos += nCurrentTextPosition;
2139     }
2140     return mnTextSize;
2141 }
2142 
2143 //  -----------------------------------------------------------------------
2144 // Rueckgabe:                           0 = kein TextField
2145 //  bit28->31   text field type :
2146 //                                      1 = Date
2147 //                                      2 = Time
2148 //                                      3 = SlideNumber
2149 //                                      4 = Url
2150 //                                      5 = DateTime
2151 //                                      6 = header
2152 //                                      7 = footer
2153 //  bit24->27   text field sub type (optional)
2154 //     23->     PPT Textfield needs a placeholder
2155 
ImplGetTextField(::com::sun::star::uno::Reference<::com::sun::star::text::XTextRange> &,const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPropSet,String & rURL)2156 sal_uInt32 PortionObj::ImplGetTextField( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & ,
2157     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, String& rURL )
2158 {
2159     sal_uInt32 nRetValue = 0;
2160     sal_Int32 nFormat;
2161     ::com::sun::star::uno::Any aAny;
2162     if ( GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextPortionType" ) ), sal_True ) )
2163     {
2164         String  aTextFieldType( *(::rtl::OUString*)aAny.getValue() );
2165         if ( aTextFieldType == String( RTL_CONSTASCII_USTRINGPARAM( "TextField" ) ) )
2166         {
2167             if ( GetPropertyValue( aAny, rXPropSet, aTextFieldType, sal_True ) )
2168             {
2169                 ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextField > aXTextField;
2170                 if ( aAny >>= aXTextField )
2171                 {
2172                     if ( aXTextField.is() )
2173                     {
2174                         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
2175                             xFieldPropSet( aXTextField, ::com::sun::star::uno::UNO_QUERY );
2176                         if ( xFieldPropSet.is() )
2177                         {
2178                             String aFieldKind( aXTextField->getPresentation( sal_True ) );
2179                             if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Date" ) ) )
2180                             {
2181                                 if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFix" ) ) ), sal_True )
2182                                 {
2183                                     sal_Bool bBool;
2184                                     aAny >>= bBool;
2185                                     if ( !bBool )  // Fixed DateFields gibt es in PPT nicht
2186                                     {
2187                                         if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Format" ) ) ), sal_True )
2188                                         {
2189                                             nFormat = *(sal_Int32*)aAny.getValue();
2190                                             switch ( nFormat )
2191                                             {
2192                                                 default:
2193                                                 case 5 :
2194                                                 case 4 :
2195                                                 case 2 : nFormat = 0; break;
2196                                                 case 8 :
2197                                                 case 9 :
2198                                                 case 3 : nFormat = 1; break;
2199                                                 case 7 :
2200                                                 case 6 : nFormat = 2; break;
2201                                             }
2202                                             nRetValue |= ( ( ( 1 << 4 ) | nFormat ) << 24 ) | 0x800000;
2203                                         }
2204                                     }
2205                                 }
2206                             }
2207                             else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) )
2208                             {
2209                                 if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ), sal_True )
2210                                     rURL = String( *(::rtl::OUString*)aAny.getValue() );
2211                                 nRetValue = 4 << 28;
2212                             }
2213                             else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Page" ) ) )
2214                             {
2215                                 nRetValue = 3 << 28 | 0x800000;
2216                             }
2217                             else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Pages" ) ) )
2218                             {
2219 
2220                             }
2221                             else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Time" ) ) )
2222                             {
2223                                 if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFix" ) ) ), sal_True )
2224                                 {
2225                                     sal_Bool bBool;
2226                                     aAny >>= bBool;
2227                                     if ( !bBool )
2228                                     {
2229                                         if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFix" ) ) ), sal_True )
2230                                         {
2231                                             nFormat = *(sal_Int32*)aAny.getValue();
2232                                             nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000;
2233                                         }
2234                                     }
2235                                 }
2236                             }
2237                             else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "File" ) ) )
2238                             {
2239 
2240                             }
2241                             else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Table" ) ) )
2242                             {
2243 
2244                             }
2245                             else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "ExtTime" ) ) )
2246                             {
2247                                 if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFix" ) ) ), sal_True )
2248                                 {
2249                                     sal_Bool bBool;
2250                                     aAny >>= bBool;
2251                                     if ( !bBool )
2252                                     {
2253                                         if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Format" ) ) ), sal_True )
2254                                         {
2255                                             nFormat = *(sal_Int32*)aAny.getValue();
2256                                             switch ( nFormat )
2257                                             {
2258                                                 default:
2259                                                 case 6 :
2260                                                 case 7 :
2261                                                 case 8 :
2262                                                 case 2 : nFormat = 12; break;
2263                                                 case 3 : nFormat = 9; break;
2264                                                 case 5 :
2265                                                 case 4 : nFormat = 10; break;
2266 
2267                                             }
2268                                             nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000;
2269                                         }
2270                                     }
2271                                 }
2272                             }
2273                             else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "ExtFile" ) ) )
2274                             {
2275 
2276                             }
2277                             else if ( aFieldKind ==  String( RTL_CONSTASCII_USTRINGPARAM( "Author" ) ) )
2278                             {
2279 
2280                             }
2281                             else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "DateTime" ) ) )
2282                             {
2283                                 nRetValue = 5 << 28 | 0x800000;
2284                             }
2285                             else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Header" ) ) )
2286                             {
2287                                 nRetValue = 6 << 28 | 0x800000;
2288                             }
2289                             else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Footer" ) ) )
2290                             {
2291                                 nRetValue = 7 << 28 | 0x800000;
2292                             }
2293                         }
2294                     }
2295                 }
2296             }
2297         }
2298     }
2299     return nRetValue;
2300 }
2301 
operator =(const PortionObj & rPortionObj)2302 PortionObj& PortionObj::operator=( const PortionObj& rPortionObj )
2303 {
2304     if ( this != &rPortionObj )
2305     {
2306         ImplClear();
2307         ImplConstruct( rPortionObj );
2308     }
2309     return *this;
2310 }
2311 
2312 //  -----------------------------------------------------------------------
2313 
ParagraphObj(const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPropSet,PPTExBulletProvider & rProv)2314 ParagraphObj::ParagraphObj( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
2315                 PPTExBulletProvider& rProv ) :
2316     maMapModeSrc        ( MAP_100TH_MM ),
2317     maMapModeDest       ( MAP_INCH, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ) )
2318 {
2319     mXPropSet = rXPropSet;
2320 
2321     bExtendedParameters = sal_False;
2322 
2323     nDepth = 0;
2324     nBulletFlags = 0;
2325     nParaFlags = 0;
2326 
2327     ImplGetParagraphValues( rProv, sal_False );
2328 }
2329 
ParagraphObj(::com::sun::star::uno::Reference<::com::sun::star::text::XTextContent> & rXTextContent,ParaFlags aParaFlags,FontCollection & rFontCollection,PPTExBulletProvider & rProv)2330     ParagraphObj::ParagraphObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > & rXTextContent,
2331                     ParaFlags aParaFlags, FontCollection& rFontCollection, PPTExBulletProvider& rProv ) :
2332     maMapModeSrc        ( MAP_100TH_MM ),
2333     maMapModeDest       ( MAP_INCH, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ) ),
2334     mbFirstParagraph    ( aParaFlags.bFirstParagraph ),
2335     mbLastParagraph     ( aParaFlags.bLastParagraph )
2336 {
2337     bExtendedParameters = sal_False;
2338 
2339     nDepth = 0;
2340     nBulletFlags = 0;
2341     nParaFlags = 0;
2342 
2343     mXPropSet = ::com::sun::star::uno::Reference<
2344         ::com::sun::star::beans::XPropertySet >
2345             ( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
2346 
2347     mXPropState = ::com::sun::star::uno::Reference<
2348         ::com::sun::star::beans::XPropertyState >
2349             ( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
2350 
2351     if ( mXPropSet.is() && mXPropState.is() )
2352     {
2353         ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumerationAccess >
2354             aXTextPortionEA( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
2355         if ( aXTextPortionEA.is() )
2356         {
2357             ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration >
2358                 aXTextPortionE( aXTextPortionEA->createEnumeration() );
2359             if ( aXTextPortionE.is() )
2360             {
2361                 while ( aXTextPortionE->hasMoreElements() )
2362                 {
2363                     ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > aXCursorText;
2364                     ::com::sun::star::uno::Any aAny( aXTextPortionE->nextElement() );
2365                     if ( aAny >>= aXCursorText )
2366                     {
2367                         PortionObj* pPortionObj = new PortionObj( aXCursorText, !aXTextPortionE->hasMoreElements(), rFontCollection );
2368                         if ( pPortionObj->Count() )
2369                             Insert( pPortionObj, LIST_APPEND );
2370                         else
2371                             delete pPortionObj;
2372                     }
2373                 }
2374             }
2375         }
2376         ImplGetParagraphValues( rProv, sal_True );//
2377     }
2378 }
2379 
ParagraphObj(const ParagraphObj & rObj)2380 ParagraphObj::ParagraphObj( const ParagraphObj& rObj )
2381 : List()
2382 , PropStateValue()
2383 , SOParagraph()
2384 {
2385     ImplConstruct( rObj );
2386 }
2387 
~ParagraphObj()2388 ParagraphObj::~ParagraphObj()
2389 {
2390     ImplClear();
2391 }
2392 
Write(SvStream * pStrm)2393 void ParagraphObj::Write( SvStream* pStrm )
2394 {
2395     for ( void* pPtr = First(); pPtr; pPtr = Next() )
2396         ((PortionObj*)pPtr)->Write( pStrm, mbLastParagraph );
2397 }
2398 
ImplClear()2399 void ParagraphObj::ImplClear()
2400 {
2401     for ( void* pPtr = First(); pPtr; pPtr = Next() )
2402         delete (PortionObj*)pPtr;
2403 }
2404 
CalculateGraphicBulletSize(sal_uInt16 nFontHeight)2405 void ParagraphObj::CalculateGraphicBulletSize( sal_uInt16 nFontHeight )
2406 {
2407     if ( ( (SvxExtNumType)nNumberingType == SVX_NUM_BITMAP ) && ( nBulletId != 0xffff ) )
2408     {
2409         // calculate the bulletrealsize for this grafik
2410         if ( aBuGraSize.Width() && aBuGraSize.Height() )
2411         {
2412             double fCharHeight = nFontHeight;
2413             double fLen = aBuGraSize.Height();
2414             fCharHeight = fCharHeight * 0.2540;
2415             double fQuo = fLen / fCharHeight;
2416             nBulletRealSize = (sal_Int16)( fQuo + 0.5 );
2417             if ( (sal_uInt16)nBulletRealSize > 400 )
2418                 nBulletRealSize = 400;
2419         }
2420     }
2421 }
2422 
2423 // from sw/source/filter/ww8/wrtw8num.cxx for default bullets to export to MS intact
lcl_SubstituteBullet(String & rNumStr,rtl_TextEncoding & rChrSet,String & rFontName)2424 static void lcl_SubstituteBullet(String& rNumStr, rtl_TextEncoding& rChrSet, String& rFontName)
2425 {
2426     sal_Unicode cChar = rNumStr.GetChar(0);
2427     StarSymbolToMSMultiFont *pConvert = CreateStarSymbolToMSMultiFont();
2428     String sFont = pConvert->ConvertChar(cChar);
2429     delete pConvert;
2430     if (sFont.Len())
2431     {
2432         rNumStr = static_cast< sal_Unicode >(cChar | 0xF000);
2433         rFontName = sFont;
2434         rChrSet = RTL_TEXTENCODING_SYMBOL;
2435     }
2436     else if ( (rNumStr.GetChar(0) < 0xE000 || rNumStr.GetChar(0) > 0xF8FF) )
2437     {
2438         /*
2439         Ok we can't fit into a known windows unicode font, but
2440         we are not in the private area, so we are a
2441         standardized symbol, so turn off the symbol bit and
2442         let words own font substitution kick in
2443         */
2444         rChrSet = RTL_TEXTENCODING_UNICODE;
2445         rFontName = ::GetFontToken(rFontName, 0);
2446     }
2447     else
2448     {
2449         /*
2450         Well we don't have an available substition, and we're
2451         in our private area, so give up and show a standard
2452         bullet symbol
2453         */
2454         rFontName.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Wingdings"));
2455         rNumStr = static_cast< sal_Unicode >(0x6C);
2456      }
2457 }
2458 
ImplGetNumberingLevel(PPTExBulletProvider & rBuProv,sal_Int16 nNumberingDepth,sal_Bool bIsBullet,sal_Bool bGetPropStateValue)2459 void ParagraphObj::ImplGetNumberingLevel( PPTExBulletProvider& rBuProv, sal_Int16 nNumberingDepth, sal_Bool bIsBullet, sal_Bool bGetPropStateValue )
2460 {
2461     ::com::sun::star::uno::Any aAny;
2462     if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "ParaLeftMargin" ) ) ) )
2463     {
2464         sal_Int32 nVal;
2465         if ( aAny >>= nVal )
2466             nTextOfs = static_cast< sal_Int16 >( nVal / ( 2540.0 / 576 ) + 0.5 ) ;
2467     }
2468     if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "ParaFirstLineIndent" ) ) ) )
2469     {
2470         if ( aAny >>= nBulletOfs )
2471             nBulletOfs = static_cast< sal_Int32 >( nBulletOfs / ( 2540.0 / 576 ) + 0.5 );
2472     }
2473     if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "NumberingIsNumber" ) ) ) )
2474         aAny >>= bNumberingIsNumber;
2475 
2476     ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexReplace > aXIndexReplace;
2477 
2478     if ( bIsBullet && ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "NumberingRules" ) ), bGetPropStateValue ) )
2479     {
2480         if ( ( mAny >>= aXIndexReplace ) && nNumberingDepth < aXIndexReplace->getCount() )
2481         {
2482             mAny <<= aXIndexReplace->getByIndex( nNumberingDepth );
2483             ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>
2484                 aPropertySequence( *( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>*)mAny.getValue() );
2485 
2486             const ::com::sun::star::beans::PropertyValue* pPropValue = aPropertySequence.getArray();
2487 
2488             sal_Int32 nPropertyCount = aPropertySequence.getLength();
2489             if ( nPropertyCount )
2490             {
2491                 bExtendedParameters = sal_True;
2492                 nBulletRealSize = 100;
2493                 nMappedNumType = 0;
2494 
2495                 String aGraphicURL;
2496                 for ( sal_Int32 i = 0; i < nPropertyCount; i++ )
2497                 {
2498                     const void* pValue = pPropValue[ i ].Value.getValue();
2499                     if ( pValue )
2500                     {
2501                         ::rtl::OUString aPropName( pPropValue[ i ].Name );
2502                         if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "NumberingType" ) ) )
2503                             nNumberingType = *( (sal_Int16*)pValue );
2504                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Adjust" ) ) )
2505                             nHorzAdjust = *( (sal_Int16*)pValue );
2506                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletChar" ) ) )
2507                         {
2508                             String aString( *( (String*)pValue ) );
2509                             if ( aString.Len() )
2510                                 cBulletId = aString.GetChar( 0 );
2511                         }
2512                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletFont" ) ) )
2513                         {
2514                             aFontDesc = *( (::com::sun::star::awt::FontDescriptor*)pValue );
2515 
2516                             // Our numbullet dialog has set the wrong textencoding for our "StarSymbol" font,
2517                             // instead of a Unicode encoding the encoding RTL_TEXTENCODING_SYMBOL was used.
2518                             // Because there might exist a lot of damaged documemts I added this two lines
2519                             // which fixes the bullet problem for the export.
2520                             if ( aFontDesc.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StarSymbol" ) ) )
2521                                 aFontDesc.CharSet = RTL_TEXTENCODING_MS_1252;
2522 
2523                         }
2524                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicURL" ) ) )
2525                             aGraphicURL = ( *(::rtl::OUString*)pValue );
2526                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicSize" ) ) )
2527                         {
2528                             if ( pPropValue[ i ].Value.getValueType() == ::getCppuType( (::com::sun::star::awt::Size*)0) )
2529                             {
2530                                 // don't cast awt::Size to Size as on 64-bits they are not the same.
2531                                 ::com::sun::star::awt::Size aSize;
2532                                 pPropValue[ i ].Value >>= aSize;
2533                                 aBuGraSize.nA = aSize.Width;
2534                                 aBuGraSize.nB = aSize.Height;
2535                             }
2536                         }
2537                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StartWith" ) ) )
2538                             nStartWith = *( (sal_Int16*)pValue );
2539                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "LeftMargin" ) ) )
2540                             nTextOfs = nTextOfs + static_cast< sal_Int16 >( *( (sal_Int32*)pValue ) / ( 2540.0 / 576 ) );
2541                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FirstLineOffset" ) ) )
2542                             nBulletOfs += (sal_Int16)( *( (sal_Int32*)pValue ) / ( 2540.0 / 576 ) );
2543                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletColor" ) ) )
2544                         {
2545                             sal_uInt32 nSOColor = *( (sal_uInt32*)pValue );
2546                             nBulletColor = nSOColor & 0xff00ff00;                       // green and hibyte
2547                             nBulletColor |= (sal_uInt8)( nSOColor ) << 16;              // red
2548                             nBulletColor |= (sal_uInt8)( nSOColor >> 16 ) | 0xfe000000; // blue
2549                         }
2550                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletRelSize" ) ) )
2551                         {
2552                             nBulletRealSize = *( (sal_Int16*)pValue );
2553                             nParaFlags |= 0x40;
2554                             nBulletFlags |= 8;
2555                         }
2556                         else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Prefix" ) ) )
2557                             sPrefix = ( *(::rtl::OUString*)pValue );
2558                         else if  ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Suffix" ) ) )
2559                             sSuffix = ( *(::rtl::OUString*)pValue );
2560 #ifdef DBG_UTIL
2561                         else if ( ! (
2562                                 ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SymbolTextDistance" ) ) )
2563                             ||  ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Graphic" ) ) ) ) )
2564                         {
2565                             DBG_ERROR( "Unbekanntes Property" );
2566                         }
2567 #endif
2568                     }
2569                 }
2570 
2571                 if ( aGraphicURL.Len() )
2572                 {
2573                     if ( aBuGraSize.Width() && aBuGraSize.Height() )
2574                     {
2575                         xub_StrLen nIndex = aGraphicURL.Search( (sal_Unicode)':', 0 );
2576                         if ( nIndex != STRING_NOTFOUND )
2577                         {
2578                             nIndex++;
2579                             if ( aGraphicURL.Len() > nIndex  )
2580                             {
2581                                 ByteString aUniqueId( aGraphicURL, nIndex, aGraphicURL.Len() - nIndex, RTL_TEXTENCODING_UTF8 );
2582                                 if ( aUniqueId.Len() )
2583                                 {
2584                                     nBulletId = rBuProv.GetId( aUniqueId, aBuGraSize );
2585                                     if ( nBulletId != 0xffff )
2586                                         bExtendedBulletsUsed = sal_True;
2587                                 }
2588                             }
2589                         }
2590                     }
2591                     else
2592                     {
2593                         nNumberingType = SVX_NUM_NUMBER_NONE;
2594                     }
2595                 }
2596 
2597                 PortionObj* pPortion = (PortionObj*)First();
2598                 CalculateGraphicBulletSize( ( pPortion ) ? pPortion->mnCharHeight : 24 );
2599 
2600                 switch( (SvxExtNumType)nNumberingType )
2601                 {
2602                     case SVX_NUM_NUMBER_NONE : nParaFlags |= 0xf; break;
2603 
2604                     case SVX_NUM_CHAR_SPECIAL :                           // Bullet
2605                     {
2606                         if ( aFontDesc.Name.equalsIgnoreAsciiCaseAscii("starsymbol") ||
2607                             aFontDesc.Name.equalsIgnoreAsciiCaseAscii("opensymbol") )
2608                         {
2609                             String sFontName = aFontDesc.Name;
2610                             String sNumStr = cBulletId;
2611                             rtl_TextEncoding eChrSet = aFontDesc.CharSet;
2612                             lcl_SubstituteBullet(sNumStr,eChrSet,sFontName);
2613                             aFontDesc.Name = sFontName;
2614                             cBulletId = sNumStr.GetChar( 0 );
2615                             aFontDesc.CharSet = eChrSet;
2616                          }
2617 
2618                         if ( aFontDesc.Name.getLength() )
2619                         {
2620 /*
2621                             if ( aFontDesc.CharSet != ::com::sun::star::awt::CharSet::SYMBOL )
2622                             {
2623                                 switch ( cBulletId )
2624                                 {
2625                                     // Currency
2626                                     case 128:   cBulletId = 0x20AC; break;
2627                                     // Punctuation and other
2628                                     case 130:   cBulletId = 0x201A; break;// SINGLE LOW-9 QUOTATION MARK
2629                                     case 131:   cBulletId = 0x0192; break;// LATIN SMALL LETTER F WITH HOOK
2630                                     case 132:   cBulletId = 0x201E; break;// DOUBLE LOW-9 QUOTATION MARK
2631                                                                           // LOW DOUBLE PRIME QUOTATION MARK
2632                                     case 133:   cBulletId = 0x2026; break;// HORIZONTAL ELLIPSES
2633                                     case 134:   cBulletId = 0x2020; break;// DAGGER
2634                                     case 135:   cBulletId = 0x2021; break;// DOUBLE DAGGER
2635                                     case 136:   cBulletId = 0x02C6; break;// MODIFIER LETTER CIRCUMFLEX ACCENT
2636                                     case 137:   cBulletId = 0x2030; break;// PER MILLE SIGN
2637                                     case 138:   cBulletId = 0x0160; break;// LATIN CAPITAL LETTER S WITH CARON
2638                                     case 139:   cBulletId = 0x2039; break;// SINGLE LEFT-POINTING ANGLE QUOTATION MARK
2639                                     case 140:   cBulletId = 0x0152; break;// LATIN CAPITAL LIGATURE OE
2640                                     case 142:   cBulletId = 0x017D; break;// LATIN CAPITAL LETTER Z WITH CARON
2641                                     case 145:   cBulletId = 0x2018; break;// LEFT SINGLE QUOTATION MARK
2642                                                                           // MODIFIER LETTER TURNED COMMA
2643                                     case 146:   cBulletId = 0x2019; break;// RIGHT SINGLE QUOTATION MARK
2644                                                                           // MODIFIER LETTER APOSTROPHE
2645                                     case 147:   cBulletId = 0x201C; break;// LEFT DOUBLE QUOTATION MARK
2646                                                                           // REVERSED DOUBLE PRIME QUOTATION MARK
2647                                     case 148:   cBulletId = 0x201D; break;// RIGHT DOUBLE QUOTATION MARK
2648                                                                           // REVERSED DOUBLE PRIME QUOTATION MARK
2649                                     case 149:   cBulletId = 0x2022; break;// BULLET
2650                                     case 150:   cBulletId = 0x2013; break;// EN DASH
2651                                     case 151:   cBulletId = 0x2014; break;// EM DASH
2652                                     case 152:   cBulletId = 0x02DC; break;// SMALL TILDE
2653                                     case 153:   cBulletId = 0x2122; break;// TRADE MARK SIGN
2654                                     case 154:   cBulletId = 0x0161; break;// LATIN SMALL LETTER S WITH CARON
2655                                     case 155:   cBulletId = 0x203A; break;// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
2656                                     case 156:   cBulletId = 0x0153; break;// LATIN SMALL LIGATURE OE
2657                                     case 158:   cBulletId = 0x017E; break;// LATIN SMALL LETTER Z WITH CARON
2658                                     case 159:   cBulletId = 0x0178; break;// LATIN CAPITAL LETTER Y WITH DIAERESIS
2659 //                                  case 222:   cBulletId = 0x00B6; break;// PILCROW SIGN / PARAGRAPH SIGN
2660                                 }
2661                             }
2662 */
2663                             nParaFlags |= 0x90; // wir geben den Font und den Charset vor
2664                         }
2665                     }
2666                     case SVX_NUM_CHARS_UPPER_LETTER :       // zaehlt von a-z, aa - az, ba - bz, ...
2667                     case SVX_NUM_CHARS_LOWER_LETTER :
2668                     case SVX_NUM_ROMAN_UPPER :
2669                     case SVX_NUM_ROMAN_LOWER :
2670                     case SVX_NUM_ARABIC :
2671                     case SVX_NUM_PAGEDESC :                 // Numerierung aus der Seitenvorlage
2672                     case SVX_NUM_BITMAP :
2673                     case SVX_NUM_CHARS_UPPER_LETTER_N :     // zaehlt von  a-z, aa-zz, aaa-zzz
2674                     case SVX_NUM_CHARS_LOWER_LETTER_N :
2675                     case SVX_NUM_NUMBER_UPPER_ZH:
2676                     case SVX_NUM_CIRCLE_NUMBER:
2677                     case SVX_NUM_NUMBER_UPPER_ZH_TW:
2678                     case SVX_NUM_NUMBER_LOWER_ZH:
2679                     case SVX_NUM_FULL_WIDTH_ARABIC:
2680                     {
2681                         if ( nNumberingType != SVX_NUM_CHAR_SPECIAL )
2682                         {
2683                             bExtendedBulletsUsed = sal_True;
2684                             if ( nNumberingDepth & 1 )
2685                                 cBulletId = 0x2013;         // defaulting bullet characters for ppt97
2686                             else if ( nNumberingDepth == 4 )
2687                                 cBulletId = 0xbb;
2688                             else
2689                                 cBulletId = 0x2022;
2690 
2691                             switch( (SvxExtNumType)nNumberingType )
2692                             {
2693                                 case SVX_NUM_CHARS_UPPER_LETTER :
2694                                 case SVX_NUM_CHARS_UPPER_LETTER_N :
2695                                 {
2696                                     if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) )
2697                                     {
2698                                         if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) )
2699                                             nMappedNumType = 0xa0001;   // (A)
2700                                         else
2701                                             nMappedNumType = 0xb0001;   // A)
2702                                     }
2703                                     else
2704                                         nMappedNumType = 0x10001;       // A.
2705                                 }
2706                                 break;
2707                                 case SVX_NUM_CHARS_LOWER_LETTER :
2708                                 case SVX_NUM_CHARS_LOWER_LETTER_N :
2709                                 {
2710                                     if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) )
2711                                     {
2712                                         if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) )
2713                                             nMappedNumType = 0x80001;   // (a)
2714                                         else
2715                                             nMappedNumType = 0x90001;   // a)
2716                                     }
2717                                     else
2718                                         nMappedNumType = 0x00001;       // a.
2719                                 }
2720                                 break;
2721                                 case SVX_NUM_ROMAN_UPPER :
2722                                 {
2723                                     if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) )
2724                                     {
2725                                         if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) )
2726                                             nMappedNumType = 0xe0001;   // (I)
2727                                         else
2728                                             nMappedNumType = 0xf0001;   // I)
2729                                     }
2730                                     else
2731                                         nMappedNumType = 0x70001;       // I.
2732                                 }
2733                                 break;
2734                                 case SVX_NUM_ROMAN_LOWER :
2735                                 {
2736                                     if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) )
2737                                     {
2738                                         if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) )
2739                                             nMappedNumType = 0x40001;   // (i)
2740                                         else
2741                                             nMappedNumType = 0x50001;   // i)
2742                                     }
2743                                     else
2744                                         nMappedNumType = 0x60001;       // i.
2745                                 }
2746                                 break;
2747                                 case SVX_NUM_ARABIC :
2748                                 {
2749                                     if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) )
2750                                     {
2751                                         if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) )
2752                                             nMappedNumType = 0xc0001;   // (1)
2753                                         else
2754                                             nMappedNumType = 0x20001;   // 1)
2755                                     }
2756                                     else
2757                                     {
2758                                         if ( ! ( sSuffix.Len() + sPrefix.Len() ) )
2759                                             nMappedNumType = 0xd0001;   // 1
2760                                         else
2761                                             nMappedNumType = 0x30001;   // 1.
2762                                     }
2763                                 }
2764                                 break;
2765                                 case SVX_NUM_NUMBER_UPPER_ZH :
2766                                 {
2767                                     if ( sSuffix.Len() )
2768                                         nMappedNumType = 0x110001;   // Simplified Chinese with single-byte period.
2769                                     else
2770                                         nMappedNumType = 0x100001;   // Simplified Chinese.
2771                                 }
2772                                 break;
2773                                 case SVX_NUM_CIRCLE_NUMBER :
2774                                 {
2775                                     nMappedNumType = 0x120001;   // Double byte circle numbers.
2776                                 }
2777                                 break;
2778                                 case SVX_NUM_NUMBER_UPPER_ZH_TW :
2779                                 {
2780                                     if ( sSuffix.Len() )
2781                                         nMappedNumType = 0x160001;   // Traditional Chinese with single-byte period.
2782                                     else
2783                                         nMappedNumType = 0x150001;   // Traditional Chinese.
2784                                 }
2785                                 break;
2786                                 case SVX_NUM_NUMBER_LOWER_ZH :
2787                                 {
2788                                     if ( sSuffix == String( sal_Unicode(0xff0e)) )
2789                                         nMappedNumType = 0x260001;   // Japanese with double-byte period.
2790                                     else if ( sSuffix.Len() )
2791                                         nMappedNumType = 0x1B0001;   // Japanese/Korean with single-byte period.
2792                                     else
2793                                         nMappedNumType = 0x1A0001;   // Japanese/Korean.
2794                                 }
2795                                 break;
2796                                 case SVX_NUM_FULL_WIDTH_ARABIC :
2797                                 {
2798                                     if ( sSuffix.Len() )
2799                                         nMappedNumType = 0x1D0001;   // Double-byte Arabic numbers with double-byte period.
2800                                     else
2801                                         nMappedNumType = 0x1C0001;   // Double-byte Arabic numbers.
2802                                 }
2803                                 break;
2804                                 default:
2805                                     break;
2806                             }
2807                         }
2808                         nParaFlags |= 0x2f;
2809                         nBulletFlags |= 6;
2810                         if ( mbIsBullet && bNumberingIsNumber )
2811                             nBulletFlags |= 1;
2812                     }
2813         default: break;
2814                 }
2815             }
2816         }
2817     }
2818     nBulletOfs = nTextOfs + nBulletOfs;
2819     if ( nBulletOfs < 0 )
2820         nBulletOfs = 0;
2821 }
2822 
ImplGetParagraphValues(PPTExBulletProvider & rBuProv,sal_Bool bGetPropStateValue)2823 void ParagraphObj::ImplGetParagraphValues( PPTExBulletProvider& rBuProv, sal_Bool bGetPropStateValue )
2824 {
2825     static String sNumberingLevel   ( RTL_CONSTASCII_USTRINGPARAM( "NumberingLevel" ) );
2826 
2827     ::com::sun::star::uno::Any aAny;
2828     if ( GetPropertyValue( aAny, mXPropSet, sNumberingLevel, sal_True ) )
2829     {
2830         if ( bGetPropStateValue )
2831             meBullet = GetPropertyState( mXPropSet, sNumberingLevel );
2832         nDepth = *( (sal_Int16*)aAny.getValue() );
2833 
2834         if ( nDepth < 0 )
2835         {
2836             mbIsBullet = sal_False;
2837             nDepth = 0;
2838         }
2839         else
2840         {
2841             if ( nDepth > 4 )
2842                 nDepth = 4;
2843             mbIsBullet = sal_True;
2844         }
2845     }
2846     else
2847     {
2848         nDepth = 0;
2849         mbIsBullet = sal_False;
2850     }
2851     ImplGetNumberingLevel( rBuProv, nDepth, mbIsBullet, bGetPropStateValue );
2852 
2853     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaTabStops" ) ), bGetPropStateValue ) )
2854         maTabStop = *( ::com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop>*)mAny.getValue();
2855     sal_Int16 eTextAdjust( ::com::sun::star::style::ParagraphAdjust_LEFT );
2856     if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "ParaAdjust" ) ), bGetPropStateValue ) )
2857         aAny >>= eTextAdjust;
2858     switch ( (::com::sun::star::style::ParagraphAdjust)eTextAdjust )
2859     {
2860         case ::com::sun::star::style::ParagraphAdjust_CENTER :
2861             mnTextAdjust = 1;
2862         break;
2863         case ::com::sun::star::style::ParagraphAdjust_RIGHT :
2864             mnTextAdjust = 2;
2865         break;
2866         case ::com::sun::star::style::ParagraphAdjust_BLOCK :
2867             mnTextAdjust = 3;
2868         break;
2869         default :
2870         case ::com::sun::star::style::ParagraphAdjust_LEFT :
2871             mnTextAdjust = 0;
2872         break;
2873     }
2874     meTextAdjust = ePropState;
2875 
2876     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaLineSpacing" ) ), bGetPropStateValue ) )
2877     {
2878         ::com::sun::star::style::LineSpacing aLineSpacing
2879             = *( (::com::sun::star::style::LineSpacing*)mAny.getValue() );
2880         switch ( aLineSpacing.Mode )
2881         {
2882             case ::com::sun::star::style::LineSpacingMode::MINIMUM :
2883             case ::com::sun::star::style::LineSpacingMode::LEADING :
2884             case ::com::sun::star::style::LineSpacingMode::FIX :
2885                 mnLineSpacing = (sal_Int16)(-( aLineSpacing.Height ) );
2886             break;
2887 
2888             case ::com::sun::star::style::LineSpacingMode::PROP :
2889             default:
2890                 mnLineSpacing = (sal_Int16)( aLineSpacing.Height );
2891             break;
2892         }
2893     }
2894     meLineSpacing = ePropState;
2895 
2896     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaBottomMargin" ) ), bGetPropStateValue ) )
2897     {
2898         double fSpacing = *( (sal_uInt32*)mAny.getValue() ) + ( 2540.0 / 576.0 ) - 1;
2899         mnLineSpacingBottom = (sal_Int16)(-( fSpacing * 576.0 / 2540.0 ) );
2900     }
2901     meLineSpacingBottom = ePropState;
2902 
2903     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaTopMargin" ) ), bGetPropStateValue ) )
2904     {
2905         double fSpacing = *( (sal_uInt32*)mAny.getValue() ) + ( 2540.0 / 576.0 ) - 1;
2906         mnLineSpacingTop = (sal_Int16)(-( fSpacing * 576.0 / 2540.0 ) );
2907     }
2908     meLineSpacingTop = ePropState;
2909 
2910     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaIsForbiddenRules" ) ), bGetPropStateValue ) )
2911         mAny >>= mbForbiddenRules;
2912     meForbiddenRules = ePropState;
2913 
2914     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaIsHangingPunctuation" ) ), bGetPropStateValue ) )
2915         mAny >>= mbParagraphPunctation;
2916     meParagraphPunctation = ePropState;
2917 
2918     mnBiDi = 0;
2919     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ), bGetPropStateValue ) )
2920     {
2921         sal_Int16 nWritingMode;
2922         mAny >>= nWritingMode;
2923 
2924         SvxFrameDirection eWritingMode( (SvxFrameDirection)nWritingMode );
2925         if ( ( eWritingMode == FRMDIR_HORI_RIGHT_TOP )
2926             || ( eWritingMode == FRMDIR_VERT_TOP_RIGHT ) )
2927         {
2928             mnBiDi = 1;
2929         }
2930     }
2931     meBiDi = ePropState;
2932 }
2933 
ImplConstruct(const ParagraphObj & rParagraphObj)2934 void ParagraphObj::ImplConstruct( const ParagraphObj& rParagraphObj )
2935 {
2936     mnTextSize = rParagraphObj.mnTextSize;
2937     mnTextAdjust = rParagraphObj.mnTextAdjust;
2938     mnLineSpacing = rParagraphObj.mnLineSpacing;
2939     mnLineSpacingTop = rParagraphObj.mnLineSpacingTop;
2940     mnLineSpacingBottom = rParagraphObj.mnLineSpacingBottom;
2941     mbFirstParagraph = rParagraphObj.mbFirstParagraph;
2942     mbLastParagraph = rParagraphObj.mbLastParagraph;
2943     mbParagraphPunctation = rParagraphObj.mbParagraphPunctation;
2944     mbForbiddenRules = rParagraphObj.mbForbiddenRules;
2945     mnBiDi = rParagraphObj.mnBiDi;
2946 
2947     ParagraphObj& rOther = const_cast<ParagraphObj&>(rParagraphObj);
2948     for ( const void* pPtr = rOther.First(); pPtr; pPtr = rOther.Next() )
2949         Insert( new PortionObj( *(const PortionObj*)pPtr ), LIST_APPEND );
2950 
2951     maTabStop = rParagraphObj.maTabStop;
2952     bExtendedParameters = rParagraphObj.bExtendedParameters;
2953     nParaFlags = rParagraphObj.nParaFlags;
2954     nBulletFlags = rParagraphObj.nBulletFlags;
2955     sPrefix = rParagraphObj.sPrefix;
2956     sSuffix = rParagraphObj.sSuffix;
2957     sGraphicUrl = rParagraphObj.sGraphicUrl;            // String auf eine Graphic
2958     aBuGraSize = rParagraphObj.aBuGraSize;
2959     nNumberingType = rParagraphObj.nNumberingType;      // in wirlichkeit ist dies ein SvxEnum
2960     nHorzAdjust = rParagraphObj.nHorzAdjust;
2961     nBulletColor = rParagraphObj.nBulletColor;
2962     nBulletOfs = rParagraphObj.nBulletOfs;
2963     nStartWith = rParagraphObj.nStartWith;              // Start der nummerierung
2964     nTextOfs = rParagraphObj.nTextOfs;
2965     nBulletRealSize = rParagraphObj.nBulletRealSize;    // GroessenVerhaeltnis in Proz
2966     nDepth = rParagraphObj.nDepth;                      // aktuelle tiefe
2967     cBulletId = rParagraphObj.cBulletId;                // wenn Numbering Type == CharSpecial
2968     aFontDesc = rParagraphObj.aFontDesc;
2969 
2970     bExtendedBulletsUsed = rParagraphObj.bExtendedBulletsUsed;
2971     nBulletId = rParagraphObj.nBulletId;
2972 }
2973 
ImplCalculateTextPositions(sal_uInt32 nCurrentTextPosition)2974 sal_uInt32 ParagraphObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition )
2975 {
2976     mnTextSize = 0;
2977     for ( void* pPtr = First(); pPtr; pPtr = Next() )
2978         mnTextSize += ((PortionObj*)pPtr)->ImplCalculateTextPositions( nCurrentTextPosition + mnTextSize );
2979     return mnTextSize;
2980 }
2981 
operator =(const ParagraphObj & rParagraphObj)2982 ParagraphObj& ParagraphObj::operator=( const ParagraphObj& rParagraphObj )
2983 {
2984     if ( this != &rParagraphObj )
2985     {
2986         ImplClear();
2987         ImplConstruct( rParagraphObj );
2988     }
2989     return *this;
2990 }
2991 
2992 //  -----------------------------------------------------------------------
2993 
ImplTextObj(int nInstance)2994 ImplTextObj::ImplTextObj( int nInstance )
2995 {
2996     mnRefCount = 1;
2997     mnTextSize = 0;
2998     mnInstance = nInstance;
2999     mpList = new List;
3000     mbHasExtendedBullets = sal_False;
3001     mbFixedCellHeightUsed = sal_False;
3002 }
3003 
~ImplTextObj()3004 ImplTextObj::~ImplTextObj()
3005 {
3006     for ( ParagraphObj* pPtr = (ParagraphObj*)mpList->First(); pPtr; pPtr = (ParagraphObj*)mpList->Next() )
3007         delete pPtr;
3008     delete mpList;
3009 }
3010 
TextObj(::com::sun::star::uno::Reference<::com::sun::star::text::XSimpleText> & rXTextRef,int nInstance,FontCollection & rFontCollection,PPTExBulletProvider & rProv)3011 TextObj::TextObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XSimpleText > & rXTextRef,
3012             int nInstance, FontCollection& rFontCollection, PPTExBulletProvider& rProv )
3013 {
3014     mpImplTextObj = new ImplTextObj( nInstance );
3015 
3016     ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumerationAccess >
3017         aXTextParagraphEA( rXTextRef, ::com::sun::star::uno::UNO_QUERY );
3018 
3019     if ( aXTextParagraphEA.is()  )
3020     {
3021         ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration >
3022             aXTextParagraphE( aXTextParagraphEA->createEnumeration() );
3023         if ( aXTextParagraphE.is() )
3024         {
3025             ParaFlags aParaFlags;
3026             while ( aXTextParagraphE->hasMoreElements() )
3027             {
3028                 ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > aXParagraph;
3029                 ::com::sun::star::uno::Any aAny( aXTextParagraphE->nextElement() );
3030                 if ( aAny >>= aXParagraph )
3031                 {
3032                     if ( !aXTextParagraphE->hasMoreElements() )
3033                         aParaFlags.bLastParagraph = sal_True;
3034                     ParagraphObj* pPara = new ParagraphObj( aXParagraph, aParaFlags, rFontCollection, rProv );
3035                     mpImplTextObj->mbHasExtendedBullets |= pPara->bExtendedBulletsUsed;
3036                     mpImplTextObj->mpList->Insert( pPara, LIST_APPEND );
3037                     aParaFlags.bFirstParagraph = sal_False;
3038                 }
3039             }
3040         }
3041     }
3042     ImplCalculateTextPositions();
3043 }
3044 
TextObj(const TextObj & rTextObj)3045 TextObj::TextObj( const TextObj& rTextObj )
3046 {
3047     mpImplTextObj = rTextObj.mpImplTextObj;
3048     mpImplTextObj->mnRefCount++;
3049 }
3050 
~TextObj()3051 TextObj::~TextObj()
3052 {
3053     if ( ! ( --mpImplTextObj->mnRefCount ) )
3054         delete mpImplTextObj;
3055 }
3056 
Write(SvStream * pStrm)3057 void TextObj::Write( SvStream* pStrm )
3058 {
3059     sal_uInt32 nSize, nPos = pStrm->Tell();
3060     *pStrm << (sal_uInt32)( EPP_TextCharsAtom << 16 ) << (sal_uInt32)0;
3061     for ( void* pPtr = First(); pPtr; pPtr = Next() )
3062         ((ParagraphObj*)pPtr)->Write( pStrm );
3063     nSize = pStrm->Tell() - nPos;
3064     pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) );
3065     *pStrm << (sal_uInt32)( nSize - 8 );
3066     pStrm->SeekRel( nSize - 8 );
3067 }
3068 
ImplCalculateTextPositions()3069 void TextObj::ImplCalculateTextPositions()
3070 {
3071     mpImplTextObj->mnTextSize = 0;
3072     for ( void* pPtr = First(); pPtr; pPtr = Next() )
3073         mpImplTextObj->mnTextSize += ((ParagraphObj*)pPtr)->ImplCalculateTextPositions( mpImplTextObj->mnTextSize );
3074 }
3075 
operator =(TextObj & rTextObj)3076 TextObj& TextObj::operator=( TextObj& rTextObj )
3077 {
3078     if ( this != &rTextObj )
3079     {
3080         if ( ! ( --mpImplTextObj->mnRefCount ) )
3081             delete mpImplTextObj;
3082         mpImplTextObj = rTextObj.mpImplTextObj;
3083         mpImplTextObj->mnRefCount++;
3084     }
3085     return *this;
3086 }
3087 
WriteTextSpecInfo(SvStream * pStrm)3088 void TextObj::WriteTextSpecInfo( SvStream* pStrm )
3089 {
3090     sal_uInt32 nCharactersLeft( Count() );
3091     if ( nCharactersLeft >= 1 )
3092     {
3093         EscherExAtom aAnimationInfoAtom( *pStrm, EPP_TextSpecInfoAtom, 0, 0 );
3094         for ( ParagraphObj* pPtr = static_cast < ParagraphObj * >( First() ); nCharactersLeft && pPtr; pPtr = static_cast< ParagraphObj* >( Next() ) )
3095         {
3096             for ( PortionObj* pPortion = static_cast< PortionObj* >( pPtr->First() ); nCharactersLeft && pPortion; pPortion = static_cast< PortionObj* >( pPtr->Next() ) )
3097             {
3098                 sal_Int32 nPortionSize = pPortion->mnTextSize >= nCharactersLeft ? nCharactersLeft : pPortion->mnTextSize;
3099                 sal_Int32 nFlags = 7;
3100                 nCharactersLeft -= nPortionSize;
3101                 *pStrm  << static_cast< sal_uInt32 >( nPortionSize )
3102                         << nFlags
3103                         << static_cast< sal_Int16 >( 1 )    // spellinfo -> needs rechecking
3104                         << static_cast< sal_Int16 >( MsLangId::convertLocaleToLanguageWithFallback( pPortion->meCharLocale ) )
3105                         << static_cast< sal_Int16 >( 0 );   // alt language
3106             }
3107         }
3108         if ( nCharactersLeft )
3109             *pStrm << nCharactersLeft << static_cast< sal_Int32 >( 1 ) << static_cast< sal_Int16 >( 1 );
3110 
3111     }
3112 }
3113 
3114 //  -----------------------------------------------------------------------
3115 
ImplAdjustFirstLineLineSpacing(TextObj & rTextObj,EscherPropertyContainer & rPropOpt)3116 void PPTWriter::ImplAdjustFirstLineLineSpacing( TextObj& rTextObj, EscherPropertyContainer& rPropOpt )
3117 {
3118     if ( !mbFontIndependentLineSpacing )
3119     {
3120         ParagraphObj* pPara = rTextObj.First();
3121         if ( pPara )
3122         {
3123             PortionObj* pPortion = (PortionObj*)pPara->First();
3124             if ( pPortion )
3125             {
3126                 sal_Int16 nLineSpacing = pPara->mnLineSpacing;
3127                 const FontCollectionEntry* pDesc = maFontCollection.GetById( pPortion->mnFont );
3128                 if ( pDesc )
3129                      nLineSpacing = (sal_Int16)( (double)nLineSpacing * pDesc->Scaling + 0.5 );
3130 
3131                 if ( ( nLineSpacing > 0 ) && ( nLineSpacing < 100 ) )
3132                 {
3133     /*
3134                     if ( rxText.is() )
3135                     {
3136                         ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape( rxText, ::com::sun::star::uno::UNO_QUERY );
3137                         if ( xShape.is() )
3138                         {
3139                             SdrObject* pObj = GetSdrObjectFromXShape( mXShape );
3140                             if ( pObj )
3141                             {
3142                                 const OutlinerParaObject* pParaObj = pObj->GetOutlinerParaObject();
3143                                 if ( pParaObj )
3144                                 {
3145                                     SdrModel* pModel = pObj->GetModel();
3146                                     if ( pModel )
3147                                     {
3148                                         Outliner aOutliner( &pModel->GetItemPool(), pParaObj->GetOutlinerMode() );
3149                                         aOutliner.SetText( *pParaObj );
3150                                         sal_uLong nTextHeight = aOutliner.GetLineHeight( 0, 0 );
3151                                         if ( nTextHeight )
3152                                         {
3153                                         }
3154                                     }
3155                                 }
3156                             }
3157                         }
3158                     }
3159     */
3160                     double fCharHeight = pPortion->mnCharHeight;
3161                     fCharHeight *= 2540 / 72;
3162                     fCharHeight *= 100 - nLineSpacing;
3163                     fCharHeight /= 100;
3164 
3165                     sal_uInt32 nUpperDistance = 0;
3166                     rPropOpt.GetOpt( ESCHER_Prop_dyTextTop, nUpperDistance );
3167                     nUpperDistance += static_cast< sal_uInt32 >( fCharHeight * 360.0 );
3168                     rPropOpt.AddOpt( ESCHER_Prop_dyTextTop, nUpperDistance );
3169                 }
3170             }
3171         }
3172     }
3173 }
3174 
3175 //  -----------------------------------------------------------------------
3176 
ImplWriteTextStyleAtom(SvStream & rOut,int nTextInstance,sal_uInt32 nAtomInstance,TextRuleEntry * pTextRule,SvStream & rExtBuStr,EscherPropertyContainer * pPropOpt)3177 void PPTWriter::ImplWriteTextStyleAtom( SvStream& rOut, int nTextInstance, sal_uInt32 nAtomInstance,
3178     TextRuleEntry* pTextRule, SvStream& rExtBuStr, EscherPropertyContainer* pPropOpt )
3179 {
3180     PPTExParaSheet& rParaSheet = mpStyleSheet->GetParaSheet( nTextInstance );
3181 
3182     rOut << (sal_uInt32)( ( EPP_TextHeaderAtom << 16 ) | ( nAtomInstance << 4 ) ) << (sal_uInt32)4
3183          << nTextInstance;
3184 
3185     if ( mbEmptyPresObj )
3186         mnTextSize = 0;
3187     if ( !mbEmptyPresObj )
3188     {
3189         ParagraphObj* pPara;
3190         TextObj aTextObj( mXText, nTextInstance, maFontCollection, (PPTExBulletProvider&)*this );
3191 
3192         // leaving out EPP_TextCharsAtom w/o text - still write out
3193         // attribute info though
3194         if ( mnTextSize )
3195             aTextObj.Write( &rOut );
3196 
3197         if ( pPropOpt )
3198             ImplAdjustFirstLineLineSpacing( aTextObj, *pPropOpt );
3199 
3200         sal_uInt32 nSize, nPos = rOut.Tell();
3201 
3202         rOut << (sal_uInt32)( EPP_StyleTextPropAtom << 16 ) << (sal_uInt32)0;
3203         ImplWriteParagraphs( rOut, aTextObj );
3204         ImplWritePortions( rOut, aTextObj );
3205         nSize = rOut.Tell() - nPos;
3206         rOut.SeekRel( - ( (sal_Int32)nSize - 4 ) );
3207         rOut << (sal_uInt32)( nSize - 8 );
3208         rOut.SeekRel( nSize - 8 );
3209 
3210         for ( pPara = aTextObj.First(); pPara; pPara = aTextObj.Next() )
3211         {
3212             for ( PortionObj* pPortion = (PortionObj*)pPara->First(); pPortion; pPortion = (PortionObj*)pPara->Next() )
3213             {
3214                 if ( pPortion->mpFieldEntry )
3215                 {
3216                     const FieldEntry* pFieldEntry = pPortion->mpFieldEntry;
3217 
3218                     switch ( pFieldEntry->nFieldType >> 28 )
3219                     {
3220                         case 1 :
3221                         case 2 :
3222                         {
3223                             rOut << (sal_uInt32)( EPP_DateTimeMCAtom << 16 ) << (sal_uInt32)8
3224                                  << (sal_uInt32)( pFieldEntry->nFieldStartPos )         // TxtOffset auf TxtField;
3225                                  << (sal_uInt8)( pFieldEntry->nFieldType & 0xff )       // Type
3226                                  << (sal_uInt8)0 << (sal_uInt16)0;                      // PadBytes
3227                         }
3228                         break;
3229                         case 3 :
3230                         {
3231                             rOut << (sal_uInt32)( EPP_SlideNumberMCAtom << 16 ) << (sal_uInt32 ) 4
3232                                  << (sal_uInt32)( pFieldEntry->nFieldStartPos );
3233                         }
3234                         break;
3235                         case 4 :
3236                         {
3237                             sal_uInt32 nPageIndex = 0;
3238                             String aPageUrl;
3239                             String aEmpty;
3240                             String aFile( pFieldEntry->aFieldUrl );
3241                             INetURLObject aUrl( pFieldEntry->aFieldUrl );
3242                             if ( INET_PROT_FILE == aUrl.GetProtocol() )
3243                                 aFile = aUrl.PathToFileName();
3244                             else if ( pFieldEntry->aFieldUrl.GetChar( 0 ) == '#' )
3245                             {
3246                                 String aPage( INetURLObject::decode( pFieldEntry->aFieldUrl, '%', INetURLObject::DECODE_WITH_CHARSET ) );
3247                                 aPage.Erase( 0, 1 );
3248                                 for ( String* pStr = (String*)maSlideNameList.First(); pStr; pStr = (String*)maSlideNameList.Next(), nPageIndex++ )
3249                                 {
3250                                     if ( *pStr == aPage )
3251                                     {
3252                                         aPageUrl = UniString::CreateFromInt32( 256 + nPageIndex );
3253                                         aPageUrl.Append( String( RTL_CONSTASCII_USTRINGPARAM( "," ) ) );
3254                                         aPageUrl.Append( String::CreateFromInt32( nPageIndex + 1 ) );
3255                                         aPageUrl.Append( String( RTL_CONSTASCII_USTRINGPARAM( ",Slide " ) ) );
3256                                         aPageUrl.Append( String::CreateFromInt32( nPageIndex + 1 ) );
3257                                     }
3258                                 }
3259                             }
3260                             sal_uInt32 nHyperId;
3261                             if ( aPageUrl.Len() )
3262                                 nHyperId = ImplInsertBookmarkURL( aPageUrl, 1 | ( nPageIndex << 8 ) | ( 1 << 31 ), pFieldEntry->aRepresentation, aEmpty, aEmpty, aPageUrl );
3263                             else
3264                                 nHyperId = ImplInsertBookmarkURL( pFieldEntry->aFieldUrl, 2 | ( nHyperId << 8 ), aFile, pFieldEntry->aFieldUrl, aEmpty, aEmpty );
3265 
3266                             rOut << (sal_uInt32)( ( EPP_InteractiveInfo << 16 ) | 0xf ) << (sal_uInt32)24
3267                                  << (sal_uInt32)( EPP_InteractiveInfoAtom << 16 ) << (sal_uInt32)16
3268                                  << (sal_uInt32)0                                   // soundref
3269                                  << nHyperId                                        // hyperlink id
3270                                  << (sal_uInt8)4                                    // hyperlink action
3271                                  << (sal_uInt8)0                                    // ole verb
3272                                  << (sal_uInt8)0                                    // jump
3273                                  << (sal_uInt8)0                                    // flags
3274                                  << (sal_uInt8)8                                    // hyperlink type ?
3275                                  << (sal_uInt8)0 << (sal_uInt8)0 << (sal_uInt8)0
3276                                  << (sal_uInt32)( EPP_TxInteractiveInfoAtom << 16 ) << (sal_uInt32)8
3277                                  << (sal_uInt32)( pFieldEntry->nFieldStartPos )
3278                                  << (sal_uInt32)( pFieldEntry->nFieldEndPos );
3279                         }
3280                         break;
3281                         case 5 :
3282                         {
3283                             rOut << (sal_uInt32)( EPP_GenericDateMCAtom << 16 ) << (sal_uInt32)4
3284                                  << (sal_uInt32)( pFieldEntry->nFieldStartPos );
3285                         }
3286                         break;
3287                         case 6 :
3288                         {
3289                             rOut << (sal_uInt32)( EPP_HeaderMCAtom << 16 ) << (sal_uInt32 ) 4
3290                                  << (sal_uInt32)( pFieldEntry->nFieldStartPos );
3291                         }
3292                         break;
3293                         case 7 :
3294                         {
3295                             rOut << (sal_uInt32)( EPP_FooterMCAtom << 16 ) << (sal_uInt32 ) 4
3296                                  << (sal_uInt32)( pFieldEntry->nFieldStartPos );
3297                         }
3298                         break;
3299                         default:
3300                         break;
3301                     }
3302                 }
3303             }
3304         }
3305 
3306         aTextObj.WriteTextSpecInfo( &rOut );
3307 
3308         // Star Office Default TabSizes schreiben ( wenn noetig )
3309         pPara = aTextObj.First();
3310         if ( pPara )
3311         {
3312             sal_uInt32  nParaFlags = 0x1f;
3313             sal_Int16   nDepth, nMask, nNumberingRule[ 10 ];
3314             sal_uInt32  nTextOfs = pPara->nTextOfs;
3315             sal_uInt32  nTabs = pPara->maTabStop.getLength();
3316             const ::com::sun::star::style::TabStop* pTabStop = ( const ::com::sun::star::style::TabStop* )pPara->maTabStop.getConstArray();
3317 
3318             for ( ; pPara; pPara = aTextObj.Next() )
3319             {
3320                 if ( pPara->bExtendedParameters )
3321                 {
3322                     nDepth = pPara->nDepth;
3323                     if ( nDepth < 5 )
3324                     {
3325                         nMask = 1 << nDepth;
3326                         if ( nParaFlags & nMask )
3327                         {
3328                             nParaFlags &=~ nMask;
3329                             if ( ( rParaSheet.maParaLevel[ nDepth ].mnTextOfs != pPara->nTextOfs ) ||
3330                                 ( rParaSheet.maParaLevel[ nDepth ].mnBulletOfs != pPara->nBulletOfs ) )
3331                             {
3332                                 nParaFlags |= nMask << 16;
3333                                 nNumberingRule[ nDepth << 1 ] = pPara->nTextOfs;
3334                                 nNumberingRule[ ( nDepth << 1 ) + 1 ] = (sal_Int16)pPara->nBulletOfs;
3335                             }
3336                         }
3337                     }
3338                 }
3339             }
3340             nParaFlags >>= 16;
3341 
3342             sal_uInt32  nDefaultTabSize = ImplMapSize( ::com::sun::star::awt::Size( 2011, 1 ) ).Width;
3343             sal_uInt32  nDefaultTabs = abs( maRect.GetWidth() ) / nDefaultTabSize;
3344             if ( nTabs )
3345                 nDefaultTabs -= (sal_Int32)( ( ( pTabStop[ nTabs - 1 ].Position / 4.40972 ) + nTextOfs ) / nDefaultTabSize );
3346             if ( (sal_Int32)nDefaultTabs < 0 )
3347                 nDefaultTabs = 0;
3348 
3349             sal_uInt32 nTabCount = nTabs + nDefaultTabs;
3350             sal_uInt32 i, nTextRulerAtomFlags = 0;
3351 
3352             if ( nTabCount )
3353                 nTextRulerAtomFlags |= 4;
3354             if ( nParaFlags )
3355                 nTextRulerAtomFlags |= ( ( nParaFlags << 3 ) | ( nParaFlags << 8 ) );
3356 
3357             if ( nTextRulerAtomFlags )
3358             {
3359                 SvStream* pRuleOut = &rOut;
3360                 if ( pTextRule )
3361                     pRuleOut = pTextRule->pOut = new SvMemoryStream( 0x100, 0x100 );
3362 
3363                 sal_uInt32 nRulePos = pRuleOut->Tell();
3364                 *pRuleOut << (sal_uInt32)( EPP_TextRulerAtom << 16 ) << (sal_uInt32)0;
3365                 *pRuleOut << nTextRulerAtomFlags;
3366                 if ( nTextRulerAtomFlags & 4 )
3367                 {
3368                     *pRuleOut << (sal_uInt16)nTabCount;
3369                     for ( i = 0; i < nTabs; i++ )
3370                     {
3371                         sal_uInt16 nPosition = (sal_uInt16)( ( pTabStop[ i ].Position / 4.40972 ) + nTextOfs );
3372                         sal_uInt16 nType;
3373                         switch ( pTabStop[ i ].Alignment )
3374                         {
3375                             case ::com::sun::star::style::TabAlign_DECIMAL :    nType = 3; break;
3376                             case ::com::sun::star::style::TabAlign_RIGHT :      nType = 2; break;
3377                             case ::com::sun::star::style::TabAlign_CENTER :     nType = 1; break;
3378 
3379                             case ::com::sun::star::style::TabAlign_LEFT :
3380                             default:                                            nType = 0;
3381                         };
3382                         *pRuleOut << nPosition
3383                                   << nType;
3384                     }
3385 
3386                     sal_uInt32 nWidth = 1;
3387                     if ( nTabs )
3388                         nWidth += (sal_Int32)( ( ( pTabStop[ nTabs - 1 ].Position / 4.40972 + nTextOfs ) / nDefaultTabSize ) );
3389                     nWidth *= nDefaultTabSize;
3390                     for ( i = 0; i < nDefaultTabs; i++, nWidth += nDefaultTabSize )
3391                         *pRuleOut << nWidth;
3392                 }
3393                 for ( i = 0; i < 5; i++ )
3394                 {
3395                     if ( nTextRulerAtomFlags & ( 8 << i ) )
3396                         *pRuleOut << nNumberingRule[ i << 1 ];
3397                     if ( nTextRulerAtomFlags & ( 256 << i ) )
3398                         *pRuleOut << nNumberingRule[ ( i << 1 ) + 1 ];
3399                 }
3400                 sal_uInt32 nBufSize = pRuleOut->Tell() - nRulePos;
3401                 pRuleOut->SeekRel( - ( (sal_Int32)nBufSize - 4 ) );
3402                 *pRuleOut << (sal_uInt32)( nBufSize - 8 );
3403                 pRuleOut->SeekRel( nBufSize - 8 );
3404             }
3405         }
3406         if ( aTextObj.HasExtendedBullets() )
3407         {
3408             ParagraphObj* pBulletPara = aTextObj.First();
3409             if ( pBulletPara )
3410             {
3411                 sal_uInt32  nBulletFlags = 0;
3412                 sal_uInt32  nNumberingType = 0, nPos2 = rExtBuStr.Tell();
3413 
3414                 rExtBuStr << (sal_uInt32)( EPP_PST_ExtendedParagraphAtom << 16 ) << (sal_uInt32)0;
3415 
3416                 for ( ; pBulletPara; pBulletPara = aTextObj.Next() )
3417                 {
3418                     nBulletFlags = 0;
3419                     sal_uInt16 nBulletId = pBulletPara->nBulletId;
3420                     if ( pBulletPara->bExtendedBulletsUsed )
3421                     {
3422                         nBulletFlags = 0x800000;
3423                         if ( pBulletPara->nNumberingType != SVX_NUM_BITMAP )
3424                             nBulletFlags = 0x3000000;
3425                     }
3426                     rExtBuStr << (sal_uInt32)nBulletFlags;
3427 
3428                     if ( nBulletFlags & 0x800000 )
3429                         rExtBuStr << nBulletId;
3430                     if ( nBulletFlags & 0x1000000 )
3431                     {
3432                         switch( pBulletPara->nNumberingType )
3433                         {
3434                             case SVX_NUM_NUMBER_NONE :
3435                             case SVX_NUM_CHAR_SPECIAL :
3436                                 nNumberingType = 0;
3437                             break;
3438                             case SVX_NUM_CHARS_UPPER_LETTER :
3439                             case SVX_NUM_CHARS_UPPER_LETTER_N :
3440                             case SVX_NUM_CHARS_LOWER_LETTER :
3441                             case SVX_NUM_CHARS_LOWER_LETTER_N :
3442                             case SVX_NUM_ROMAN_UPPER :
3443                             case SVX_NUM_ROMAN_LOWER :
3444                             case SVX_NUM_ARABIC :
3445                             case SVX_NUM_NUMBER_UPPER_ZH:
3446                             case SVX_NUM_CIRCLE_NUMBER:
3447                             case SVX_NUM_NUMBER_UPPER_ZH_TW:
3448                             case SVX_NUM_NUMBER_LOWER_ZH:
3449                             case SVX_NUM_FULL_WIDTH_ARABIC:
3450                                 nNumberingType = pBulletPara->nMappedNumType;
3451                             break;
3452 
3453     //                      case SVX_NUM_PAGEDESC :
3454                             case SVX_NUM_BITMAP :
3455                                 nNumberingType = 0;
3456                             break;
3457 
3458                         }
3459                         rExtBuStr << (sal_uInt32)nNumberingType;
3460                     }
3461                     if ( nBulletFlags & 0x2000000 )
3462                         rExtBuStr << (sal_uInt16)pBulletPara->nStartWith;
3463                     rExtBuStr << (sal_uInt32)0 << (sal_uInt32)0;
3464                 }
3465                 sal_uInt32 nBulletSize = ( rExtBuStr.Tell() - nPos2 ) - 8;
3466                 rExtBuStr.SeekRel( - ( (sal_Int32)nBulletSize + 4 ) );
3467                 rExtBuStr << nBulletSize;
3468                 rExtBuStr.SeekRel( nBulletSize );
3469             }
3470         }
3471     }
3472 }
3473 
3474 //  -----------------------------------------------------------------------
3475 
ImplWriteObjectEffect(SvStream & rSt,::com::sun::star::presentation::AnimationEffect eAe,::com::sun::star::presentation::AnimationEffect eTe,sal_uInt16 nOrder)3476 void PPTWriter::ImplWriteObjectEffect( SvStream& rSt,
3477     ::com::sun::star::presentation::AnimationEffect eAe,
3478     ::com::sun::star::presentation::AnimationEffect eTe,
3479     sal_uInt16 nOrder )
3480 {
3481     EscherExContainer aAnimationInfo( rSt, EPP_AnimationInfo );
3482     EscherExAtom aAnimationInfoAtom( rSt, EPP_AnimationInfoAtom, 0, 1 );
3483     sal_uInt32  nDimColor = 0x7000000;  // color to use for dimming
3484     sal_uInt32  nFlags = 0x4400;        // set of flags that determine type of build
3485     sal_uInt32  nSoundRef = 0;          // 0 if storage is from clipboard. Otherwise index(ID) in SoundCollection list.
3486     sal_uInt32  nDelayTime = 0;         // delay before playing object
3487     sal_uInt16  nSlideCount = 1;        // number of slides to play object
3488     sal_uInt8   nBuildType = 1;         // type of build
3489     sal_uInt8   nFlyMethod = 0;         // animation effect( fly, zoom, appear, etc )
3490     sal_uInt8   nFlyDirection = 0;      // Animation direction( left, right, up, down, etc )
3491     sal_uInt8   nAfterEffect = 0;       // what to do after build
3492     sal_uInt8   nSubEffect = 0;         // build by word or letter
3493     sal_uInt8   nOleVerb = 0;           // Determines object's class (sound, video, other)
3494 
3495     if ( eAe == ::com::sun::star::presentation::AnimationEffect_NONE )
3496     {
3497         nBuildType = 0;
3498         eAe = eTe;
3499     }
3500     switch ( eAe )
3501     {
3502         case ::com::sun::star::presentation::AnimationEffect_NONE :
3503         break;
3504         case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LEFT :
3505         {
3506             nFlyDirection = 2;
3507             nFlyMethod = 10;
3508         }
3509         break;
3510         case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_TOP :
3511         {
3512             nFlyDirection = 3;
3513             nFlyMethod = 10;
3514         }
3515         break;
3516         case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_RIGHT :
3517         {
3518             nFlyDirection = 0;
3519             nFlyMethod = 10;
3520         }
3521         break;
3522         case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_BOTTOM :
3523         {
3524             nFlyDirection = 1;
3525             nFlyMethod = 10;
3526         }
3527         break;
3528         case ::com::sun::star::presentation::AnimationEffect_FADE_TO_CENTER :
3529         {
3530             nFlyDirection = 1;
3531             nFlyMethod = 11;
3532         }
3533         break;
3534         case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_CENTER :
3535         {
3536             nFlyDirection = 0;
3537             nFlyMethod = 11;
3538         }
3539         break;
3540         case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LEFT :
3541         {
3542             nFlyDirection = 0;
3543             nFlyMethod = 12;
3544         }
3545         break;
3546         case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_TOP :
3547         {
3548             nFlyDirection = 1;
3549             nFlyMethod = 12;
3550         }
3551         break;
3552         case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_RIGHT :
3553         {
3554             nFlyDirection = 2;
3555             nFlyMethod = 12;
3556         }
3557         break;
3558         case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_BOTTOM :
3559         {
3560             nFlyDirection = 3;
3561             nFlyMethod = 12;
3562         }
3563         break;
3564         case ::com::sun::star::presentation::AnimationEffect_VERTICAL_STRIPES :
3565         {
3566             nFlyDirection = 0;
3567             nFlyMethod = 2;
3568         }
3569         break;
3570         case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_STRIPES :
3571         {
3572             nFlyDirection = 1;
3573             nFlyMethod = 2;
3574         }
3575         break;
3576         case ::com::sun::star::presentation::AnimationEffect_CLOCKWISE :
3577         {
3578             nFlyDirection = 1;
3579             nFlyMethod = 3;
3580         }
3581         break;
3582         case ::com::sun::star::presentation::AnimationEffect_COUNTERCLOCKWISE :
3583         {
3584             nFlyDirection = 0;
3585             nFlyMethod = 3;
3586         }
3587         break;
3588         case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_UPPERLEFT :
3589         {
3590             nFlyDirection = 7;
3591             nFlyMethod = 9;
3592         }
3593         break;
3594         case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_UPPERRIGHT :
3595         {
3596             nFlyDirection = 6;
3597             nFlyMethod = 9;
3598         }
3599         break;
3600         case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LOWERLEFT :
3601         {
3602             nFlyDirection = 5;
3603             nFlyMethod = 9;
3604         }
3605         break;
3606         case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LOWERRIGHT :
3607         {
3608             nFlyDirection = 4;
3609             nFlyMethod = 9;
3610         }
3611         break;
3612         case ::com::sun::star::presentation::AnimationEffect_CLOSE_VERTICAL :
3613         {
3614             nFlyDirection = 1;
3615             nFlyMethod = 13;
3616         }
3617         break;
3618         case ::com::sun::star::presentation::AnimationEffect_CLOSE_HORIZONTAL :
3619         {
3620             nFlyDirection = 3;
3621             nFlyMethod = 13;
3622         }
3623         break;
3624         case ::com::sun::star::presentation::AnimationEffect_OPEN_VERTICAL :
3625         {
3626             nFlyDirection = 0;
3627             nFlyMethod = 13;
3628         }
3629         break;
3630         case ::com::sun::star::presentation::AnimationEffect_OPEN_HORIZONTAL :
3631         {
3632             nFlyDirection = 2;
3633             nFlyMethod = 13;
3634         }
3635         break;
3636         case ::com::sun::star::presentation::AnimationEffect_PATH :
3637         {
3638             nFlyDirection = 28;
3639             nFlyMethod = 12;
3640         }
3641         break;
3642         case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_LEFT :
3643         {
3644             nFlyDirection = 0;
3645             nFlyMethod = 1;
3646         }
3647         break;
3648         case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_TOP :
3649         {
3650             nFlyDirection = 0;
3651             nFlyMethod = 1;
3652         }
3653         break;
3654         case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_RIGHT :
3655         {
3656             nFlyDirection = 0;
3657             nFlyMethod = 1;
3658         }
3659         break;
3660         case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_BOTTOM :
3661         {
3662             nFlyDirection = 0;
3663             nFlyMethod = 1;
3664         }
3665         break;
3666         case ::com::sun::star::presentation::AnimationEffect_SPIRALIN_LEFT :
3667         case ::com::sun::star::presentation::AnimationEffect_SPIRALIN_RIGHT :
3668         case ::com::sun::star::presentation::AnimationEffect_SPIRALOUT_LEFT :
3669         case ::com::sun::star::presentation::AnimationEffect_SPIRALOUT_RIGHT :
3670         {
3671             nFlyDirection = 0x1c;
3672             nFlyMethod = 0xc;
3673         }
3674         break;
3675         case ::com::sun::star::presentation::AnimationEffect_DISSOLVE :
3676         {
3677             nFlyDirection = 0;
3678             nFlyMethod = 5;
3679         }
3680         break;
3681         case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_LEFT :
3682         {
3683             nFlyDirection = 2;
3684             nFlyMethod = 10;
3685         }
3686         break;
3687         case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_TOP :
3688         {
3689             nFlyDirection = 3;
3690             nFlyMethod = 10;
3691         }
3692         break;
3693         case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_RIGHT :
3694         {
3695             nFlyDirection = 0;
3696             nFlyMethod = 10;
3697         }
3698         break;
3699         case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_BOTTOM :
3700         {
3701             nFlyDirection = 1;
3702             nFlyMethod = 10;
3703         }
3704         break;
3705         case ::com::sun::star::presentation::AnimationEffect_RANDOM :
3706         {
3707             nFlyDirection = 0;
3708             nFlyMethod = 1;
3709         }
3710         break;
3711         case ::com::sun::star::presentation::AnimationEffect_VERTICAL_LINES :
3712         {
3713             nFlyDirection = 1;
3714             nFlyMethod = 8;
3715         }
3716         break;
3717         case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_LINES :
3718         {
3719             nFlyDirection = 0;
3720             nFlyMethod = 8;
3721         }
3722         break;
3723         case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_LEFT :
3724         {
3725             nFlyDirection = 2;
3726             nFlyMethod = 10;
3727         }
3728         break;
3729         case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_TOP :
3730         {
3731             nFlyDirection = 3;
3732             nFlyMethod = 10;
3733         }
3734         break;
3735         case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_RIGHT :
3736         {
3737             nFlyDirection = 0;
3738             nFlyMethod = 10;
3739         }
3740         break;
3741         case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_BOTTOM :
3742         {
3743             nFlyDirection = 1;
3744             nFlyMethod = 10;
3745         }
3746         break;
3747         case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_UPPERLEFT :
3748         {
3749             nFlyDirection = 7;
3750             nFlyMethod = 9;
3751         }
3752         break;
3753         case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_UPPERRIGHT :
3754         {
3755             nFlyDirection = 6;
3756             nFlyMethod = 9;
3757         }
3758         break;
3759         case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_LOWERLEFT :
3760         {
3761             nFlyDirection = 5;
3762             nFlyMethod = 9;
3763         }
3764         break;
3765         case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_LOWERRIGHT :
3766         {
3767             nFlyDirection = 4;
3768             nFlyMethod = 9;
3769         }
3770         break;
3771         case ::com::sun::star::presentation::AnimationEffect_APPEAR :
3772         break;
3773         case ::com::sun::star::presentation::AnimationEffect_HIDE :
3774         {
3775             nFlyDirection = 0;
3776             nFlyMethod = 1;
3777         }
3778         break;
3779         case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_UPPERLEFT :
3780         {
3781             nFlyDirection = 4;
3782             nFlyMethod = 12;
3783         }
3784         break;
3785         case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_UPPERRIGHT :
3786         {
3787             nFlyDirection = 5;
3788             nFlyMethod = 12;
3789         }
3790         break;
3791         case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LOWERRIGHT :
3792         {
3793             nFlyDirection = 7;
3794             nFlyMethod = 12;
3795         }
3796         break;
3797         case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LOWERLEFT :
3798         {
3799             nFlyDirection = 6;
3800             nFlyMethod = 12;
3801         }
3802         break;
3803         case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_UPPERLEFT :
3804         case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_UPPERRIGHT :
3805         case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_LOWERRIGHT :
3806         case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_LOWERLEFT :
3807             nAfterEffect |= 2;
3808         break;
3809         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_LEFT :
3810         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_UPPERLEFT :
3811         {
3812             nFlyDirection = 8;
3813             nFlyMethod = 12;
3814         }
3815         break;
3816         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_TOP :
3817         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_UPPERRIGHT :
3818         {
3819             nFlyDirection = 11;
3820             nFlyMethod = 12;
3821         }
3822         break;
3823         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_RIGHT :
3824         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_LOWERRIGHT :
3825         {
3826             nFlyDirection = 10;
3827             nFlyMethod = 12;
3828         }
3829         break;
3830         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_BOTTOM :
3831         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_LOWERLEFT :
3832         {
3833             nFlyDirection = 9;
3834             nFlyMethod = 12;
3835         }
3836         break;
3837         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_LEFT :
3838         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_UPPERLEFT :
3839         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_TOP :
3840         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_UPPERRIGHT :
3841         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_RIGHT :
3842         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_LOWERRIGHT :
3843         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_BOTTOM :
3844         case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_LOWERLEFT :
3845             nAfterEffect |= 2;
3846         break;
3847         case ::com::sun::star::presentation::AnimationEffect_VERTICAL_CHECKERBOARD :
3848         {
3849             nFlyDirection = 1;
3850             nFlyMethod = 3;
3851         }
3852         break;
3853         case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_CHECKERBOARD :
3854         {
3855             nFlyDirection = 0;
3856             nFlyMethod = 3;
3857         }
3858         break;
3859         case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_ROTATE :
3860         case ::com::sun::star::presentation::AnimationEffect_VERTICAL_ROTATE :
3861         {
3862             nFlyDirection = 27;
3863             nFlyMethod = 12;
3864         }
3865         break;
3866         case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_STRETCH :
3867         case ::com::sun::star::presentation::AnimationEffect_VERTICAL_STRETCH :
3868         {
3869             nFlyDirection = 22;
3870             nFlyMethod = 12;
3871         }
3872         break;
3873         case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_LEFT :
3874         case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_UPPERLEFT :
3875         {
3876             nFlyDirection = 23;
3877             nFlyMethod = 12;
3878         }
3879         break;
3880         case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_TOP :
3881         case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_UPPERRIGHT :
3882         {
3883             nFlyDirection = 24;
3884             nFlyMethod = 12;
3885         }
3886         break;
3887         case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_RIGHT :
3888         case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_LOWERRIGHT :
3889         {
3890             nFlyDirection = 25;
3891             nFlyMethod = 12;
3892         }
3893         break;
3894         case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_BOTTOM :
3895         case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_LOWERLEFT :
3896         {
3897             nFlyDirection = 26;
3898             nFlyMethod = 12;
3899         }
3900         break;
3901         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN :
3902         {
3903             nFlyDirection = 16;
3904             nFlyMethod = 12;
3905         }
3906         break;
3907         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_SMALL :
3908         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_SPIRAL :
3909         {
3910             nFlyDirection = 17;
3911             nFlyMethod = 12;
3912         }
3913         break;
3914         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT :
3915         {
3916             nFlyDirection = 18;
3917             nFlyMethod = 12;
3918         }
3919         break;
3920         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_SMALL :
3921         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_SPIRAL :
3922         {
3923             nFlyDirection = 19;
3924             nFlyMethod = 12;
3925         }
3926         break;
3927         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_LEFT :
3928         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_UPPERLEFT :
3929         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_TOP :
3930         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_UPPERRIGHT :
3931         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_RIGHT :
3932         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_LOWERRIGHT :
3933         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_BOTTOM :
3934         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_LOWERLEFT :
3935         case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_CENTER :
3936         {
3937             nFlyDirection = 16;
3938             nFlyMethod = 12;
3939         }
3940         break;
3941         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_LEFT :
3942         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_UPPERLEFT :
3943         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_TOP :
3944         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_UPPERRIGHT :
3945         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_RIGHT :
3946         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_LOWERRIGHT :
3947         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_BOTTOM :
3948         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_LOWERLEFT :
3949         case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_CENTER :
3950             nAfterEffect |= 2;
3951             break;
3952         default:
3953             break;
3954     }
3955     if ( mnDiaMode >= 1 )
3956         nFlags |= 4;
3957     if ( eTe != ::com::sun::star::presentation::AnimationEffect_NONE )
3958         nBuildType = 2;
3959     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "SoundOn" ) ) ) )
3960     {
3961         sal_Bool bBool;
3962         mAny >>= bBool;
3963         if ( bBool )
3964         {
3965             if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ) ) )
3966             {
3967                 nSoundRef = maSoundCollection.GetId( *(::rtl::OUString*)mAny.getValue() );
3968                 if ( nSoundRef )
3969                     nFlags |= 0x10;
3970             }
3971         }
3972     }
3973     sal_Bool bDimHide = sal_False;
3974     sal_Bool bDimPrevious = sal_False;
3975     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "DimHide" ) ) ) )
3976         mAny >>= bDimHide;
3977     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "DimPrevious" ) ) ) )
3978         mAny >>= bDimPrevious;
3979     if ( bDimPrevious )
3980         nAfterEffect |= 1;
3981     if ( bDimHide )
3982         nAfterEffect |= 2;
3983     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "DimColor" ) ) ) )
3984         nDimColor = mpPptEscherEx->GetColor( *((sal_uInt32*)mAny.getValue()) ) | 0xfe000000;
3985 
3986     rSt << nDimColor << nFlags << nSoundRef << nDelayTime
3987         << nOrder                                   // order of build ( 1.. )
3988         << nSlideCount << nBuildType << nFlyMethod << nFlyDirection
3989         << nAfterEffect << nSubEffect << nOleVerb
3990         << (sal_uInt16)0;                               // PadWord
3991 }
3992 
3993 //  -----------------------------------------------------------------------
3994 
ImplWriteClickAction(SvStream & rSt,::com::sun::star::presentation::ClickAction eCa,sal_Bool bMediaClickAction)3995 void PPTWriter::ImplWriteClickAction( SvStream& rSt, ::com::sun::star::presentation::ClickAction eCa, sal_Bool bMediaClickAction )
3996 {
3997     sal_uInt32 nSoundRef = 0;   // a reference to a sound in the sound collection, or NULL.
3998     sal_uInt32 nHyperLinkID = 0;// a persistent unique identifier to an external hyperlink object (only valid when action == HyperlinkAction).
3999     sal_uInt8   nAction = 0;     // Action See Action Table
4000     sal_uInt8   nOleVerb = 0;    // OleVerb Only valid when action == OLEAction. OLE verb to use, 0 = first verb, 1 = second verb, etc.
4001     sal_uInt8   nJump = 0;       // Jump See Jump Table
4002     sal_uInt8   nFlags = 0;      // Bit 1: Animated. If 1, then button is animated
4003                             // Bit 2: Stop sound. If 1, then stop current sound when button is pressed.
4004                             // Bit 3: CustomShowReturn. If 1, and this is a jump to custom show, then return to this slide after custom show.
4005     sal_uInt8   nHyperLinkType = 0;// HyperlinkType a value from the LinkTo enum, such as LT_URL (only valid when action == HyperlinkAction).
4006 
4007     String  aFile;
4008 
4009     /*
4010         Action Table:       Action Value
4011         NoAction            0
4012         MacroAction         1
4013         RunProgramAction    2
4014         JumpAction          3
4015         HyperlinkAction     4
4016         OLEAction           5
4017         MediaAction         6
4018         CustomShowAction    7
4019 
4020         Jump Table:     Jump Value
4021         NoJump          0
4022         NextSlide,      1
4023         PreviousSlide,  2
4024         FirstSlide,     3
4025         LastSlide,      4
4026         LastSlideViewed 5
4027         EndShow         6
4028     */
4029 
4030     if ( bMediaClickAction )
4031         nAction = 6;
4032     else switch( eCa )
4033     {
4034         case ::com::sun::star::presentation::ClickAction_STOPPRESENTATION :
4035             nJump += 2;
4036         case ::com::sun::star::presentation::ClickAction_LASTPAGE :
4037             nJump++;
4038         case ::com::sun::star::presentation::ClickAction_FIRSTPAGE :
4039             nJump++;
4040         case ::com::sun::star::presentation::ClickAction_PREVPAGE :
4041             nJump++;
4042         case ::com::sun::star::presentation::ClickAction_NEXTPAGE :
4043         {
4044             nJump++;
4045             nAction = 3;
4046         }
4047         break;
4048         case ::com::sun::star::presentation::ClickAction_SOUND :
4049         {
4050             if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Bookmark" ) ) ) )
4051                 nSoundRef = maSoundCollection.GetId( *(::rtl::OUString*)mAny.getValue() );
4052         }
4053         break;
4054         case ::com::sun::star::presentation::ClickAction_PROGRAM :
4055         {
4056             if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Bookmark" ) ) ) )
4057             {
4058                 INetURLObject aUrl( *(::rtl::OUString*)mAny.getValue() );
4059                 if ( INET_PROT_FILE == aUrl.GetProtocol() )
4060                 {
4061                     aFile = aUrl.PathToFileName();
4062                     nAction = 2;
4063                 }
4064             }
4065         }
4066         break;
4067 
4068         case ::com::sun::star::presentation::ClickAction_BOOKMARK :
4069         {
4070             if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Bookmark" ) ) ) )
4071             {
4072                 String  aBookmark( *(::rtl::OUString*)mAny.getValue() );
4073                 sal_uInt32 nIndex = 0;
4074                 for ( String* pStr = (String*)maSlideNameList.First(); pStr; pStr = (String*)maSlideNameList.Next(), nIndex++ )
4075                 {
4076                     if ( *pStr == aBookmark )
4077                     {
4078                         // Bookmark ist ein link zu einer Dokumentseite
4079                         nAction = 4;
4080                         nHyperLinkType = 7;
4081 
4082                         String aEmpty;
4083                         String aHyperString = UniString::CreateFromInt32( 256 + nIndex );
4084                         aHyperString.Append( String( RTL_CONSTASCII_USTRINGPARAM( "," ) ) );
4085                         aHyperString.Append( String::CreateFromInt32( nIndex + 1 ) );
4086                         aHyperString.Append( String( RTL_CONSTASCII_USTRINGPARAM( ",Slide " ) ) );
4087                         aHyperString.Append( String::CreateFromInt32( nIndex + 1 ) );
4088                         nHyperLinkID = ImplInsertBookmarkURL( aHyperString, 1 | ( nIndex << 8 ) | ( 1 << 31 ), aBookmark, aEmpty, aEmpty, aHyperString );
4089                     }
4090                 }
4091             }
4092         }
4093         break;
4094 
4095         case ::com::sun::star::presentation::ClickAction_DOCUMENT :
4096         {
4097             if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Bookmark" ) ) ) )
4098             {
4099                 String aBookmark( *(::rtl::OUString*)mAny.getValue() );
4100                 if ( aBookmark.Len() )
4101                 {
4102                     nAction = 4;
4103                     nHyperLinkType = 8;
4104 
4105                     String aEmpty;
4106                     String aBookmarkFile( aBookmark );
4107                     INetURLObject aUrl( aBookmark );
4108                     if ( INET_PROT_FILE == aUrl.GetProtocol() )
4109                         aBookmarkFile = aUrl.PathToFileName();
4110                     nHyperLinkID = ImplInsertBookmarkURL( aBookmark, (sal_uInt32)(2 | ( 1 << 31 )), aBookmarkFile, aBookmark, aEmpty, aEmpty );
4111                 }
4112             }
4113         }
4114         break;
4115 
4116         case ::com::sun::star::presentation::ClickAction_INVISIBLE :
4117         case ::com::sun::star::presentation::ClickAction_VERB :
4118         case ::com::sun::star::presentation::ClickAction_VANISH :
4119         case ::com::sun::star::presentation::ClickAction_MACRO :
4120         default :
4121         break;
4122     }
4123 
4124     sal_uInt32 nContainerSize = 24;
4125     if ( nAction == 2 )
4126         nContainerSize += ( aFile.Len() * 2 ) + 8;
4127     rSt << (sal_uInt32)( ( EPP_InteractiveInfo << 16 ) | 0xf ) << (sal_uInt32)nContainerSize
4128         << (sal_uInt32)( EPP_InteractiveInfoAtom << 16 ) << (sal_uInt32)16
4129         << nSoundRef
4130         << nHyperLinkID
4131         << nAction
4132         << nOleVerb
4133         << nJump
4134         << nFlags
4135         << (sal_uInt32)nHyperLinkType;
4136 
4137     if ( nAction == 2 )     // run program Action
4138     {
4139         sal_uInt16 i, nLen = aFile.Len();
4140         rSt << (sal_uInt32)( ( EPP_CString << 16 ) | 0x20 ) << (sal_uInt32)( nLen * 2 );
4141         for ( i = 0; i < nLen; i++ )
4142             rSt << aFile.GetChar( i );
4143     }
4144 
4145     rSt << (sal_uInt32)( ( EPP_InteractiveInfo << 16 ) | 0x1f ) << (sal_uInt32)24   // Mouse Over Action
4146         << (sal_uInt32)( EPP_InteractiveInfo << 16 ) << (sal_uInt32)16;
4147     for ( int i = 0; i < 4; i++, rSt << (sal_uInt32)0 ) ;
4148 }
4149 
4150 //  -----------------------------------------------------------------------
4151 
ImplGetEffect(const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rPropSet,::com::sun::star::presentation::AnimationEffect & eEffect,::com::sun::star::presentation::AnimationEffect & eTextEffect,sal_Bool & bIsSound)4152 sal_Bool PPTWriter::ImplGetEffect( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rPropSet,
4153                                 ::com::sun::star::presentation::AnimationEffect& eEffect,
4154                                 ::com::sun::star::presentation::AnimationEffect& eTextEffect,
4155                                 sal_Bool& bIsSound )
4156 {
4157     ::com::sun::star::uno::Any aAny;
4158     if ( GetPropertyValue( aAny, rPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Effect" ) ) ) )
4159         aAny >>= eEffect;
4160     else
4161         eEffect = ::com::sun::star::presentation::AnimationEffect_NONE;
4162 
4163     if ( GetPropertyValue( aAny, rPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextEffect" ) ) ) )
4164         aAny >>= eTextEffect;
4165     else
4166         eTextEffect = ::com::sun::star::presentation::AnimationEffect_NONE;
4167     if ( GetPropertyValue( aAny, rPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "SoundOn" ) ) ) )
4168         aAny >>= bIsSound;
4169     else
4170         bIsSound = sal_False;
4171 
4172     sal_Bool bHasEffect = ( ( eEffect != ::com::sun::star::presentation::AnimationEffect_NONE )
4173                         || ( eTextEffect != ::com::sun::star::presentation::AnimationEffect_NONE )
4174                         || bIsSound );
4175     return bHasEffect;
4176 };
4177 
4178 //  -----------------------------------------------------------------------
4179 
ImplCreatePresentationPlaceholder(const sal_Bool bMasterPage,const PageType,const sal_uInt32 nStyleInstance,const sal_uInt8 nPlaceHolderId)4180 sal_Bool PPTWriter::ImplCreatePresentationPlaceholder( const sal_Bool bMasterPage, const PageType /* ePageType */,
4181                                                         const sal_uInt32 nStyleInstance, const sal_uInt8 nPlaceHolderId )
4182 {
4183     sal_Bool bRet = ImplGetText();
4184     if ( bRet && bMasterPage )
4185     {
4186         mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4187         sal_uInt32 nPresShapeID = mpPptEscherEx->GenerateShapeId();
4188         mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xa00, nPresShapeID );// Flags: HaveAnchor | HasSpt
4189         EscherPropertyContainer aPropOpt;
4190         aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x50001 );
4191         aPropOpt.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 );
4192         aPropOpt.AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle );
4193         aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x110001 );
4194         aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x8000001 );
4195         aPropOpt.AddOpt( ESCHER_Prop_shadowColor, 0x8000002 );
4196         aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
4197         sal_uInt32 nLineFlags = 0x90001;
4198         if ( aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ) )
4199             nLineFlags |= 0x10001;  // draw dashed line if no line
4200         aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags );
4201 
4202         SvMemoryStream  aExtBu( 0x200, 0x200 );
4203         SvMemoryStream  aClientTextBox( 0x200, 0x200 );
4204         ImplWriteTextStyleAtom( aClientTextBox, nStyleInstance, 0, NULL, aExtBu, &aPropOpt );
4205 
4206         aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
4207         aPropOpt.CreateShapeProperties( mXShape );
4208         aPropOpt.Commit( *mpStrm );
4209         mpPptEscherEx->AddAtom( 8, ESCHER_ClientAnchor );
4210         *mpStrm << (sal_Int16)maRect.Top() << (sal_Int16)maRect.Left() << (sal_Int16)maRect.Right() << (sal_Int16)maRect.Bottom();      // oben, links, rechts, unten ????
4211         mpPptEscherEx->OpenContainer( ESCHER_ClientData );
4212         mpPptEscherEx->AddAtom( 8, EPP_OEPlaceholderAtom );
4213         *mpStrm << (sal_uInt32)0                // PlacementID
4214                 << (sal_uInt8)nPlaceHolderId    // PlaceHolderID
4215                 << (sal_uInt8)0                 // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER )
4216                 << (sal_uInt16)0;               // padword
4217         mpPptEscherEx->CloseContainer();        // ESCHER_ClientData
4218 /*
4219         if ( aExtBu.Tell() )
4220         {
4221             if ( !pClientData )
4222                 pClientData = new SvMemoryStream( 0x200, 0x200 );
4223             ImplProgTagContainer( pClientData, &aExtBu );
4224         }
4225 */
4226         if ( aClientTextBox.Tell() )
4227         {
4228             *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf )
4229                     << (sal_uInt32)aClientTextBox.Tell();
4230 
4231             mpStrm->Write( aClientTextBox.GetData(), aClientTextBox.Tell() );
4232         }
4233         mpPptEscherEx->CloseContainer();    // ESCHER_SpContainer
4234     }
4235     else
4236         bRet = sal_False;
4237     return bRet;
4238 }
4239 
4240 //  -----------------------------------------------------------------------
4241 
ImplCreateShape(sal_uInt32 nType,sal_uInt32 nFlags,EscherSolverContainer & rSolver)4242 void PPTWriter::ImplCreateShape( sal_uInt32 nType, sal_uInt32 nFlags, EscherSolverContainer& rSolver )
4243 {
4244     sal_uInt32 nId = mpPptEscherEx->GenerateShapeId();
4245     mpPptEscherEx->AddShape( nType, nFlags, nId );
4246     rSolver.AddShape( mXShape, nId );
4247 }
4248 
ImplCreateTextShape(EscherPropertyContainer & rPropOpt,EscherSolverContainer & rSolver,sal_Bool bFill)4249 void PPTWriter::ImplCreateTextShape( EscherPropertyContainer& rPropOpt, EscherSolverContainer& rSolver, sal_Bool bFill )
4250 {
4251     mnTextStyle = EPP_TEXTSTYLE_TEXT;
4252     mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4253     ImplCreateShape( ESCHER_ShpInst_TextBox, 0xa00, rSolver );
4254     if ( bFill )
4255         rPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
4256     if ( ImplGetText() )
4257         rPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
4258 }
4259 
ImplWritePage(const PHLayout & rLayout,EscherSolverContainer & aSolverContainer,PageType ePageType,sal_Bool bMasterPage,int nPageNumber)4260 void PPTWriter::ImplWritePage( const PHLayout& rLayout, EscherSolverContainer& aSolverContainer, PageType ePageType, sal_Bool bMasterPage, int nPageNumber )
4261 {
4262     // #119551# PPT does not support groups of polygons and text (MS patch KB2289187)
4263     // sal_uInt32  nGroupLevel = 0;
4264 
4265     sal_uInt32  nInstance, nGroups, nShapes, nShapeCount, nPer, nLastPer, nIndices, nOlePictureId;
4266     sal_uInt16  nEffectCount;
4267     ::com::sun::star::awt::Point   aTextRefPoint;
4268 
4269     ResetGroupTable( nShapes = mXShapes->getCount() );
4270 
4271     nIndices = nInstance = nLastPer = nShapeCount = nEffectCount = 0;
4272 
4273     sal_Bool bIsTitlePossible = sal_True;           // bei mehr als einem title geht powerpoint in die knie
4274 
4275     sal_uInt32  nOutlinerCount = 0;             // die gliederungsobjekte muessen dem layout entsprechen,
4276     sal_uInt32  nPrevTextStyle = 0;                // es darf nicht mehr als zwei geben
4277 
4278     nOlePictureId = 0;
4279 
4280     sal_Bool bAdditionalText = sal_False;
4281 
4282     sal_Bool bSecOutl = sal_False;
4283     sal_uInt32 nPObjects = 0;
4284 
4285     SvMemoryStream* pClientTextBox = NULL;
4286     SvMemoryStream* pClientData = NULL;
4287 
4288     while( GetNextGroupEntry() )
4289     {
4290         nShapeCount++;
4291 
4292         nPer = ( 5 * nShapeCount ) / nShapes;
4293         if ( nPer != nLastPer )
4294         {
4295             nLastPer = nPer;
4296             sal_uInt32 nValue = mnPagesWritten * 5 + nPer;
4297             if ( nValue > mnStatMaxValue )
4298                 nValue = mnStatMaxValue;
4299             if ( mbStatusIndicator && ( nValue > mnLatestStatValue ) )
4300             {
4301                 mXStatusIndicator->setValue( nValue );
4302                 mnLatestStatValue = nValue;
4303             }
4304         }
4305         nGroups = GetGroupsClosed();
4306         for ( sal_uInt32 i = 0; i < nGroups; i++, mpPptEscherEx->LeaveGroup() ) ;
4307 
4308         if ( ImplGetShapeByIndex( GetCurrentGroupIndex(), sal_True ) )
4309         {
4310             sal_Bool bIsSound;
4311             sal_Bool bMediaClickAction = sal_False;
4312             ::com::sun::star::presentation::AnimationEffect eAe;
4313             ::com::sun::star::presentation::AnimationEffect eTe;
4314 
4315             if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "PresentationOrder" ) ) ) )
4316                 nEffectCount = *(sal_uInt16*)mAny.getValue();
4317 
4318             sal_Bool bEffect = ImplGetEffect( mXPropSet, eAe, eTe, bIsSound );
4319             ::com::sun::star::presentation::ClickAction eCa = ::com::sun::star::presentation::ClickAction_NONE;
4320             if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "OnClick" ) ) ) )
4321                 mAny >>= eCa;
4322 
4323             sal_Bool bGroup = mType == "drawing.Group";
4324             sal_Bool bOpenBezier   = mType == "drawing.OpenBezier";
4325             sal_Bool bClosedBezier = mType == "drawing.ClosedBezier";
4326             sal_Bool bPolyPolygon  = mType == "drawing.PolyPolygon";
4327             sal_Bool bPolyLine = mType == "drawing.PolyLine";
4328 
4329             List        aAdjustmentList;
4330             Rectangle   aPolyBoundRect;
4331 
4332             const ::com::sun::star::awt::Size   aSize100thmm( mXShape->getSize() );
4333             const ::com::sun::star::awt::Point  aPoint100thmm( mXShape->getPosition() );
4334             Rectangle   aRect100thmm( Point( aPoint100thmm.X, aPoint100thmm.Y ), Size( aSize100thmm.Width, aSize100thmm.Height ) );
4335             EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect100thmm );
4336 
4337             if ( bGroup )
4338             {
4339                 SvMemoryStream* pTmp = NULL;
4340                 ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >
4341                     aXIndexAccess( mXShape, ::com::sun::star::uno::UNO_QUERY );
4342                 if ( EnterGroup( aXIndexAccess ) )
4343                 {
4344                     if ( bEffect && !mbUseNewAnimations )
4345                     {
4346                         pTmp = new SvMemoryStream( 0x200, 0x200 );
4347                         ImplWriteObjectEffect( *pTmp, eAe, eTe, ++nEffectCount );
4348                     }
4349                     if ( eCa != ::com::sun::star::presentation::ClickAction_NONE )
4350                     {
4351                         if ( !pTmp )
4352                             pTmp = new SvMemoryStream( 0x200, 0x200 );
4353                         ImplWriteClickAction( *pTmp, eCa, bMediaClickAction );
4354                     }
4355                     sal_uInt32 nShapeId = mpPptEscherEx->EnterGroup( &maRect, pTmp );
4356                     aSolverContainer.AddShape( mXShape, nShapeId );
4357                     delete pTmp;
4358                 }
4359             }
4360             else
4361             {
4362                 sal_Bool bIsFontwork = sal_False;
4363                 sal_Bool bIsHatching = sal_False;
4364                 ::com::sun::star::uno::Any aAny;
4365                 ::com::sun::star::drawing::FillStyle eFS;
4366                 if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFontwork" ) ), sal_True ) )
4367                     aAny >>= bIsFontwork;
4368                 if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ), sal_True ) )
4369                 {
4370                     aAny >>= eFS;
4371                     bIsHatching = eFS == ::com::sun::star::drawing::FillStyle_HATCH;
4372                 }
4373                 if ( bIsHatching || bIsFontwork || ( mType == "drawing.Measure" ) || ( mType == "drawing.Caption" ) )
4374                 {
4375                     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "BoundRect" ) ) ) )
4376                     {
4377                         ::com::sun::star::awt::Rectangle aRect( *(::com::sun::star::awt::Rectangle*)mAny.getValue() );
4378                         maPosition = ImplMapPoint( ::com::sun::star::awt::Point( aRect.X, aRect.Y ) );
4379                         maSize = ImplMapSize( ::com::sun::star::awt::Size( aRect.Width, aRect.Height ) );
4380                         maRect = Rectangle( Point( maPosition.X, maPosition.Y ), Size( maSize.Width, maSize.Height ) );
4381                     }
4382                     mType = "drawing.dontknow";
4383                 }
4384             }
4385             sal_uInt8 nPlaceHolderAtom = EPP_PLACEHOLDER_NONE;
4386 
4387             mnTextSize = 0;
4388             mnTextStyle = EPP_TEXTSTYLE_NORMAL;
4389 
4390             if ( mType == "drawing.Custom" )
4391             {
4392                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4393                 sal_uInt32 nMirrorFlags;
4394                 rtl::OUString sCustomShapeType;
4395                 MSO_SPT eShapeType = aPropOpt.GetCustomShapeType( mXShape, nMirrorFlags, sCustomShapeType );
4396                 if ( sCustomShapeType.equalsAscii( "col-502ad400" ) || sCustomShapeType.equalsAscii( "col-60da8460" ) )
4397                 {   // sj: creating metafile for customshapes that can't be saved to ms format properly
4398                     ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer );
4399                     if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False ) )
4400                     {
4401                         aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
4402                         SdrObject* pObj = GetSdrObjectFromXShape( mXShape );
4403                         if ( pObj )
4404                         {
4405                             Rectangle aBound = pObj->GetCurrentBoundRect();
4406                             maPosition = ImplMapPoint( ::com::sun::star::awt::Point( aBound.Left(), aBound.Top() ) );
4407                             maSize = ImplMapSize( ::com::sun::star::awt::Size ( aBound.GetWidth(), aBound.GetHeight() ) );
4408                             maRect = Rectangle( Point( maPosition.X, maPosition.Y ), Size( maSize.Width, maSize.Height ) );
4409                             mnAngle = 0;
4410                         }
4411                     }
4412                 }
4413                 else
4414                 {
4415                     ImplCreateShape( eShapeType, nMirrorFlags | 0xa00, aSolverContainer );
4416                     aPropOpt.CreateCustomShapeProperties( eShapeType, mXShape );
4417                     aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape);
4418                     if ( ImplGetText() )
4419                     {
4420                         if ( !aPropOpt.IsFontWork() )
4421                             aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_True, sal_True );
4422                     }
4423                 }
4424             }
4425             else if ( mType == "drawing.Rectangle" )
4426             {
4427                 sal_Int32 nRadius = 0;
4428                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4429                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CornerRadius" ) ) ) )
4430                 {
4431                     mAny >>= nRadius;
4432                     nRadius = ImplMapSize( ::com::sun::star::awt::Size( nRadius, 0 ) ).Width;
4433                 }
4434                 if ( nRadius )
4435                 {
4436                     ImplCreateShape( ESCHER_ShpInst_RoundRectangle, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt
4437                     sal_Int32 nLenght = maRect.GetWidth();
4438                     if ( nLenght > maRect.GetHeight() )
4439                         nLenght = maRect.GetHeight();
4440                     nLenght >>= 1;
4441                     if ( nRadius >= nLenght )
4442                         nRadius = 0x2a30;                           // 0x2a30 ist PPTs maximum radius
4443                     else
4444                         nRadius = ( 0x2a30 * nRadius ) / nLenght;
4445                     aPropOpt.AddOpt( ESCHER_Prop_adjustValue, nRadius );
4446                 }
4447                 else
4448                 {
4449                     ImplCreateShape( ESCHER_ShpInst_Rectangle, 0xa00, aSolverContainer );          // Flags: Connector | HasSpt
4450                 }
4451                 aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
4452                 if ( ImplGetText() )
4453                     aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False );
4454             }
4455             else if ( mType == "drawing.Ellipse" )
4456             {
4457                 ::com::sun::star::drawing::CircleKind  eCircleKind( ::com::sun::star::drawing::CircleKind_FULL );
4458                 PolyStyle ePolyKind = POLY_CHORD;
4459                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CircleKind" ) ) ) )
4460                 {
4461                     mAny >>= eCircleKind;
4462                     switch ( eCircleKind )
4463                     {
4464                         case ::com::sun::star::drawing::CircleKind_SECTION :
4465                         {
4466                             ePolyKind = POLY_PIE;
4467                         }
4468                         break;
4469                         case ::com::sun::star::drawing::CircleKind_ARC :
4470                         {
4471                             ePolyKind = POLY_ARC;
4472                         }
4473                         break;
4474 
4475                         case ::com::sun::star::drawing::CircleKind_CUT :
4476                         {
4477                             ePolyKind = POLY_CHORD;
4478                         }
4479                         break;
4480 
4481                         default:
4482                             eCircleKind = ::com::sun::star::drawing::CircleKind_FULL;
4483                     }
4484                 }
4485                 if ( eCircleKind == ::com::sun::star::drawing::CircleKind_FULL )
4486                 {
4487                     mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4488                     ImplCreateShape( ESCHER_ShpInst_Ellipse, 0xa00, aSolverContainer );            // Flags: Connector | HasSpt
4489                     aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
4490                     if ( ImplGetText() )
4491                         aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False );
4492                 }
4493                 else
4494                 {
4495                     sal_Int32 nStartAngle, nEndAngle;
4496                     if ( !ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CircleStartAngle" ) ) ) )
4497                         continue;
4498                     nStartAngle = *( (sal_Int32*)mAny.getValue() );
4499                     if( !ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CircleEndAngle" ) ) ) )
4500                         continue;
4501                     nEndAngle = *( (sal_Int32*)mAny.getValue() );
4502                     ::com::sun::star::awt::Point aPoint( mXShape->getPosition() );
4503                     ::com::sun::star::awt::Size  aSize( mXShape->getSize() );
4504                     ::com::sun::star::awt::Point aStart, aEnd, aCenter;
4505                     Rectangle aRect( Point( aPoint.X, aPoint.Y ), Size( aSize.Width, aSize.Height ) );
4506                     aStart.X = (sal_Int32)( ( cos( (double)( nStartAngle * F_PI18000 ) ) * 100.0 ) );
4507                     aStart.Y = - (sal_Int32)( ( sin( (double)( nStartAngle * F_PI18000 ) ) * 100.0 ) );
4508                     aEnd.X = (sal_Int32)( ( cos( (double)( nEndAngle * F_PI18000 ) ) * 100.0 ) );
4509                     aEnd.Y = - (sal_Int32)( ( sin( (double)( nEndAngle * F_PI18000 ) ) * 100.0 ) );
4510                     aCenter.X = aPoint.X + ( aSize.Width / 2 );
4511                     aCenter.Y = aPoint.Y + ( aSize.Height / 2 );
4512                     aStart.X += aCenter.X;
4513                     aStart.Y += aCenter.Y;
4514                     aEnd.X += aCenter.X;
4515                     aEnd.Y += aCenter.Y;
4516                     Polygon aPolygon( aRect, Point( aStart.X, aStart.Y ), Point( aEnd.X, aEnd.Y ), ePolyKind );
4517                     sal_Bool bNeedText = sal_True;
4518                     if ( mnAngle )
4519                     {
4520                         aPolygon.Rotate( aRect.TopLeft(), (sal_uInt16)( mnAngle / 10 ) );
4521                         if ( ImplGetText() )
4522                         {
4523                             // #119551# PPT does not support groups of polygons and text (MS patch KB2289187)
4524                             // mpPptEscherEx->EnterGroup( 0,0 );
4525                             // nGroupLevel = mpPptEscherEx->GetGroupLevel();
4526                             bNeedText = sal_False;
4527                             bAdditionalText = sal_True;
4528                             mnTextSize = 0;
4529                         }
4530                         mnAngle = 0;
4531                     }
4532                     mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4533                     ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer );       // Flags: Connector | HasSpt
4534                     ::com::sun::star::awt::Rectangle aNewRect;
4535                     switch ( ePolyKind )
4536                     {
4537                         case POLY_PIE :
4538                         case POLY_CHORD :
4539                         {
4540                             if ( aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, &aPolygon ) )
4541                                 aPropOpt.CreateFillProperties( mXPropSet, sal_True , mXShape );
4542                         }
4543                         break;
4544 
4545                         case POLY_ARC :
4546                         {
4547                             if ( aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, &aPolygon ) )
4548                                 aPropOpt.CreateLineProperties( mXPropSet, sal_False );
4549                         }
4550                         break;
4551                     }
4552                     maRect = ImplMapRectangle( aNewRect );
4553                     maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
4554                     maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
4555                     if ( bNeedText && ImplGetText() )
4556                         aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False );
4557                 }
4558             }
4559             else if ( mType == "drawing.Control" )
4560             {
4561                 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XControlShape  >
4562                     aXControlShape( mXShape, ::com::sun::star::uno::UNO_QUERY );
4563                 if ( !aXControlShape.is() )
4564                     continue;
4565                 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >
4566                     aXControlModel( aXControlShape->getControl() );
4567                 if ( !aXControlModel.is() )
4568                     continue;
4569 
4570                 sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT;
4571                 try
4572                 {
4573                     // try to get the aspect when available
4574                     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
4575                         xShapeProps( mXShape, ::com::sun::star::uno::UNO_QUERY_THROW );
4576                     xShapeProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Aspect" ) ) ) >>= nAspect;
4577                 }
4578                 catch( ::com::sun::star::uno::Exception& )
4579                 {}
4580 
4581                 *mpExEmbed  << (sal_uInt32)( 0xf | ( EPP_ExControl << 16 ) )
4582                             << (sal_uInt32)0;               // Size of this container
4583 
4584                 sal_uInt32 nSize, nOldPos = mpExEmbed->Tell();
4585 
4586                 sal_uInt32 nPageId = nPageNumber;
4587                 if ( ePageType == MASTER )
4588                     nPageId |= 0x80000000;
4589                 else
4590                     nPageId += 0x100;
4591                 *mpExEmbed  << (sal_uInt32)( EPP_ExControlAtom << 16 )
4592                             << (sal_uInt32)4
4593                             << nPageId;
4594                 PPTExOleObjEntry* pEntry = new PPTExOleObjEntry( OCX_CONTROL, mpExEmbed->Tell() );
4595                 pEntry->xControlModel = aXControlModel;
4596                 pEntry->xShape = mXShape;
4597                 maExOleObj.Insert( pEntry );
4598 
4599                 mnExEmbed++;
4600 
4601                 *mpExEmbed  << (sal_uInt32)( 1 | ( EPP_ExOleObjAtom << 16 ) )
4602                             << (sal_uInt32)24
4603                             << (sal_uInt32)nAspect
4604                             << (sal_uInt32)2
4605                             << (sal_uInt32)mnExEmbed
4606                             << (sal_uInt32)0
4607                             << (sal_uInt32)4    // index to the persist table
4608                             << (sal_uInt32)0x0012de00;
4609 
4610 
4611                 ::com::sun::star::awt::Size     aSize;
4612                 String          aControlName;
4613                 SvStorageRef    xTemp( new SvStorage( new SvMemoryStream(), sal_True ) );
4614                 if ( SvxMSConvertOCXControls::WriteOCXStream( xTemp, aXControlModel, aSize, aControlName ) )
4615                 {
4616                     String  aUserName( xTemp->GetUserName() );
4617                     String  aOleIdentifier;
4618                     if ( aUserName.Len() )
4619                     {
4620                         SvStorageStreamRef xCompObj = xTemp->OpenSotStream(
4621                             String( RTL_CONSTASCII_USTRINGPARAM( "\1CompObj" ) ),
4622                                 STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYALL );
4623                         xCompObj->Seek( STREAM_SEEK_TO_END );
4624                         sal_uInt32  nStreamLen = xCompObj->Tell();
4625                         xCompObj->Seek( 0 );
4626                         sal_Int16   nVersion, nByteOrder;
4627                         sal_Int32   nWinVersion, nVal, nStringLen;
4628                         *xCompObj   >> nVersion
4629                                     >> nByteOrder
4630                                     >> nWinVersion
4631                                     >> nVal;
4632                         xCompObj->SeekRel( 16 );    // skipping clsid
4633                         *xCompObj   >> nStringLen;
4634                         if ( ( xCompObj->Tell() + nStringLen ) < nStreamLen )
4635                         {
4636                             xCompObj->SeekRel( nStringLen );        // now skipping the UserName;
4637                             *xCompObj >> nStringLen;
4638                             if ( ( xCompObj->Tell() + nStringLen ) < nStreamLen )
4639                             {
4640                                 xCompObj->SeekRel( nStringLen );    // now skipping the clipboard formatname
4641                                 *xCompObj   >> nStringLen;
4642                                 if ( ( nStringLen > 1 ) && ( ( xCompObj->Tell() + nStringLen ) < nStreamLen ) )
4643                                 {   // i think that the OleIdentifier will follow
4644                                     ByteString aTemp;
4645                                     sal_Char* p = aTemp.AllocBuffer( (sal_uInt16)(nStringLen - 1) );
4646                                     xCompObj->Read( p, nStringLen - 1 );
4647                                     aOleIdentifier = String( aTemp, gsl_getSystemTextEncoding() );
4648                                 }
4649                             }
4650                         }
4651                     }
4652                     if ( aControlName.Len() )
4653                         PPTWriter::WriteCString( *mpExEmbed, aControlName, 1 );
4654                     if ( aOleIdentifier.Len() )
4655                         PPTWriter::WriteCString( *mpExEmbed, aOleIdentifier, 2 );
4656                     if ( aUserName.Len() )
4657                         PPTWriter::WriteCString( *mpExEmbed, aUserName, 3 );
4658                 }
4659                 nSize = mpExEmbed->Tell() - nOldPos;
4660                 mpExEmbed->Seek( nOldPos - 4 );
4661                 *mpExEmbed << nSize;
4662                 mpExEmbed->Seek( STREAM_SEEK_TO_END );
4663                 nOlePictureId = mnExEmbed;
4664 
4665                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4666                 sal_uInt32 nSpFlags = SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_OLESHAPE;
4667                 ImplCreateShape( ESCHER_ShpInst_HostControl, nSpFlags, aSolverContainer );
4668                 if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False  ) )
4669                     aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
4670                 //export form control graphic
4671                 else if ( aPropOpt.CreateBlipPropertiesforOLEControl(mXPropSet,mXShape))
4672                     aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
4673                 aPropOpt.AddOpt( ESCHER_Prop_pictureId, mnExEmbed );
4674                 aPropOpt.AddOpt( ESCHER_Prop_pictureActive, 0x10000 );
4675 
4676                 if ( aControlName.Len() )
4677                 {
4678                     sal_uInt16 i, nBufSize;
4679                     nBufSize = ( aControlName.Len() + 1 ) << 1;
4680                     sal_uInt8* pBuf = new sal_uInt8[ nBufSize ];
4681                     sal_uInt8* pTmp = pBuf;
4682                     for ( i = 0; i < aControlName.Len(); i++ )
4683                     {
4684                         sal_Unicode nUnicode = aControlName.GetChar( i );
4685                         *pTmp++ = (sal_uInt8)nUnicode;
4686                         *pTmp++ = (sal_uInt8)( nUnicode >> 8 );
4687                     }
4688                     *pTmp++ = 0;
4689                     *pTmp = 0;
4690                     aPropOpt.AddOpt( ESCHER_Prop_wzName, sal_True, nBufSize, pBuf, nBufSize );
4691                 }
4692             }
4693             else if ( mType == "drawing.Connector" )
4694             {
4695                 sal_uInt16 nSpType, nSpFlags;
4696                 ::com::sun::star::awt::Rectangle aNewRect;
4697                 if ( aPropOpt.CreateConnectorProperties( mXShape, aSolverContainer, aNewRect, nSpType, nSpFlags ) == sal_False )
4698                     continue;
4699 
4700                 maRect = ImplMapRectangle( aNewRect );
4701                 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
4702                 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
4703 
4704                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4705                 ImplCreateShape( nSpType, nSpFlags, aSolverContainer );
4706 
4707                 // #119459# for connector shape, the start point and end point is fixed, and should not be rotated.
4708                 mnAngle = 0;
4709             }
4710             else if ( mType == "drawing.Measure" )
4711             {
4712                 continue;
4713             }
4714             else if ( mType == "drawing.Line" )
4715             {
4716                 ::com::sun::star::awt::Rectangle aNewRect;
4717                 aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_LINE, sal_False, aNewRect, NULL );
4718                 maRect = ImplMapRectangle( aNewRect );
4719                 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
4720                 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
4721                 if ( ImplGetText() )
4722                 {
4723                     aTextRefPoint = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
4724                     mnTextSize = 0;
4725                     bAdditionalText = sal_True;
4726                     // #119551# PPT does not support groups of polygons and text (MS patch KB2289187)
4727                     // mpPptEscherEx->EnterGroup( &maRect,0 );
4728                 }
4729                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4730                 sal_uInt32 nFlags = 0xa00;                                  // Flags: Connector | HasSpt
4731                 if ( maRect.Top() > maRect.Bottom() )
4732                     nFlags |= 0x80;                                         // Flags: VertMirror
4733                 if ( maRect.Left() > maRect.Right() )
4734                     nFlags |= 0x40;                                         // Flags: HorzMirror
4735 
4736                 ImplCreateShape( ESCHER_ShpInst_Line, nFlags, aSolverContainer );
4737                 aPropOpt.AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex );
4738                 aPropOpt.CreateLineProperties( mXPropSet, sal_False );
4739                 mnAngle = 0;
4740             }
4741             else if ( bPolyPolygon )
4742             {
4743                 if ( ImplGetText() )
4744                 {
4745                     // #119551# PPT does not support groups of polygons and text (MS patch KB2289187)
4746                     // mpPptEscherEx->EnterGroup( 0,0 );
4747                     // nGroupLevel = mpPptEscherEx->GetGroupLevel();
4748                     bAdditionalText = sal_True;
4749                     mnTextSize = 0;
4750                 }
4751                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4752                 ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer );            // Flags: Connector | HasSpt
4753                 ::com::sun::star::awt::Rectangle aNewRect;
4754                 aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, NULL );
4755                 maRect = ImplMapRectangle( aNewRect );
4756                 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
4757                 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
4758                 aPropOpt.CreateFillProperties( mXPropSet, sal_True , mXShape );
4759                 mnAngle = 0;
4760             }
4761             else if ( bPolyLine )
4762             {
4763                 if ( ImplGetText() )
4764                 {
4765                     // #119551# PPT does not support groups of polygons and text (MS patch KB2289187)
4766                     // mpPptEscherEx->EnterGroup( 0,0 );
4767                     // nGroupLevel = mpPptEscherEx->GetGroupLevel();
4768                     bAdditionalText = sal_True;
4769                     mnTextSize = 0;
4770                 }
4771                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4772                 ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer );            // Flags: Connector | HasSpt
4773                 ::com::sun::star::awt::Rectangle aNewRect;
4774                 aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, NULL );
4775                 maRect = ImplMapRectangle( aNewRect );
4776                 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
4777                 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
4778                 aPropOpt.CreateLineProperties( mXPropSet, sal_False );
4779                 mnAngle = 0;
4780             }
4781             else if ( bOpenBezier )
4782             {
4783                 if ( ImplGetText() )
4784                 {
4785                     // #119551# PPT does not support groups of polygons and text (MS patch KB2289187)
4786                     // mpPptEscherEx->EnterGroup( 0,0 );
4787                     // nGroupLevel = mpPptEscherEx->GetGroupLevel();
4788                     bAdditionalText = sal_True;
4789                     mnTextSize = 0;
4790                 }
4791                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4792                 ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer );            // Flags: Connector | HasSpt
4793                 ::com::sun::star::awt::Rectangle aNewRect;
4794                 aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_True, aNewRect, NULL );
4795                 maRect = ImplMapRectangle( aNewRect );
4796                 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
4797                 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
4798                 aPropOpt.CreateLineProperties( mXPropSet, sal_False );
4799                 mnAngle = 0;
4800             }
4801             else if ( bClosedBezier )
4802             {
4803                 if ( ImplGetText() )
4804                 {
4805                     // #119551# PPT does not support groups of polygons and text (MS patch KB2289187)
4806                     // mpPptEscherEx->EnterGroup( 0,0 );
4807                     // nGroupLevel = mpPptEscherEx->GetGroupLevel();
4808                     bAdditionalText = sal_True;
4809                     mnTextSize = 0;
4810                 }
4811                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4812                 ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer );            // Flags: Connector | HasSpt
4813                 ::com::sun::star::awt::Rectangle aNewRect;
4814                 aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_True, aNewRect, NULL );
4815                 maRect = ImplMapRectangle( aNewRect );
4816                 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
4817                 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
4818                 aPropOpt.CreateFillProperties( mXPropSet, sal_True , mXShape );
4819                 mnAngle = 0;
4820             }
4821             else if ( ( mType == "drawing.GraphicObject" ) || ( mType == "presentation.GraphicObject" ) )
4822             {
4823                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4824 
4825                 // ein GraphicObject kann auch ein ClickMe Element sein
4826                 if ( mbEmptyPresObj && ( ePageType == NORMAL ) )
4827                 {
4828                     nPlaceHolderAtom = rLayout.nUsedObjectPlaceHolder;
4829                     ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer );           // Flags: HaveAnchor | HaveMaster
4830                     aPropOpt.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 );
4831                     aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 );
4832                     aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x10001 );
4833                     aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody );
4834                 }
4835                 else
4836                 {
4837                     mXText = ::com::sun::star::uno::Reference<
4838                         ::com::sun::star::text::XSimpleText >
4839                             ( mXShape, ::com::sun::star::uno::UNO_QUERY );
4840 
4841                     if ( mXText.is() )
4842                         mnTextSize = mXText->getString().getLength();
4843 
4844                     if ( mnTextSize )                                       // graphic object oder Flachenfuellung
4845                     {
4846                         /* SJ #i34951#: because M. documents are not allowing GraphicObjects containing text, we
4847                         have to create a simpe Rectangle with fill bitmap instead (while not allowing BitmapMode_Repeat).
4848                         */
4849                         ImplCreateShape( ESCHER_ShpInst_Rectangle, 0xa00, aSolverContainer );       // Flags: Connector | HasSpt
4850                         if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), sal_True, sal_True, sal_False ) )
4851                         {
4852                             aPropOpt.AddOpt( ESCHER_Prop_WrapText, ESCHER_WrapNone );
4853                             aPropOpt.AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle );
4854                             aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 );
4855                             aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x8000000 );
4856                             aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
4857                             if ( ImplGetText() )
4858                                 aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False );
4859                         }
4860                     }
4861                     else
4862                     {
4863                         ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer );
4864 
4865                         if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), sal_False, sal_True ) )
4866                         {
4867                             aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
4868                         }
4869                     }
4870                 }
4871             }
4872             else if ( ( mType == "drawing.Text" ) || ( mType == "presentation.Notes" ) )
4873             {
4874                 if ( ( ePageType == NOTICE ) && mbPresObj )
4875                 {
4876                     if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Notes, EPP_PLACEHOLDER_MASTERNOTESBODYIMAGE ) )
4877                         continue;
4878                     else
4879                         nPlaceHolderAtom = EPP_PLACEHOLDER_NOTESBODY;
4880                 }
4881                 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
4882             }
4883             else if ( mType == "presentation.TitleText" )
4884             {
4885                 if ( mbPresObj )
4886                 {
4887                     if ( ( ePageType == NOTICE ) && mbEmptyPresObj )
4888                     {
4889                         mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4890                         nPlaceHolderAtom = EPP_PLACEHOLDER_MASTERNOTESBODYIMAGE;
4891                         ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x200, aSolverContainer );
4892                         aPropOpt.CreateLineProperties( mXPropSet, sal_False );
4893                         aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 );
4894                     }
4895                     else if ( rLayout.bTitlePossible && bIsTitlePossible )
4896                     {
4897                         bIsTitlePossible = sal_False;
4898 
4899                         ImplGetText();
4900                         TextObj aTextObj( mXText, EPP_TEXTTYPE_Title, maFontCollection, (PPTExBulletProvider&)*this );
4901                         if ( ePageType == MASTER )
4902                         {
4903                             if ( mnTextSize )
4904                             {
4905                                 ::rtl::OUString aUString( mXText->getString() );
4906                                 sal_uInt16 nChar;
4907 
4908                                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4909                                 mnShapeMasterTitle = mpPptEscherEx->GenerateShapeId();
4910                                 mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xa00, mnShapeMasterTitle );// Flags: HaveAnchor | HasSpt
4911                                 EscherPropertyContainer aPropertyOptions;
4912                                 aPropertyOptions.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x50001 );
4913                                 aPropertyOptions.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 );
4914                                 aPropertyOptions.AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle );
4915 //                              aPropertyOptions.AddOpt( ESCHER_Prop_fillColor, nFillColor );
4916 //                              aPropertyOptions.AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor );
4917                                 aPropertyOptions.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x110001 );
4918                                 aPropertyOptions.AddOpt( ESCHER_Prop_lineColor, 0x8000001 );
4919                                 aPropertyOptions.AddOpt( ESCHER_Prop_shadowColor, 0x8000002 );
4920                                 aPropertyOptions.CreateFillProperties( mXPropSet, sal_True, mXShape );
4921                                 sal_uInt32 nLineFlags = 0x90001;
4922                                 if ( aPropertyOptions.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ) )
4923                                     nLineFlags |= 0x10001;  // draw dashed line if no line
4924                                 aPropertyOptions.AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags );
4925                                 aPropertyOptions.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
4926                                 ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt );
4927                                 aPropertyOptions.Commit( *mpStrm );
4928                                 mpPptEscherEx->AddAtom( 8, ESCHER_ClientAnchor );
4929                                 *mpStrm << (sal_Int16)maRect.Top() << (sal_Int16)maRect.Left() << (sal_Int16)maRect.Right() << (sal_Int16)maRect.Bottom();      // oben, links, rechts, unten ????
4930                                 mpPptEscherEx->OpenContainer( ESCHER_ClientData );
4931                                 mpPptEscherEx->AddAtom( 8, EPP_OEPlaceholderAtom );
4932                                 *mpStrm << (sal_uInt32)0                                                        // PlacementID
4933                                         << (sal_uInt8)EPP_PLACEHOLDER_MASTERTITLE                               // PlaceHolderID
4934                                         << (sal_uInt8)0                                                         // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER )
4935                                         << (sal_uInt16)0;                                                       // padword
4936                                 mpPptEscherEx->CloseContainer();    // ESCHER_ClientData
4937                                 mpPptEscherEx->OpenContainer( ESCHER_ClientTextbox );
4938                                 mpPptEscherEx->AddAtom( 4, EPP_TextHeaderAtom );
4939                                 *mpStrm << (sal_uInt32)EPP_TEXTTYPE_Title;
4940                                 mpPptEscherEx->AddAtom( mnTextSize << 1, EPP_TextCharsAtom );
4941                                 const sal_Unicode* pString = aUString.getStr();
4942                                 for ( sal_uInt32 i = 0; i < mnTextSize; i++ )
4943                                 {
4944                                     nChar = pString[ i ];       // 0xa -> 0xb weicher Zeilenumbruch
4945                                     if ( nChar == 0xa )
4946                                         nChar++;                // 0xd -> 0xd harter Zeilenumbruch
4947                                     *mpStrm << nChar;
4948                                 }
4949                                 mpPptEscherEx->AddAtom( 6, EPP_BaseTextPropAtom );
4950                                 *mpStrm << (sal_uInt32)( mnTextSize + 1 ) << (sal_uInt16)0;
4951                                 mpPptEscherEx->AddAtom( 10, EPP_TextSpecInfoAtom );
4952                                 *mpStrm << (sal_uInt32)( mnTextSize + 1 ) << (sal_uInt32)1 << (sal_uInt16)0;
4953                                 mpPptEscherEx->CloseContainer();    // ESCHER_ClientTextBox
4954                                 mpPptEscherEx->CloseContainer();    // ESCHER_SpContainer
4955                             }
4956                             continue;
4957                         }
4958                         else
4959                         {
4960                             mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
4961                             mnTextStyle = EPP_TEXTSTYLE_TITLE;
4962                             nPlaceHolderAtom = rLayout.nTypeOfTitle;
4963                             ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer );          // Flags: HaveAnchor | HaveMaster
4964                             aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterTitle );
4965                             aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
4966                             aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
4967                             ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt );
4968                             if ( mbEmptyPresObj )
4969                             {
4970                                 sal_uInt32 nNoLineDrawDash = 0;
4971                                 aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash );
4972                                 nNoLineDrawDash |= 0x10001;
4973                                 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash );
4974                             }
4975                         }
4976                     }
4977                     else
4978                         mbPresObj = sal_False;
4979                 }
4980                 if ( !mbPresObj )
4981                 {
4982                     mType = "drawing.Text";
4983                     ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
4984                 }
4985             }
4986             else if ( ( mType == "presentation.Outliner" ) || ( mType == "presentation.Subtitle" ) )
4987             {
4988                 if ( mbPresObj )
4989                 {
4990                     nOutlinerCount++;
4991                     if ( (rLayout.bOutlinerPossible && ( nOutlinerCount == 1 )) ||
4992                          (( rLayout.bSecOutlinerPossible && ( nOutlinerCount == 2 ) ) && ( nPrevTextStyle == EPP_TEXTSTYLE_BODY ))
4993                        )
4994                     {
4995                         ImplGetText();
4996                         TextObj aTextObj( mXText, EPP_TEXTTYPE_Body, maFontCollection, (PPTExBulletProvider&)*this );
4997                         if ( ePageType == MASTER )
4998                         {
4999                             nPrevTextStyle = EPP_TEXTSTYLE_TITLE;
5000                             if ( mnTextSize )
5001                             {
5002                                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
5003                                 mnShapeMasterBody = mpPptEscherEx->GenerateShapeId();
5004                                 mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xa00, mnShapeMasterBody );  // Flags: HaveAnchor | HasSpt
5005                                 EscherPropertyContainer aPropOpt2;
5006                                 aPropOpt2.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x50001 );
5007                                 aPropOpt2.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 );
5008 //                              aPropOpt2.AddOpt( ESCHER_Prop_fillColor, nFillColor );
5009 //                              aPropOpt2.AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor );
5010                                 aPropOpt2.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x110001 );
5011                                 aPropOpt2.AddOpt( ESCHER_Prop_lineColor, 0x8000001 );
5012                                 aPropOpt2.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90001 );
5013                                 aPropOpt2.AddOpt( ESCHER_Prop_shadowColor, 0x8000002 );
5014                                 aPropOpt2.CreateFillProperties( mXPropSet, sal_True, mXShape  );
5015                                 sal_uInt32 nLineFlags = 0x90001;
5016                                 if ( aPropOpt2.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ) )
5017                                     nLineFlags |= 0x10001;  // draw dashed line if no line
5018                                 aPropOpt2.AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags );
5019                                 aPropOpt2.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
5020                                 ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt2 );
5021                                 aPropOpt2.Commit( *mpStrm );
5022                                 mpPptEscherEx->AddAtom( 8, ESCHER_ClientAnchor );
5023                                 *mpStrm << (sal_Int16)maRect.Top() << (sal_Int16)maRect.Left() << (sal_Int16)maRect.Right() << (sal_Int16)maRect.Bottom();  // oben, links, rechts, unten ????
5024                                 mpPptEscherEx->OpenContainer( ESCHER_ClientData );
5025                                 mpPptEscherEx->AddAtom( 8, EPP_OEPlaceholderAtom );
5026                                 sal_uInt8 PlaceHolderID = ( mType == "presentation.Subtitle") ? EPP_PLACEHOLDER_MASTERSUBTITLE:EPP_PLACEHOLDER_MASTERBODY;
5027                                 *mpStrm << (sal_uInt32)1                                                        // PlacementID
5028                                         << PlaceHolderID/*(sal_uInt8)EPP_PLACEHOLDER_MASTERBODY */                                   // PlaceHolderID
5029                                         << (sal_uInt8)0                                                         // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER )
5030                                         << (sal_uInt16)0;                                                       // padword
5031                                 mpPptEscherEx->CloseContainer();    // ESCHER_ClientData
5032                                 mpPptEscherEx->OpenContainer( ESCHER_ClientTextbox );       // printf
5033                                 mpPptEscherEx->AddAtom( 4, EPP_TextHeaderAtom );
5034                                 if ( mType == "presentation.Subtitle")
5035                                     *mpStrm << (sal_uInt32)EPP_TEXTTYPE_CenterBody;
5036                                 else
5037                                     *mpStrm << (sal_uInt32)EPP_TEXTTYPE_Body;
5038                                 mnTextSize = aTextObj.Count();
5039                                 aTextObj.Write( mpStrm );
5040                                 mpPptEscherEx->BeginAtom();
5041                                 for ( ParagraphObj* pPara = aTextObj.First() ; pPara; pPara = aTextObj.Next() )
5042                                 {
5043                                     sal_uInt32 nCharCount = pPara->Count();
5044                                     sal_uInt16 nDepth = pPara->nDepth;
5045                                     if ( nDepth > 4)
5046                                         nDepth = 4;
5047 
5048                                     *mpStrm << nCharCount
5049                                             << nDepth;
5050                                 }
5051                                 mpPptEscherEx->EndAtom( EPP_BaseTextPropAtom );
5052                                 mpPptEscherEx->AddAtom( 10, EPP_TextSpecInfoAtom );
5053                                 *mpStrm << (sal_uInt32)( mnTextSize ) << (sal_uInt32)1 << (sal_uInt16)0;
5054 
5055                                 mpPptEscherEx->CloseContainer();    // ESCHER_ClientTextBox
5056                                 mpPptEscherEx->CloseContainer();    // ESCHER_SpContainer
5057                             }
5058                             continue;
5059                         }
5060                         else
5061                         {
5062                             mnTextStyle = EPP_TEXTSTYLE_BODY;
5063                             nPlaceHolderAtom = rLayout.nTypeOfOutliner;
5064                             mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
5065                             ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer );          // Flags: HaveAnchor | HaveMaster
5066                             aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody );
5067                             aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
5068                             aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
5069                             ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt );
5070                             if ( mbEmptyPresObj )
5071                             {
5072                                 sal_uInt32 nNoLineDrawDash = 0;
5073                                 aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash );
5074                                 nNoLineDrawDash |= 0x10001;
5075                                 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash );
5076                             }
5077                         }
5078                     }
5079                     else
5080                         mbPresObj = sal_False;
5081                 }
5082                 if ( !mbPresObj )
5083                 {
5084                     if (ePageType == MASTER )
5085                     {
5086                         SdrObject* pObj = GetSdrObjectFromXShape( mXShape );
5087                         if (pObj && pObj->IsNotVisibleAsMaster())
5088                             continue;
5089                     }
5090 
5091                     mType = "drawing.Text";
5092                     ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
5093                 }
5094             }
5095             else if ( ( mType == "drawing.Page" ) || ( mType == "presentation.Page" ) )
5096             {
5097                 if ( ( ePageType == NOTICE ) && mbPresObj )
5098                 {
5099                     if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Notes, EPP_PLACEHOLDER_MASTERNOTESSLIDEIMAGE ) )
5100                         continue;
5101                     else
5102                         nPlaceHolderAtom = EPP_PLACEHOLDER_NOTESSLIDEIMAGE;
5103                 }
5104                 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
5105             }
5106             else if ( mType == "drawing.Frame" )
5107             {
5108                 continue;
5109             }
5110             else if ( ( mType == "drawing.OLE2" ) || ( mType == "presentation.OLE2" )
5111                         || ( mType == "presentation.Chart" ) || ( mType == "presentation.Calc" )
5112                             || ( mType == "presentation.OrgChart" ) )
5113             {
5114                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
5115                 if ( mbEmptyPresObj && ( ePageType == NORMAL ) )
5116                 {
5117                     nPlaceHolderAtom = rLayout.nUsedObjectPlaceHolder;
5118                     ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer );              // Flags: HaveAnchor | HaveMaster
5119                     aPropOpt.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 );
5120                     aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 );
5121                     aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x10001 );
5122                     aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody );
5123                 }
5124                 else
5125                 {
5126                     *mpExEmbed  << (sal_uInt32)( 0xf | ( EPP_ExEmbed << 16 ) )
5127                                 << (sal_uInt32)0;               // Size of this container
5128 
5129                     sal_uInt32 nSize, nOldPos = mpExEmbed->Tell();
5130 
5131                     *mpExEmbed  << (sal_uInt32)( EPP_ExEmbedAtom << 16 )
5132                                 << (sal_uInt32)8
5133                                 << (sal_uInt32)0    // follow colorscheme : 0->do not follow
5134                                                     //                      1->follow collorscheme
5135                                                     //                      2->follow text and background scheme
5136                                 << (sal_uInt8)1     // (bool)set if embedded server can not be locked
5137                                 << (sal_uInt8)0     // (bool)do not need to send dimension
5138                                 << (sal_uInt8)0     // (bool)is object a world table
5139                                 << (sal_uInt8)0;    // pad byte
5140 
5141                     PPTExOleObjEntry* pE = new PPTExOleObjEntry( NORMAL_OLE_OBJECT, mpExEmbed->Tell() );
5142                     pE->xShape = mXShape;
5143                     maExOleObj.Insert( pE );
5144 
5145                     mnExEmbed++;
5146 
5147                     sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT;
5148                     try
5149                     {
5150                         // try to get the aspect when available
5151                         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
5152                             xShapeProps( mXShape, ::com::sun::star::uno::UNO_QUERY_THROW );
5153                         xShapeProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Aspect" ) ) ) >>= nAspect;
5154                     }
5155                     catch( ::com::sun::star::uno::Exception& )
5156                     {}
5157 
5158                     *mpExEmbed  << (sal_uInt32)( 1 | ( EPP_ExOleObjAtom << 16 ) )
5159                                 << (sal_uInt32)24
5160                                 << (sal_uInt32)nAspect      // Aspect
5161                                 << (sal_uInt32)0
5162                                 << (sal_uInt32)mnExEmbed    // index to the persist table
5163                                 << (sal_uInt32)0            // subtype
5164                                 << (sal_uInt32)0
5165                                 << (sal_uInt32)0x0012b600;
5166 
5167 //                  PPTWriter::WriteCString( *mpExEmbed, "Photo Editor Photo", 1 );
5168 //                  PPTWriter::WriteCString( *mpExEmbed, "MSPhotoEd.3", 2 );
5169 //                  PPTWriter::WriteCString( *mpExEmbed, "Microsoft Photo Editor 3.0 Photo", 3 );
5170 
5171                     nSize = mpExEmbed->Tell() - nOldPos;
5172                     mpExEmbed->Seek( nOldPos - 4 );
5173                     *mpExEmbed << nSize;
5174                     mpExEmbed->Seek( STREAM_SEEK_TO_END );
5175                     nOlePictureId = mnExEmbed;
5176 
5177                     sal_uInt32 nSpFlags = 0xa00;
5178                     if ( nOlePictureId )
5179                         nSpFlags |= 0x10;
5180                     ImplCreateShape( ESCHER_ShpInst_PictureFrame, nSpFlags, aSolverContainer );
5181                     if ( aPropOpt.CreateOLEGraphicProperties( mXShape ) )
5182                         aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
5183                     if ( nOlePictureId )
5184                         aPropOpt.AddOpt( ESCHER_Prop_pictureId, nOlePictureId );
5185                 }
5186             }
5187             else if ( mType == "presentation.Header" )
5188             {
5189                 if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERHEADER ) )
5190                     continue;
5191                 else
5192                 {
5193                     mbPresObj = sal_False;
5194                     mType = "drawing.Text";
5195                     ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
5196                 }
5197             }
5198             else if ( mType == "presentation.Footer" )
5199             {
5200                 if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERFOOTER ) )
5201                     continue;
5202                 else
5203                 {
5204                     mbPresObj = sal_False;
5205                     mType = "drawing.Text";
5206                     ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
5207                 }
5208             }
5209             else if ( mType == "presentation.DateTime" )
5210             {
5211                 if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERDATE ) )
5212                     continue;
5213                 else
5214                 {
5215                     mbPresObj = sal_False;
5216                     mType = "drawing.Text";
5217                     ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
5218                 }
5219             }
5220             else if ( mType == "presentation.SlideNumber" )
5221             {
5222                 if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERSLIDENUMBER ) )
5223                     continue;
5224                 else
5225                 {
5226                     mbPresObj = sal_False;
5227                     mType = "drawing.Text";
5228                     ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
5229                 }
5230             }
5231             else if ( ( (sal_Char)'3' == mType.GetChar( 8 ) ) && ( (char)'D' == mType.GetChar( 9 ) ) )  // drawing.3D
5232             {
5233                 // SceneObject, CubeObject, SphereObject, LatheObject, ExtrudeObject, PolygonObject
5234                 if ( !ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ) ) )
5235                     continue;
5236 
5237                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
5238                 ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer );
5239 
5240                 if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ), sal_False ) )
5241                     aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
5242             }
5243             else if ( mType == "drawing.Media" )
5244             {
5245                 mnAngle = 0;
5246                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
5247                 ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer );
5248                 if ( aPropOpt.CreateMediaGraphicProperties( mXShape ) )
5249                     aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
5250                 ::com::sun::star::uno::Any aAny;
5251                 if ( PropValue::GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MediaURL" ) ), sal_True ) )
5252                 {
5253                     rtl::OUString aMediaURL;
5254                     if ( (aAny >>= aMediaURL ) &&  aMediaURL.getLength() )
5255                     {
5256                         // SJ: creating the Media RefObj
5257                         sal_uInt32 nRefId = ++mnExEmbed;
5258 
5259                         *mpExEmbed  << (sal_uInt16)0xf
5260                                     << (sal_uInt16)EPP_ExMCIMovie       // PPT_PST_ExAviMovie
5261                                     << (sal_uInt32)0;
5262                         sal_uInt32 nSize, nStart = mpExEmbed->Tell();
5263                         *mpExEmbed  << (sal_uInt16)0
5264                                     << (sal_uInt16)EPP_ExObjRefAtom
5265                                     << (sal_uInt32)4
5266                                     << nRefId;
5267                         *mpExEmbed  << (sal_uInt16)0xf
5268                                     << (sal_uInt16)EPP_ExVideo
5269                                     << (sal_uInt32)0;
5270 
5271                         *mpExEmbed  << (sal_uInt16)0
5272                                     << (sal_uInt16)EPP_ExMediaAtom
5273                                     << (sal_uInt32)8
5274                                     << nRefId
5275                                     << (sal_uInt16)0
5276                                     << (sal_uInt16)0x435;
5277 
5278 
5279                         sal_uInt16 i, nStringLen = (sal_uInt16)aMediaURL.getLength();
5280                         *mpExEmbed << (sal_uInt32)( EPP_CString << 16 ) << (sal_uInt32)( nStringLen * 2 );
5281                         for ( i = 0; i < nStringLen; i++ )
5282                         {
5283                             sal_Unicode nChar = aMediaURL[ i ];
5284                             *mpExEmbed << nChar;
5285                         }
5286                         nSize = mpExEmbed->Tell() - nStart;
5287                         mpExEmbed->SeekRel( - ( (sal_Int32)nSize + 4 ) );
5288                         *mpExEmbed << nSize;    // size of PPT_PST_ExMCIMovie
5289                         mpExEmbed->SeekRel( 0x10 );
5290                         nSize -= 20;
5291                         *mpExEmbed << nSize;    // PPT_PST_ExMediaAtom
5292                         mpExEmbed->SeekRel( nSize );
5293 
5294                         if ( !pClientData )
5295                             pClientData = new SvMemoryStream( 0x200, 0x200 );
5296                         *pClientData << (sal_uInt16)0
5297                                      << (sal_uInt16)EPP_ExObjRefAtom
5298                                      << (sal_uInt32)4
5299                                      << nRefId;
5300                         // write EPP_InteractiveInfo container for no_action
5301                         *pClientData << (sal_uInt32)( ( EPP_InteractiveInfo << 16 ) | 0xf ) << (sal_uInt32)24;
5302                         *pClientData << (sal_uInt16)0
5303                                      << (sal_uInt16)EPP_InteractiveInfoAtom
5304                                      << (sal_uInt32)16
5305                                      << (sal_uInt32) 0
5306                                      << (sal_uInt32) 0
5307                                      << (sal_uInt8) 6
5308                                      << (sal_uInt8) 0
5309                                      << (sal_uInt8) 0
5310                                      << (sal_uInt8) 0
5311                                      << (sal_uInt32) 0;
5312                     }
5313                 }
5314             }
5315             else if ( (mType == "drawing.Table") || (mType == "presentation.Table") )
5316             {
5317                 SvMemoryStream* pTmp = NULL;
5318                 if ( bEffect && !mbUseNewAnimations )
5319                 {
5320                     pTmp = new SvMemoryStream( 0x200, 0x200 );
5321                     ImplWriteObjectEffect( *pTmp, eAe, eTe, ++nEffectCount );
5322                 }
5323                 if ( eCa != ::com::sun::star::presentation::ClickAction_NONE )
5324                 {
5325                     if ( !pTmp )
5326                         pTmp = new SvMemoryStream( 0x200, 0x200 );
5327                     ImplWriteClickAction( *pTmp, eCa, bMediaClickAction );
5328                 }
5329                 ImplCreateTable( mXShape, aSolverContainer, aPropOpt );
5330                 continue;
5331             }
5332             else if ( mType == "drawing.dontknow" )
5333             {
5334                 mnAngle = 0;
5335                 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
5336                 ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer );
5337                 if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False ) )
5338                     aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
5339             }
5340             else
5341             {
5342                 continue;
5343             }
5344             sal_Int32 nPlacementID = -1;
5345 
5346             sal_Bool bClientData = ( bEffect || ( eCa != ::com::sun::star::presentation::ClickAction_NONE ) ||
5347                                         nPlaceHolderAtom || nOlePictureId );
5348             if ( bClientData )
5349             {
5350                 if ( nPlaceHolderAtom )
5351                 {
5352                     if ( ( mnTextStyle == EPP_TEXTSTYLE_TITLE ) || ( mnTextStyle == EPP_TEXTSTYLE_BODY ) )
5353                         nPlacementID = nIndices++;
5354                     else
5355                     {
5356                         switch ( nPlaceHolderAtom )
5357                         {
5358                             default :
5359                             {
5360                                 if ( nPlaceHolderAtom < 19 )
5361                                     break;
5362                             }
5363                             case EPP_PLACEHOLDER_NOTESBODY :
5364                             case EPP_PLACEHOLDER_MASTERDATE :
5365                             case EPP_PLACEHOLDER_NOTESSLIDEIMAGE :
5366                             case EPP_PLACEHOLDER_MASTERNOTESBODYIMAGE :
5367                                 nPlacementID = nIndices++;
5368                         }
5369                     }
5370                     if ( !pClientData )
5371                         pClientData = new SvMemoryStream( 0x200, 0x200 );
5372 
5373                     *pClientData << (sal_uInt32)( EPP_OEPlaceholderAtom << 16 ) << (sal_uInt32)8
5374                                  << nPlacementID                // PlacementID
5375                                  << (sal_uInt8)nPlaceHolderAtom // PlaceHolderID
5376                                  << (sal_uInt8)0                // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER )
5377                                  << (sal_uInt16)0;              // padword
5378                 }
5379                 if ( nOlePictureId )
5380                 {
5381                     if ( !pClientData )
5382                         pClientData = new SvMemoryStream( 0x200, 0x200 );
5383 
5384                     *pClientData << (sal_uInt32)( EPP_ExObjRefAtom << 16 ) << (sal_uInt32)4
5385                                  << nOlePictureId;
5386                     nOlePictureId = 0;
5387                 }
5388                 if ( bEffect )
5389                 {
5390                     if ( !pClientData )
5391                         pClientData = new SvMemoryStream( 0x200, 0x200 );
5392 
5393                     // check if it is sensible to replace the object effect with text effect,
5394                     // because in Impress there is the possibility to use a compound effect,
5395                     // e.g. the object effect is an AnimationEffect_FADE_FROM_LEFT and the
5396                     // text effect is a AnimationEffect_FADE_FROM_TOP, in PowerPoint there
5397                     // can be used only one effect
5398                     if ( mnTextSize && ( eTe != ::com::sun::star::presentation::AnimationEffect_NONE )
5399                         && ( eAe != ::com::sun::star::presentation::AnimationEffect_NONE )
5400                             && ( eTe != eAe ) )
5401                     {
5402                         sal_uInt32 nFillStyleFlags, nLineStyleFlags;
5403                         if ( aPropOpt.GetOpt( ESCHER_Prop_fNoFillHitTest, nFillStyleFlags )
5404                             && aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineStyleFlags ) )
5405                         {
5406                             // there is no fillstyle and also no linestyle
5407                             if ( ! ( ( nFillStyleFlags & 0x10 ) + ( nLineStyleFlags & 9 ) ) )
5408                                 eAe = eTe;
5409                         }
5410                     }
5411                     if ( !mbUseNewAnimations  )
5412                         ImplWriteObjectEffect( *pClientData, eAe, eTe, ++nEffectCount );
5413                 }
5414 
5415                 if ( eCa != ::com::sun::star::presentation::ClickAction_NONE )
5416                 {
5417                     if ( !pClientData )
5418                         pClientData = new SvMemoryStream( 0x200, 0x200 );
5419                     ImplWriteClickAction( *pClientData, eCa, bMediaClickAction );
5420                 }
5421             }
5422             if ( ( mnTextStyle == EPP_TEXTSTYLE_TITLE ) || ( mnTextStyle == EPP_TEXTSTYLE_BODY ) )
5423             {
5424                 if ( !pClientTextBox )
5425                     pClientTextBox = new SvMemoryStream( 0x200, 0x200 );
5426 
5427                 if ( mbEmptyPresObj == sal_False )
5428                 {
5429                     if ( ( ePageType == NORMAL ) && ( bMasterPage == sal_False ) )
5430                     {
5431                         sal_uInt32 nTextType = EPP_TEXTTYPE_Body;
5432                         if ( mnTextStyle == EPP_TEXTSTYLE_BODY )
5433                         {
5434                             if ( bSecOutl )
5435                                 nTextType = EPP_TEXTTYPE_HalfBody;
5436                             else if ( mType == "presentation.Subtitle" )
5437                                 nTextType = EPP_TEXTTYPE_CenterBody;
5438                             bSecOutl = sal_True;
5439                         }
5440                         else
5441                             nTextType = EPP_TEXTTYPE_Title;
5442 
5443                         TextRuleEntry aTextRule( nPageNumber );
5444                         SvMemoryStream aExtBu( 0x200, 0x200 );
5445                         ImplGetText();
5446                         ImplWriteTextStyleAtom( *pClientTextBox, nTextType, nPObjects, &aTextRule, aExtBu, NULL );
5447                         ImplWriteExtParaHeader( aExtBu, nPObjects++, nTextType, nPageNumber + 0x100 );
5448                         SvMemoryStream* pOut = aTextRule.pOut;
5449                         if ( pOut )
5450                         {
5451                             pClientTextBox->Write( pOut->GetData(), pOut->Tell() );
5452                             delete pOut, aTextRule.pOut = NULL;
5453                         }
5454                         if ( aExtBu.Tell() )
5455                         {
5456                             if ( !pClientData )
5457                                 pClientData = new SvMemoryStream( 0x200, 0x200 );
5458                             ImplProgTagContainer( pClientData, &aExtBu );
5459                         }
5460                     }
5461                 }
5462             }
5463             else
5464             {
5465                 if ( !aPropOpt.IsFontWork() )
5466                 {
5467                     if ( mnTextSize || ( nPlaceHolderAtom == EPP_PLACEHOLDER_MASTERDATE ) || ( nPlaceHolderAtom == EPP_PLACEHOLDER_NOTESBODY ) )
5468                     {
5469                         int nInstance2;
5470                         if ( ( nPlaceHolderAtom == EPP_PLACEHOLDER_MASTERDATE ) || ( nPlaceHolderAtom == EPP_PLACEHOLDER_NOTESBODY ) )
5471                             nInstance2 = 2;
5472                         else
5473                             nInstance2 = EPP_TEXTTYPE_Other;     // Text in a Shape
5474 
5475                         if ( !pClientTextBox )
5476                             pClientTextBox = new SvMemoryStream( 0x200, 0x200 );
5477 
5478                         SvMemoryStream  aExtBu( 0x200, 0x200 );
5479                         ImplWriteTextStyleAtom( *pClientTextBox, nInstance2, 0, NULL, aExtBu, &aPropOpt );
5480                         if ( aExtBu.Tell() )
5481                         {
5482                             if ( !pClientData )
5483                                 pClientData = new SvMemoryStream( 0x200, 0x200 );
5484                             ImplProgTagContainer( pClientData, &aExtBu );
5485                         }
5486                     }
5487                     else if ( nPlaceHolderAtom >= 19 )
5488                     {
5489                         if ( !pClientTextBox )
5490                             pClientTextBox = new SvMemoryStream( 12 );
5491 
5492                         *pClientTextBox << (sal_uInt32)( EPP_TextHeaderAtom << 16 ) << (sal_uInt32)4
5493                                         << (sal_uInt32)7;
5494                     }
5495                 }
5496             }
5497 
5498             aPropOpt.CreateShadowProperties( mXPropSet );
5499             maRect.Justify();
5500             if ( mnAngle )
5501                 ImplFlipBoundingBox( aPropOpt );
5502             aPropOpt.CreateShapeProperties( mXShape );
5503             aPropOpt.Commit( *mpStrm );
5504             if ( GetCurrentGroupLevel() > 0 )
5505                 mpPptEscherEx->AddChildAnchor( maRect );
5506             else
5507                 mpPptEscherEx->AddClientAnchor( maRect );
5508 
5509             if ( pClientData )
5510             {
5511                 *mpStrm << (sal_uInt32)( ( ESCHER_ClientData << 16 ) | 0xf )
5512                         << (sal_uInt32)pClientData->Tell();
5513 
5514                 mpStrm->Write( pClientData->GetData(), pClientData->Tell() );
5515                 delete pClientData, pClientData = NULL;
5516             }
5517             if ( pClientTextBox )
5518             {
5519                 *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf )
5520                         << (sal_uInt32)pClientTextBox->Tell();
5521 
5522                 mpStrm->Write( pClientTextBox->GetData(), pClientTextBox->Tell() );
5523                 delete pClientTextBox, pClientTextBox = NULL;
5524             }
5525             mpPptEscherEx->CloseContainer();      // ESCHER_SpContainer
5526         }
5527         nPrevTextStyle = mnTextStyle;
5528 
5529         if ( bAdditionalText )
5530         {
5531             bAdditionalText = sal_False;
5532 
5533             ::com::sun::star::uno::Any  aAny;
5534             EscherPropertyContainer     aPropOpt;
5535             mnAngle = ( PropValue::GetPropertyValue( aAny,
5536                 mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True ) )
5537                     ? *((sal_Int32*)aAny.getValue() )
5538                     : 0;
5539 
5540             aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 );
5541             aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
5542             if ( mType == "drawing.Line" )
5543             {
5544                 double fDist = hypot( maRect.GetWidth(), maRect.GetHeight() );
5545                 maRect = Rectangle( Point( aTextRefPoint.X, aTextRefPoint.Y ),
5546                                         Point( (sal_Int32)( aTextRefPoint.X + fDist ), aTextRefPoint.Y - 1 ) );
5547                 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_False );
5548                 aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x60006 );        // Size Shape To Fit Text
5549                 if ( mnAngle < 0 )
5550                     mnAngle = ( 36000 + mnAngle ) % 36000;
5551                 if ( mnAngle )
5552                     ImplFlipBoundingBox( aPropOpt );
5553             }
5554             else
5555             {
5556                 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_False );
5557                 if ( mnAngle < 0 )
5558                     mnAngle = ( 36000 + mnAngle ) % 36000;
5559                 else
5560                     mnAngle = ( 36000 - ( mnAngle % 36000 ) );
5561 
5562                 mnAngle *= 655;
5563                 mnAngle += 0x8000;
5564                 mnAngle &=~0xffff;  // nAngle auf volle Gradzahl runden
5565                 aPropOpt.AddOpt( ESCHER_Prop_Rotation, mnAngle );
5566 
5567                 // #119551# PPT does not support groups of polygons and text (MS patch KB2289187)
5568                 // mpPptEscherEx->SetGroupSnapRect( nGroupLevel, maRect );
5569                 // mpPptEscherEx->SetGroupLogicRect( nGroupLevel, maRect );
5570             }
5571             if ( !pClientTextBox )
5572                 pClientTextBox = new SvMemoryStream( 0x200, 0x200 );
5573 
5574             SvMemoryStream  aExtBu( 0x200, 0x200 );
5575             ImplWriteTextStyleAtom( *pClientTextBox, EPP_TEXTTYPE_Other, 0, NULL, aExtBu, &aPropOpt );
5576 
5577             aPropOpt.CreateShapeProperties( mXShape );
5578             aPropOpt.Commit( *mpStrm );
5579             if ( GetCurrentGroupLevel() > 0 )
5580                 mpPptEscherEx->AddChildAnchor( maRect );
5581             else
5582                 mpPptEscherEx->AddClientAnchor( maRect );
5583 
5584             *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf )
5585                     << (sal_uInt32)pClientTextBox->Tell();
5586 
5587             mpStrm->Write( pClientTextBox->GetData(), pClientTextBox->Tell() );
5588             delete pClientTextBox, pClientTextBox = NULL;
5589 
5590             mpPptEscherEx->CloseContainer();  // ESCHER_SpContainer
5591 
5592             // #119551# PPT does not support groups of polygons and text (MS patch KB2289187)
5593             // mpPptEscherEx->LeaveGroup();
5594         }
5595     }
5596     ClearGroupTable();                              // gruppierungen wegschreiben, sofern noch irgendwelche offen sind, was eigendlich nicht sein sollte
5597     nGroups = GetGroupsClosed();
5598     for ( sal_uInt32 i = 0; i < nGroups; i++, mpPptEscherEx->LeaveGroup() ) ;
5599     mnPagesWritten++;
5600 }
5601 
5602 //  -----------------------------------------------------------------------
5603 
ImplMapPoint(const::com::sun::star::awt::Point & rPoint)5604 ::com::sun::star::awt::Point PPTWriter::ImplMapPoint( const ::com::sun::star::awt::Point& rPoint )
5605 {
5606     Point aRet( OutputDevice::LogicToLogic( Point( rPoint.X, rPoint.Y ), maMapModeSrc, maMapModeDest ) );
5607     return ::com::sun::star::awt::Point( aRet.X(), aRet.Y() );
5608 }
5609 
5610 //  -----------------------------------------------------------------------
5611 
ImplMapSize(const::com::sun::star::awt::Size & rSize)5612 ::com::sun::star::awt::Size PPTWriter::ImplMapSize( const ::com::sun::star::awt::Size& rSize )
5613 {
5614     Size aRetSize( OutputDevice::LogicToLogic( Size( rSize.Width, rSize.Height ), maMapModeSrc, maMapModeDest ) );
5615 
5616     if ( !aRetSize.Width() )
5617         aRetSize.Width()++;
5618     if ( !aRetSize.Height() )
5619         aRetSize.Height()++;
5620     return ::com::sun::star::awt::Size( aRetSize.Width(), aRetSize.Height() );
5621 }
5622 
5623 //  -----------------------------------------------------------------------
5624 
ImplMapRectangle(const::com::sun::star::awt::Rectangle & rRect)5625 Rectangle PPTWriter::ImplMapRectangle( const ::com::sun::star::awt::Rectangle& rRect )
5626 {
5627     ::com::sun::star::awt::Point    aPoint( rRect.X, rRect.Y );
5628     ::com::sun::star::awt::Size     aSize( rRect.Width, rRect.Height );
5629     ::com::sun::star::awt::Point    aP( ImplMapPoint( aPoint ) );
5630     ::com::sun::star::awt::Size     aS( ImplMapSize( aSize ) );
5631     return Rectangle( Point( aP.X, aP.Y ), Size( aS.Width, aS.Height ) );
5632 }
5633 
5634 //  -----------------------------------------------------------------------
5635 
5636 struct CellBorder
5637 {
5638     sal_Int32                       mnPos;      // specifies the distance to the top/left position of the table
5639     sal_Int32                       mnLength;
5640     table::BorderLine               maCellBorder;
5641 
CellBorderCellBorder5642     CellBorder() : mnPos ( 0 ), mnLength( 0 ){};
5643 };
5644 
ImplCreateCellBorder(const CellBorder * pCellBorder,sal_Int32 nX1,sal_Int32 nY1,sal_Int32 nX2,sal_Int32 nY2)5645 sal_Bool PPTWriter::ImplCreateCellBorder( const CellBorder* pCellBorder, sal_Int32 nX1, sal_Int32 nY1, sal_Int32 nX2, sal_Int32 nY2)
5646 {
5647     sal_Int32 nLineWidth = pCellBorder->maCellBorder.OuterLineWidth + pCellBorder->maCellBorder.InnerLineWidth;
5648     if ( nLineWidth )
5649     {
5650         nLineWidth *= 2;
5651         mnAngle = 0;
5652         mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
5653         EscherPropertyContainer aPropOptSp;
5654 
5655         sal_uInt32 nId = mpPptEscherEx->GenerateShapeId();
5656         mpPptEscherEx->AddShape( ESCHER_ShpInst_Line, 0xa02, nId );
5657         aPropOptSp.AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex );
5658         aPropOptSp.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0xa0008 );
5659         aPropOptSp.AddOpt( ESCHER_Prop_fshadowObscured, 0x20000 );
5660 
5661         sal_uInt32 nBorderColor = pCellBorder->maCellBorder.Color & 0xff00;                 // green
5662         nBorderColor |= static_cast< sal_uInt8 >( pCellBorder->maCellBorder.Color ) << 16;  // red
5663         nBorderColor |= static_cast< sal_uInt8 >( pCellBorder->maCellBorder.Color >> 16 );  // blue
5664         aPropOptSp.AddOpt( ESCHER_Prop_lineColor, nBorderColor );
5665 
5666         aPropOptSp.AddOpt( ESCHER_Prop_lineWidth, nLineWidth * 360 );
5667         aPropOptSp.AddOpt( ESCHER_Prop_fc3DLightFace, 0x80000 );
5668         aPropOptSp.Commit( *mpStrm );
5669         mpPptEscherEx->AddAtom( 16, ESCHER_ChildAnchor );
5670         *mpStrm     << nX1
5671                     << nY1
5672                     << nX2
5673                     << nY2;
5674         mpPptEscherEx->CloseContainer();
5675         return sal_True;
5676     }
5677     return sal_False;
5678 }
5679 
5680 //get merged cell's width
GetCellRight(sal_Int32 nColumn,Rectangle & rect,std::vector<std::pair<sal_Int32,sal_Int32>> & aColumns,uno::Reference<table::XMergeableCell> & xCell)5681 sal_Int32 GetCellRight( sal_Int32 nColumn,
5682     Rectangle& rect,
5683     std::vector< std::pair< sal_Int32, sal_Int32 > >& aColumns,
5684     uno::Reference< table::XMergeableCell >& xCell )
5685 {
5686     sal_Int32 nRight = aColumns[ nColumn ].first + aColumns[ nColumn ].second;
5687     for ( sal_Int32 nColumnSpan = 1; nColumnSpan < xCell->getColumnSpan(); nColumnSpan++ )
5688     {
5689         sal_uInt32 nC = nColumnSpan + nColumn;
5690         if ( nC < aColumns.size() )
5691             nRight += aColumns[ nC ].second;
5692         else
5693             nRight = rect.Right();
5694     }
5695     return nRight;
5696 }
5697 //get merged cell's height
GetCellBottom(sal_Int32 nRow,Rectangle & rect,std::vector<std::pair<sal_Int32,sal_Int32>> & aRows,uno::Reference<table::XMergeableCell> & xCell)5698 sal_Int32 GetCellBottom( sal_Int32 nRow,
5699     Rectangle& rect,
5700     std::vector< std::pair< sal_Int32, sal_Int32 > >& aRows,
5701     uno::Reference< table::XMergeableCell >& xCell )
5702 {
5703     sal_Int32 nBottom = aRows[nRow].first + aRows[nRow].second;
5704     for ( sal_Int32 nRowSpan = 1; nRowSpan < xCell->getRowSpan(); nRowSpan++ )
5705     {
5706         sal_uInt32 nR = nRowSpan + nRow;
5707         if ( nR < aRows.size() )
5708             nBottom += aRows[ nR ].second;
5709         else
5710             nBottom = rect.Bottom();
5711     }
5712     return nBottom;
5713 }
5714 
WriteCString(SvStream & rSt,const String & rString,sal_uInt32 nInstance)5715 void PPTWriter::WriteCString( SvStream& rSt, const String& rString, sal_uInt32 nInstance )
5716 {
5717     sal_uInt32 i, nLen = rString.Len();
5718     if ( nLen )
5719     {
5720         rSt << (sal_uInt32)( ( nInstance << 4 ) | ( EPP_CString << 16 ) )
5721             << (sal_uInt32)( nLen << 1 );
5722         for ( i = 0; i < nLen; i++ )
5723             rSt << rString.GetChar( (sal_uInt16)i );
5724     }
5725 }
5726 
ImplCreateTable(uno::Reference<drawing::XShape> & rXShape,EscherSolverContainer & aSolverContainer,EscherPropertyContainer & aPropOpt)5727 void PPTWriter::ImplCreateTable( uno::Reference< drawing::XShape >& rXShape, EscherSolverContainer& aSolverContainer,
5728                                 EscherPropertyContainer& aPropOpt )
5729 {
5730     try
5731     {
5732         static const rtl::OUString  sModel( RTL_CONSTASCII_USTRINGPARAM ( "Model" ) );
5733         static const rtl::OUString sWidth( RTL_CONSTASCII_USTRINGPARAM ( "Width" ) );
5734         static const rtl::OUString sHeight( RTL_CONSTASCII_USTRINGPARAM ( "Height" ) );
5735 
5736         uno::Reference< table::XTable > xTable;
5737         if ( mXPropSet->getPropertyValue( sModel ) >>= xTable )
5738         {
5739             uno::Reference< table::XColumnRowRange > xColumnRowRange( xTable, uno::UNO_QUERY_THROW );
5740             uno::Reference< container::XIndexAccess > xColumns( xColumnRowRange->getColumns(), uno::UNO_QUERY_THROW );
5741             uno::Reference< container::XIndexAccess > xRows( xColumnRowRange->getRows(), uno::UNO_QUERY_THROW );
5742             sal_uInt16 nRowCount = static_cast< sal_uInt16 >( xRows->getCount() );
5743             sal_uInt16 nColumnCount = static_cast< sal_uInt16 >( xColumns->getCount() );
5744 
5745             std::vector< std::pair< sal_Int32, sal_Int32 > > aColumns;
5746             std::vector< std::pair< sal_Int32, sal_Int32 > > aRows;
5747 
5748             awt::Point aPosition( ImplMapPoint( rXShape->getPosition() ) );
5749             sal_Int32 nPosition = aPosition.X;
5750             for ( sal_Int32 x = 0; x < nColumnCount; x++ )
5751             {
5752                 uno::Reference< beans::XPropertySet > xPropSet( xColumns->getByIndex( x ), uno::UNO_QUERY_THROW );
5753                 awt::Size aS( 0, 0 );
5754                 xPropSet->getPropertyValue( sWidth ) >>= aS.Width;
5755                 awt::Size aM( ImplMapSize( aS ) );
5756                 aColumns.push_back( std::pair< sal_Int32, sal_Int32 >( nPosition, aM.Width ) );
5757                 nPosition += aM.Width;
5758                 if ( x == nColumnCount - 1  && nPosition != maRect.Right() )
5759                     maRect.Right() = nPosition;
5760             }
5761 
5762             nPosition = aPosition.Y;
5763             for ( sal_Int32 y = 0; y < nRowCount; y++ )
5764             {
5765                 uno::Reference< beans::XPropertySet > xPropSet( xRows->getByIndex( y ), uno::UNO_QUERY_THROW );
5766                 awt::Size aS( 0, 0 );
5767                 xPropSet->getPropertyValue( sHeight ) >>= aS.Height;
5768                 awt::Size aM( ImplMapSize( aS ) );
5769                 aRows.push_back( std::pair< sal_Int32, sal_Int32 >( nPosition, aM.Height ) );
5770                 nPosition += aM.Height;
5771                 if ( y == nRowCount - 1 && nPosition != maRect.Bottom())
5772                     maRect.Bottom() = nPosition;
5773             }
5774             mpPptEscherEx->OpenContainer( ESCHER_SpgrContainer );
5775             mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
5776             mpPptEscherEx->AddAtom( 16, ESCHER_Spgr, 1 );
5777             *mpStrm     << (sal_Int32)maRect.Left() // Bounding box fuer die Gruppierten shapes an die sie attached werden
5778                         << (sal_Int32)maRect.Top()
5779                         << (sal_Int32)maRect.Right()
5780                         << (sal_Int32)maRect.Bottom();
5781 
5782             sal_uInt32 nShapeId = mpPptEscherEx->GenerateShapeId();
5783             mpPptEscherEx->AddShape( ESCHER_ShpInst_Min, 0x201, nShapeId );     // Flags: Group | Patriarch
5784             aSolverContainer.AddShape( rXShape, nShapeId );
5785             EscherPropertyContainer aPropOpt2;
5786 
5787             if ( nRowCount )
5788             {
5789                 SvMemoryStream aMemStrm;
5790                 aMemStrm.ObjectOwnsMemory( sal_False );
5791                 aMemStrm << nRowCount
5792                          << nRowCount
5793                          << (sal_uInt16)4;
5794 
5795                 std::vector< std::pair< sal_Int32, sal_Int32 > >::const_iterator aIter( aRows.begin() );
5796                 while( aIter != aRows.end() )
5797                     aMemStrm << (*aIter++).second;
5798 
5799                 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x1000100 );
5800                 aPropOpt2.AddOpt( ESCHER_Prop_tableProperties, 1 );
5801                 aPropOpt2.AddOpt( ESCHER_Prop_tableRowProperties, sal_True, aMemStrm.Tell(), static_cast< sal_uInt8* >( const_cast< void* >( aMemStrm.GetData() ) ), aMemStrm.Tell() );
5802                 aPropOpt.CreateShapeProperties( rXShape );
5803                 aPropOpt.Commit( *mpStrm );
5804                 aPropOpt2.Commit( *mpStrm, 3, ESCHER_UDefProp );
5805                 if ( GetCurrentGroupLevel() > 0 )
5806                     mpPptEscherEx->AddChildAnchor( maRect );
5807                 else
5808                     mpPptEscherEx->AddClientAnchor( maRect );
5809                 mpPptEscherEx->CloseContainer();
5810 
5811 
5812                 uno::Reference< table::XCellRange > xCellRange( xTable, uno::UNO_QUERY_THROW );
5813                 for( sal_Int32 nRow = 0; nRow < xRows->getCount(); nRow++ )
5814                 {
5815                     for( sal_Int32 nColumn = 0; nColumn < xColumns->getCount(); nColumn++ )
5816                     {
5817                         uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nColumn, nRow ), uno::UNO_QUERY_THROW );
5818                         if ( !xCell->isMerged() )
5819                         {
5820                             sal_Int32 nLeft   = aColumns[ nColumn ].first;
5821                             sal_Int32 nTop    = aRows[ nRow ].first;
5822                             sal_Int32 nRight  = GetCellRight( nColumn, maRect,aColumns,xCell );
5823                             sal_Int32 nBottom = GetCellBottom( nRow,  maRect,aRows,xCell );
5824 
5825                             mbFontIndependentLineSpacing = sal_False;
5826                             mXPropSet = uno::Reference< beans::XPropertySet >( xCell, uno::UNO_QUERY_THROW );
5827                             mXText = uno::Reference< text::XSimpleText >( xCell, uno::UNO_QUERY_THROW );
5828                             mnTextSize = mXText->getString().getLength();
5829 
5830                             ::com::sun::star::uno::Any aAny;
5831                             if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FontIndependentLineSpacing" ) ) ), sal_True )
5832                                 aAny >>= mbFontIndependentLineSpacing;
5833 
5834                             EscherPropertyContainer aPropOptSp;
5835                             mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
5836                             ImplCreateShape( ESCHER_ShpInst_Rectangle, 0xa02, aSolverContainer );          // Flags: Connector | HasSpt | Child
5837                             aPropOptSp.CreateFillProperties( mXPropSet, sal_True );
5838                             aPropOptSp.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 );
5839                             aPropOptSp.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
5840                             aPropOptSp.AddOpt( ESCHER_Prop_WrapText, ESCHER_WrapSquare );
5841 
5842                             SvMemoryStream aClientTextBox( 0x200, 0x200 );
5843                             SvMemoryStream  aExtBu( 0x200, 0x200 );
5844 
5845                             ImplWriteTextStyleAtom( aClientTextBox, EPP_TEXTTYPE_Other, 0, NULL, aExtBu, &aPropOptSp );
5846 
5847                             // need write client data for extend bullet
5848                             if ( aExtBu.Tell() )
5849                             {
5850                                 SvMemoryStream* pClientData = new SvMemoryStream( 0x200, 0x200 );
5851                                 ImplProgTagContainer( pClientData, &aExtBu );
5852                                 *mpStrm << (sal_uInt32)( ( ESCHER_ClientData << 16 ) | 0xf )
5853                                     << (sal_uInt32)pClientData->Tell();
5854 
5855                                 mpStrm->Write( pClientData->GetData(), pClientData->Tell() );
5856                                 delete pClientData, pClientData = NULL;
5857                             }
5858 
5859                             aPropOptSp.Commit( *mpStrm );
5860                             mpPptEscherEx->AddAtom( 16, ESCHER_ChildAnchor );
5861                             *mpStrm     << nLeft
5862                                 << nTop
5863                                 << nRight
5864                                 << nBottom;
5865 
5866                             *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf )
5867                                 << (sal_uInt32)aClientTextBox.Tell();
5868 
5869                             mpStrm->Write( aClientTextBox.GetData(), aClientTextBox.Tell() );
5870                             mpPptEscherEx->CloseContainer();
5871                         }
5872                     }
5873                 }
5874 
5875                 static const rtl::OUString sTopBorder( String( RTL_CONSTASCII_USTRINGPARAM( "TopBorder" ) ) );
5876                 static const rtl::OUString sBottomBorder( String( RTL_CONSTASCII_USTRINGPARAM( "BottomBorder" ) ) );
5877                 static const rtl::OUString sLeftBorder( String( RTL_CONSTASCII_USTRINGPARAM( "LeftBorder" ) ) );
5878                 static const rtl::OUString sRightBorder( String( RTL_CONSTASCII_USTRINGPARAM( "RightBorder" ) ) );
5879                 static const rtl::OUString  sDiagonalTLBR( RTL_CONSTASCII_USTRINGPARAM ( "DiagonalTLBR" ) );
5880                 static const rtl::OUString  sDiagonalBLTR( RTL_CONSTASCII_USTRINGPARAM ( "DiagonalBLTR" ) );
5881 
5882                 // creating horz lines
5883                 for( sal_Int32 nLine = 0; nLine < ( xRows->getCount() + 1 ); nLine++ )
5884                 {
5885                     for( sal_Int32 nColumn = 0; nColumn < xColumns->getCount(); nColumn++ )
5886                     {
5887                         CellBorder aCellBorder;
5888                         aCellBorder.mnPos = aColumns[ nColumn ].first;
5889                         aCellBorder.mnLength = aColumns[ nColumn ].second;
5890                         sal_Bool bTop = sal_False;
5891                         //write nLine*nColumn cell's top border
5892                         if ( nLine < xRows->getCount() )
5893                         {   // top border
5894                             uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nColumn, nLine ), uno::UNO_QUERY_THROW );
5895                             if ( !xCell->isMerged()  )
5896                             {
5897                                 uno::Reference< beans::XPropertySet > xPropSet2( xCell, uno::UNO_QUERY_THROW );
5898                                 table::BorderLine aBorderLine;
5899                                 if ( xPropSet2->getPropertyValue( sTopBorder ) >>= aBorderLine )
5900                                     aCellBorder.maCellBorder = aBorderLine;
5901                                 sal_Int32 nRight  = GetCellRight( nColumn, maRect,aColumns,xCell );
5902                                 bTop = ImplCreateCellBorder( &aCellBorder, aCellBorder.mnPos,
5903                                     aRows[ nLine ].first, nRight,  aRows[ nLine ].first );
5904                             }
5905                         }
5906 
5907                         //if nLine*nColumn cell's top border is empty, check (nLine-1)*nColumn cell's bottom border
5908                         //and write the last row's bottom border
5909                         if (( nLine && !bTop ) || (nLine == xRows->getCount()))
5910                         {   // bottom border
5911                             sal_Int32 nRow =  nLine;
5912 
5913                             while( nRow )
5914                             {   //find last no merged cell
5915                                 uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nColumn, nRow - 1 ), uno::UNO_QUERY_THROW );
5916                                 if ( !xCell->isMerged()  )
5917                                 {
5918                                     sal_Int32 nRight  = GetCellRight( nColumn,  maRect,aColumns,xCell );
5919                                     sal_Int32 nBottom = GetCellBottom( nRow - 1, maRect,aRows,xCell );
5920                                     if ( nBottom == ( aRows[ nLine-1 ].first + aRows[ nLine-1 ].second ) )
5921                                     {
5922                                         uno::Reference< table::XMergeableCell > xCellOwn( xCellRange->getCellByPosition( nColumn, nRow - 1 ), uno::UNO_QUERY_THROW );
5923                                         uno::Reference< beans::XPropertySet > xPropSet2( xCellOwn, uno::UNO_QUERY_THROW );
5924                                         table::BorderLine aBorderLine;
5925                                         if ( xPropSet2->getPropertyValue( sBottomBorder ) >>= aBorderLine )
5926                                             aCellBorder.maCellBorder = aBorderLine;
5927                                         ImplCreateCellBorder( &aCellBorder, aCellBorder.mnPos,
5928                                             nBottom, nRight, nBottom);
5929                                     }
5930                                     nRow=0;
5931                                 }
5932                                 else
5933                                     nRow--;
5934                             }
5935                         }
5936                     }
5937                 }
5938 
5939                 // creating vertical lines
5940                 for( sal_Int32 nLine = 0; nLine < ( xColumns->getCount() + 1 ); nLine++ )
5941                 {
5942                     for( sal_Int32 nRow = 0; nRow < xRows->getCount(); nRow++ )
5943                     {
5944 
5945                         CellBorder aCellBorder;
5946                         aCellBorder.mnPos = aRows[ nRow].first;
5947                         aCellBorder.mnLength = aRows[ nRow].second;
5948                         sal_Bool bLeft = sal_False;
5949                         if ( nLine < xColumns->getCount() )
5950                         {   // left border
5951                             uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nLine, nRow ), uno::UNO_QUERY_THROW );
5952                             if (!xCell->isMerged() )
5953                             {
5954                                 uno::Reference< beans::XPropertySet > xCellSet( xCell, uno::UNO_QUERY_THROW );
5955                                 table::BorderLine aBorderLine;
5956                                 if ( xCellSet->getPropertyValue( sLeftBorder ) >>= aBorderLine )
5957                                     aCellBorder.maCellBorder = aBorderLine;
5958                                 sal_Int32 nBottom = GetCellBottom( nRow, maRect, aRows,xCell );
5959                                 bLeft = ImplCreateCellBorder( &aCellBorder, aColumns[nLine].first, aCellBorder.mnPos,
5960                                     aColumns[nLine].first, nBottom );
5961                             }
5962                         }
5963                         if ( ( nLine && !bLeft )||(nLine == xColumns->getCount()))
5964                         {   // right border
5965                             sal_Int32 nColumn = nLine;
5966                             while ( nColumn )
5967                             {
5968                                 uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nColumn - 1, nRow ), uno::UNO_QUERY_THROW );
5969                                 if (!xCell->isMerged() )
5970                                 {
5971                                     sal_Int32 nRight  = GetCellRight( nColumn-1, maRect, aColumns,xCell );
5972                                     sal_Int32 nBottom = GetCellBottom( nRow,   maRect, aRows, xCell );
5973                                     if ( nRight == (aColumns[nLine-1].first + aColumns[nLine-1].second) )
5974                                     {
5975                                         uno::Reference< table::XMergeableCell > xCellOwn( xCellRange->getCellByPosition( nColumn - 1, nRow ), uno::UNO_QUERY_THROW );
5976                                         uno::Reference< beans::XPropertySet > xCellSet( xCellOwn, uno::UNO_QUERY_THROW );
5977                                         table::BorderLine aBorderLine;
5978                                         if ( xCellSet->getPropertyValue( sRightBorder ) >>= aBorderLine )
5979                                             aCellBorder.maCellBorder = aBorderLine;
5980                                         ImplCreateCellBorder( &aCellBorder, nRight, aCellBorder.mnPos,
5981                                             nRight,  nBottom );
5982                                     }
5983                                     nColumn = 0;
5984                                 }
5985                                 else
5986                                     nColumn --;
5987                             }
5988                         }
5989                     }
5990                 }
5991             }
5992         }
5993     }
5994     catch( uno::Exception& )
5995     {
5996     }
5997     mpPptEscherEx->CloseContainer();
5998 }
5999