1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "escherex.hxx"
22 // ---------------------------------------------------------------------------------------------
23 // ---------------------------------------------------------------------------------------------
24 // ---------------------------------------------------------------------------------------------
26 PptEscherEx::PptEscherEx( SvStream
& rOutStrm
, const OUString
& rBaseURI
) :
27 EscherEx( EscherExGlobalRef( new EscherExGlobal
), &rOutStrm
)
29 mxGlobal
->SetBaseURI( rBaseURI
);
33 // ---------------------------------------------------------------------------------------------
35 sal_uInt32
PptEscherEx::DrawingGroupContainerSize()
37 return ImplDggContainerSize() + 8;
40 void PptEscherEx::WriteDrawingGroupContainer( SvStream
& rSt
)
42 sal_uInt32 nSize
= DrawingGroupContainerSize();
43 rSt
<< (sal_uInt32
)( 0xf | ( 1035 << 16 ) ) // EPP_PPDrawingGroup
44 << (sal_uInt32
)( nSize
- 8 );
46 ImplWriteDggContainer( rSt
);
49 // ---------------------------------------------------------------------------------------------
51 sal_uInt32
PptEscherEx::ImplDggContainerSize()
55 nSize
= mxGlobal
->GetDggAtomSize();
56 nSize
+= mxGlobal
->GetBlibStoreContainerSize();
57 nSize
+= ImplOptAtomSize();
58 nSize
+= ImplSplitMenuColorsAtomSize();
63 void PptEscherEx::ImplWriteDggContainer( SvStream
& rSt
)
65 sal_uInt32 nSize
= ImplDggContainerSize();
68 rSt
<< (sal_uInt32
)( 0xf | ( ESCHER_DggContainer
<< 16 ) )
69 << (sal_uInt32
)( nSize
- 8 );
71 mxGlobal
->SetDggContainer();
72 mxGlobal
->WriteDggAtom( rSt
);
73 mxGlobal
->WriteBlibStoreContainer( rSt
);
74 ImplWriteOptAtom( rSt
);
75 ImplWriteSplitMenuColorsAtom( rSt
);
79 // ---------------------------------------------------------------------------------------------
81 #define ESCHER_OPT_COUNT 6
83 sal_uInt32
PptEscherEx::ImplOptAtomSize()
86 if ( ESCHER_OPT_COUNT
)
87 nSize
= ( ESCHER_OPT_COUNT
* 6 ) + 8;
91 void PptEscherEx::ImplWriteOptAtom( SvStream
& rSt
)
93 sal_uInt32 nSize
= ImplOptAtomSize();
96 rSt
<< (sal_uInt32
)( ( ESCHER_OPT
<< 16 ) | ( ESCHER_OPT_COUNT
<< 4 ) | 0x3 )
97 << (sal_uInt32
)( nSize
- 8 )
98 << (sal_uInt16
)ESCHER_Prop_fillColor
<< (sal_uInt32
)0xffb800
99 << (sal_uInt16
)ESCHER_Prop_fillBackColor
<< (sal_uInt32
)0
100 << (sal_uInt16
)ESCHER_Prop_fNoFillHitTest
<< (sal_uInt32
)0x00100010
101 << (sal_uInt16
)ESCHER_Prop_lineColor
<< (sal_uInt32
)0x8000001
102 << (sal_uInt16
)ESCHER_Prop_fNoLineDrawDash
<< (sal_uInt32
)0x00080008
103 << (sal_uInt16
)ESCHER_Prop_shadowColor
<< (sal_uInt32
)0x8000002;
107 // ---------------------------------------------------------------------------------------------
109 #define ESCHER_SPLIT_MENU_COLORS_COUNT 4
111 sal_uInt32
PptEscherEx::ImplSplitMenuColorsAtomSize()
113 sal_uInt32 nSize
= 0;
114 if ( ESCHER_SPLIT_MENU_COLORS_COUNT
)
115 nSize
= ( ESCHER_SPLIT_MENU_COLORS_COUNT
<< 2 ) + 8;
119 void PptEscherEx::ImplWriteSplitMenuColorsAtom( SvStream
& rSt
)
121 sal_uInt32 nSize
= ImplSplitMenuColorsAtomSize();
124 rSt
<< (sal_uInt32
)( ( ESCHER_SplitMenuColors
<< 16 ) | ( ESCHER_SPLIT_MENU_COLORS_COUNT
<< 4 ) )
125 << (sal_uInt32
)( nSize
- 8 )
126 << (sal_uInt32
)0x08000004
127 << (sal_uInt32
)0x08000001
128 << (sal_uInt32
)0x08000002
129 << (sal_uInt32
)0x100000f7;
134 // ---------------------------------------------------------------------------------------------
136 PptEscherEx::~PptEscherEx()
140 // ---------------------------------------------------------------------------------------------
142 void PptEscherEx::OpenContainer( sal_uInt16 n_EscherContainer
, int nRecInstance
)
144 *mpOutStrm
<< (sal_uInt16
)( ( nRecInstance
<< 4 ) | 0xf ) << n_EscherContainer
<< (sal_uInt32
)0;
145 mOffsets
.push_back( mpOutStrm
->Tell() - 4 );
146 mRecTypes
.push_back( n_EscherContainer
);
148 switch( n_EscherContainer
)
150 case ESCHER_DgContainer
:
154 mbEscherDg
= sal_True
;
155 mnCurrentDg
= mxGlobal
->GenerateDrawingId();
156 AddAtom( 8, ESCHER_Dg
, 0, mnCurrentDg
);
157 PtReplaceOrInsert( ESCHER_Persist_Dg
| mnCurrentDg
, mpOutStrm
->Tell() );
158 *mpOutStrm
<< (sal_uInt32
)0 // The number of shapes in this drawing
159 << (sal_uInt32
)0; // The last MSOSPID given to an SP in this DG
164 case ESCHER_SpgrContainer
:
168 mbEscherSpgr
= sal_True
;
178 // ---------------------------------------------------------------------------------------------
180 void PptEscherEx::CloseContainer()
183 not creating group objects with a depth higher than 16, because then
184 PPT is having a big performance problem when starting a slide show
186 if ( ( mRecTypes
.back() != ESCHER_SpgrContainer
) || ( mnGroupLevel
< 12 ) )
188 sal_uInt32 nSize
, nPos
= mpOutStrm
->Tell();
189 nSize
= ( nPos
- mOffsets
.back() ) - 4;
190 mpOutStrm
->Seek( mOffsets
.back() );
193 switch( mRecTypes
.back() )
195 case ESCHER_DgContainer
:
199 mbEscherDg
= sal_False
;
200 if ( DoSeek( ESCHER_Persist_Dg
| mnCurrentDg
) )
201 *mpOutStrm
<< mxGlobal
->GetDrawingShapeCount( mnCurrentDg
) << mxGlobal
->GetLastShapeId( mnCurrentDg
);
206 case ESCHER_SpgrContainer
:
210 mbEscherSpgr
= sal_False
;
220 mRecTypes
.pop_back();
221 mpOutStrm
->Seek( nPos
);
225 // ---------------------------------------------------------------------------------------------
227 sal_uInt32
PptEscherEx::EnterGroup( Rectangle
* pBoundRect
, SvMemoryStream
* pClientData
)
229 sal_uInt32 nShapeId
= 0;
231 not creating group objects with a depth higher than 16, because then
232 PPT is having a big performance problem when starting a slide show
234 if ( mnGroupLevel
< 12 )
240 OpenContainer( ESCHER_SpgrContainer
);
241 OpenContainer( ESCHER_SpContainer
);
242 AddAtom( 16, ESCHER_Spgr
, 1 );
243 PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap
| mnGroupLevel
, mpOutStrm
->Tell() );
244 *mpOutStrm
<< (sal_Int32
)aRect
.Left() // bounding box for the grouped shapes to which they are attached
245 << (sal_Int32
)aRect
.Top()
246 << (sal_Int32
)aRect
.Right()
247 << (sal_Int32
)aRect
.Bottom();
249 nShapeId
= GenerateShapeId();
251 AddShape( ESCHER_ShpInst_Min
, 5, nShapeId
); // Flags: Group | Patriarch
254 AddShape( ESCHER_ShpInst_Min
, 0x201, nShapeId
); // Flags: Group | HaveAnchor
255 if ( mnGroupLevel
== 1 )
257 AddAtom( 8, ESCHER_ClientAnchor
);
258 PtReplaceOrInsert( ESCHER_Persist_Grouping_Logic
| mnGroupLevel
, mpOutStrm
->Tell() );
259 *mpOutStrm
<< (sal_Int16
)aRect
.Top() << (sal_Int16
)aRect
.Left() << (sal_Int16
)aRect
.Right() << (sal_Int16
)aRect
.Bottom();
263 AddAtom( 16, ESCHER_ChildAnchor
);
264 PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap
| mnGroupLevel
, mpOutStrm
->Tell() );
265 *mpOutStrm
<< (sal_Int32
)aRect
.Left()
266 << (sal_Int32
)aRect
.Top()
267 << (sal_Int32
)aRect
.Right()
268 << (sal_Int32
)aRect
.Bottom();
273 pClientData
->Seek( STREAM_SEEK_TO_END
);
274 sal_uInt32 nSize
= pClientData
->Tell();
277 *mpOutStrm
<< (sal_uInt32
)( ( ESCHER_ClientData
<< 16 ) | 0xf )
279 mpOutStrm
->Write( pClientData
->GetData(), nSize
);
282 CloseContainer(); // ESCHER_SpContainer
288 // ---------------------------------------------------------------------------------------------
290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */