1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: escherex.cxx,v $
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"
39 // ---------------------------------------------------------------------------------------------
40 // ---------------------------------------------------------------------------------------------
41 // ---------------------------------------------------------------------------------------------
43 PptEscherEx::PptEscherEx( SvStream
& rOutStrm
, UINT32 nDrawings
) :
44 EscherEx ( rOutStrm
, nDrawings
)
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()
75 nSize
= ImplDggAtomSize();
76 nSize
+= GetBlibStoreContainerSize();
77 nSize
+= ImplOptAtomSize();
78 nSize
+= ImplSplitMenuColorsAtomSize();
83 void PptEscherEx::ImplWriteDggContainer( SvStream
& rSt
)
85 sal_uInt32 nSize
= ImplDggContainerSize();
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();
110 rSt
<< (sal_uInt32
)( ESCHER_Dgg
<< 16 )
111 << (sal_uInt32
)( nSize
- 8 )
113 << (sal_uInt32
)( mnFIDCLs
+ 1 )
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;
133 void PptEscherEx::ImplWriteOptAtom( SvStream
& rSt
)
135 sal_uInt32 nSize
= ImplOptAtomSize();
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;
161 void PptEscherEx::ImplWriteSplitMenuColorsAtom( SvStream
& rSt
)
163 UINT32 nSize
= ImplSplitMenuColorsAtomSize();
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
:
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
210 case ESCHER_SpgrContainer
:
219 case ESCHER_SpContainer
:
229 // ---------------------------------------------------------------------------------------------
231 void PptEscherEx::CloseContainer()
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() );
244 switch( mRecTypes
.back() )
246 case ESCHER_DgContainer
:
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
264 if ( mnTotalShapeIdUsedDg
)
266 UINT32 i
, nFIDCL
= ( ( mnTotalShapeIdUsedDg
- 1 ) / 0x400 );
269 for ( i
= 0; i
<= nFIDCL
; i
++ )
271 maFIDCLs
<< mnCurrentDg
; // drawing number
276 UINT32 nShapesLeft
= mnTotalShapeIdUsedDg
% 0x400;
278 nShapesLeft
= 0x400; // shape count in this IDCL
279 maFIDCLs
<< (UINT32
)nShapesLeft
;
289 case ESCHER_SpgrContainer
:
293 mbEscherSpgr
= FALSE
;
303 mRecTypes
.pop_back();
304 mpOutStrm
->Seek( nPos
);
308 // ---------------------------------------------------------------------------------------------
310 sal_uInt32
PptEscherEx::EnterGroup( Rectangle
* pBoundRect
, SvMemoryStream
* pClientData
)
312 sal_uInt32 nShapeId
= 0;
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 )
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();
334 AddShape( ESCHER_ShpInst_Min
, 5, nShapeId
); // Flags: Group | Patriarch
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();
344 pClientData
->Seek( STREAM_SEEK_TO_END
);
345 sal_uInt32 nSize
= pClientData
->Tell();
348 *mpOutStrm
<< (sal_uInt32
)( ( ESCHER_ClientData
<< 16 ) | 0xf )
350 mpOutStrm
->Write( pClientData
->GetData(), nSize
);
353 CloseContainer(); // ESCHER_SpContainer
359 // ---------------------------------------------------------------------------------------------