merge the formfield patch from ooo-build
[ooovba.git] / sd / source / filter / eppt / escherex.cxx
blob0fdd8c26cb5daa1a3f6e211d414bbdeba9a2c207
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: escherex.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
35 #ifndef _PptEscherEx_HXX
36 #include "escherex.hxx"
37 #endif
39 // ---------------------------------------------------------------------------------------------
40 // ---------------------------------------------------------------------------------------------
41 // ---------------------------------------------------------------------------------------------
43 PptEscherEx::PptEscherEx( SvStream& rOutStrm, UINT32 nDrawings ) :
44 EscherEx ( rOutStrm, nDrawings )
46 mnFIDCLs = nDrawings;
47 mnCurrentDg = 0;
48 mnCurrentShapeID = 0;
49 mnTotalShapesDgg = 0;
50 mnCurrentShapeMaximumID = 0;
53 // ---------------------------------------------------------------------------------------------
55 sal_uInt32 PptEscherEx::DrawingGroupContainerSize()
57 return ImplDggContainerSize() + 8;
60 void PptEscherEx::WriteDrawingGroupContainer( SvStream& rSt )
62 UINT32 nSize = DrawingGroupContainerSize();
63 rSt << (sal_uInt32)( 0xf | ( 1035 << 16 ) ) // EPP_PPDrawingGroup
64 << (sal_uInt32)( nSize - 8 );
66 ImplWriteDggContainer( rSt );
69 // ---------------------------------------------------------------------------------------------
71 sal_uInt32 PptEscherEx::ImplDggContainerSize()
73 UINT32 nSize;
75 nSize = ImplDggAtomSize();
76 nSize += GetBlibStoreContainerSize();
77 nSize += ImplOptAtomSize();
78 nSize += ImplSplitMenuColorsAtomSize();
80 return nSize + 8;
83 void PptEscherEx::ImplWriteDggContainer( SvStream& rSt )
85 sal_uInt32 nSize = ImplDggContainerSize();
86 if ( nSize )
88 rSt << (sal_uInt32)( 0xf | ( ESCHER_DggContainer << 16 ) )
89 << (sal_uInt32)( nSize - 8 );
91 ImplWriteDggAtom( rSt );
92 WriteBlibStoreContainer( rSt );
93 ImplWriteOptAtom( rSt );
94 ImplWriteSplitMenuColorsAtom( rSt );
98 // ---------------------------------------------------------------------------------------------
100 sal_uInt32 PptEscherEx::ImplDggAtomSize()
102 return maFIDCLs.Tell() + 24;
105 void PptEscherEx::ImplWriteDggAtom( SvStream& rSt )
107 sal_uInt32 nSize = ImplDggAtomSize();
108 if ( nSize )
110 rSt << (sal_uInt32)( ESCHER_Dgg << 16 )
111 << (sal_uInt32)( nSize - 8 )
112 << mnCurrentShapeID
113 << (sal_uInt32)( mnFIDCLs + 1 )
114 << mnTotalShapesDgg
115 << mnDrawings;
117 rSt.Write( maFIDCLs.GetData(), nSize - 24 );
121 // ---------------------------------------------------------------------------------------------
123 #define ESCHER_OPT_COUNT 6
125 sal_uInt32 PptEscherEx::ImplOptAtomSize()
127 sal_uInt32 nSize = 0;
128 if ( ESCHER_OPT_COUNT )
129 nSize = ( ESCHER_OPT_COUNT * 6 ) + 8;
130 return nSize;
133 void PptEscherEx::ImplWriteOptAtom( SvStream& rSt )
135 sal_uInt32 nSize = ImplOptAtomSize();
136 if ( nSize )
138 rSt << (sal_uInt32)( ( ESCHER_OPT << 16 ) | ( ESCHER_OPT_COUNT << 4 ) | 0x3 )
139 << (sal_uInt32)( nSize - 8 )
140 << (sal_uInt16)ESCHER_Prop_fillColor << (sal_uInt32)0xffb800
141 << (sal_uInt16)ESCHER_Prop_fillBackColor << (sal_uInt32)0
142 << (sal_uInt16)ESCHER_Prop_fNoFillHitTest << (sal_uInt32)0x00100010
143 << (sal_uInt16)ESCHER_Prop_lineColor << (sal_uInt32)0x8000001
144 << (sal_uInt16)ESCHER_Prop_fNoLineDrawDash << (sal_uInt32)0x00080008
145 << (sal_uInt16)ESCHER_Prop_shadowColor << (sal_uInt32)0x8000002;
149 // ---------------------------------------------------------------------------------------------
151 #define ESCHER_SPLIT_MENU_COLORS_COUNT 4
153 sal_uInt32 PptEscherEx::ImplSplitMenuColorsAtomSize()
155 sal_uInt32 nSize = 0;
156 if ( ESCHER_SPLIT_MENU_COLORS_COUNT )
157 nSize = ( ESCHER_SPLIT_MENU_COLORS_COUNT << 2 ) + 8;
158 return nSize;
161 void PptEscherEx::ImplWriteSplitMenuColorsAtom( SvStream& rSt )
163 UINT32 nSize = ImplSplitMenuColorsAtomSize();
164 if ( nSize )
166 rSt << (sal_uInt32)( ( ESCHER_SplitMenuColors << 16 ) | ( ESCHER_SPLIT_MENU_COLORS_COUNT << 4 ) )
167 << (sal_uInt32)( nSize - 8 )
168 << (sal_uInt32)0x08000004
169 << (sal_uInt32)0x08000001
170 << (sal_uInt32)0x08000002
171 << (sal_uInt32)0x100000f7;
176 // ---------------------------------------------------------------------------------------------
178 PptEscherEx::~PptEscherEx()
182 // ---------------------------------------------------------------------------------------------
184 void PptEscherEx::OpenContainer( UINT16 n_EscherContainer, int nRecInstance )
186 *mpOutStrm << (UINT16)( ( nRecInstance << 4 ) | 0xf ) << n_EscherContainer << (UINT32)0;
187 mOffsets.push_back( mpOutStrm->Tell() - 4 );
188 mRecTypes.push_back( n_EscherContainer );
190 switch( n_EscherContainer )
192 case ESCHER_DgContainer :
194 if ( !mbEscherDg )
196 mbEscherDg = TRUE;
197 mnCurrentDg++;
198 mnTotalShapesDg = 0;
199 mnTotalShapeIdUsedDg = 0;
200 mnCurrentShapeID = ( mnCurrentShapeMaximumID &~0x3ff ) + 0x400; // eine neue Seite bekommt immer eine neue ShapeId die ein vielfaches von 1024 ist,
201 // damit ist erste aktuelle Shape ID 0x400
202 AddAtom( 8, ESCHER_Dg, 0, mnCurrentDg );
203 PtReplaceOrInsert( ESCHER_Persist_Dg | mnCurrentDg, mpOutStrm->Tell() );
204 *mpOutStrm << (UINT32)0 // The number of shapes in this drawing
205 << (UINT32)0; // The last MSOSPID given to an SP in this DG
208 break;
210 case ESCHER_SpgrContainer :
212 if ( mbEscherDg )
214 mbEscherSpgr = TRUE;
217 break;
219 case ESCHER_SpContainer :
222 break;
224 default:
225 break;
229 // ---------------------------------------------------------------------------------------------
231 void PptEscherEx::CloseContainer()
233 /* SJ: #Issue 26747#
234 not creating group objects with a depth higher than 16, because then
235 PPT is having a big performance problem when starting a slide show
237 if ( ( mRecTypes.back() != ESCHER_SpgrContainer ) || ( mnGroupLevel < 12 ) )
239 UINT32 nSize, nPos = mpOutStrm->Tell();
240 nSize = ( nPos - mOffsets.back() ) - 4;
241 mpOutStrm->Seek( mOffsets.back() );
242 *mpOutStrm << nSize;
244 switch( mRecTypes.back() )
246 case ESCHER_DgContainer :
248 if ( mbEscherDg )
250 mbEscherDg = FALSE;
251 if ( DoSeek( ESCHER_Persist_Dg | mnCurrentDg ) )
253 // shapeanzahl des drawings setzen
254 mnTotalShapesDgg += mnTotalShapesDg;
255 *mpOutStrm << mnTotalShapesDg << mnCurrentShapeMaximumID;
257 if ( !mnTotalShapesDg )
259 maFIDCLs << (UINT32)0
260 << (UINT32)0;
262 else
264 if ( mnTotalShapeIdUsedDg )
266 UINT32 i, nFIDCL = ( ( mnTotalShapeIdUsedDg - 1 ) / 0x400 );
267 if ( nFIDCL )
268 mnFIDCLs += nFIDCL;
269 for ( i = 0; i <= nFIDCL; i++ )
271 maFIDCLs << mnCurrentDg; // drawing number
272 if ( i < nFIDCL )
273 maFIDCLs << 0x400;
274 else
276 UINT32 nShapesLeft = mnTotalShapeIdUsedDg % 0x400;
277 if ( !nShapesLeft )
278 nShapesLeft = 0x400; // shape count in this IDCL
279 maFIDCLs << (UINT32)nShapesLeft;
287 break;
289 case ESCHER_SpgrContainer :
291 if ( mbEscherSpgr )
293 mbEscherSpgr = FALSE;
297 break;
299 default:
300 break;
302 mOffsets.pop_back();
303 mRecTypes.pop_back();
304 mpOutStrm->Seek( nPos );
308 // ---------------------------------------------------------------------------------------------
310 sal_uInt32 PptEscherEx::EnterGroup( Rectangle* pBoundRect, SvMemoryStream* pClientData )
312 sal_uInt32 nShapeId = 0;
313 /* SJ: #Issue 26747#
314 not creating group objects with a depth higher than 16, because then
315 PPT is having a big performance problem when starting a slide show
317 if ( mnGroupLevel < 12 )
319 Rectangle aRect;
320 if ( pBoundRect )
321 aRect = *pBoundRect;
323 OpenContainer( ESCHER_SpgrContainer );
324 OpenContainer( ESCHER_SpContainer );
325 AddAtom( 16, ESCHER_Spgr, 1 );
326 PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap | mnGroupLevel, mpOutStrm->Tell() );
327 *mpOutStrm << (INT32)aRect.Left() // Bounding box fuer die Gruppierten shapes an die sie attached werden
328 << (INT32)aRect.Top()
329 << (INT32)aRect.Right()
330 << (INT32)aRect.Bottom();
332 nShapeId = GetShapeID();
333 if ( !mnGroupLevel )
334 AddShape( ESCHER_ShpInst_Min, 5, nShapeId ); // Flags: Group | Patriarch
335 else
337 AddShape( ESCHER_ShpInst_Min, 0x201, nShapeId ); // Flags: Group | HaveAnchor
338 AddAtom( 8, ESCHER_ClientAnchor );
339 PtReplaceOrInsert( ESCHER_Persist_Grouping_Logic | mnGroupLevel, mpOutStrm->Tell() );
340 *mpOutStrm << (INT16)aRect.Top() << (INT16)aRect.Left() << (INT16)aRect.Right() << (INT16)aRect.Bottom();
342 if ( pClientData )
344 pClientData->Seek( STREAM_SEEK_TO_END );
345 sal_uInt32 nSize = pClientData->Tell();
346 if ( nSize )
348 *mpOutStrm << (sal_uInt32)( ( ESCHER_ClientData << 16 ) | 0xf )
349 << nSize;
350 mpOutStrm->Write( pClientData->GetData(), nSize );
353 CloseContainer(); // ESCHER_SpContainer
355 mnGroupLevel++;
356 return nShapeId;
359 // ---------------------------------------------------------------------------------------------