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
27
28 #ifndef _PptEscherEx_HXX
29 #include "escherex.hxx"
30 #endif
31
32 // ---------------------------------------------------------------------------------------------
33 // ---------------------------------------------------------------------------------------------
34 // ---------------------------------------------------------------------------------------------
35
PptEscherEx(SvStream & rOutStrm,const rtl::OUString & rBaseURI)36 PptEscherEx::PptEscherEx( SvStream& rOutStrm, const rtl::OUString& rBaseURI ) :
37 EscherEx( EscherExGlobalRef( new EscherExGlobal ), rOutStrm )
38 {
39 mxGlobal->SetBaseURI( rBaseURI );
40 mnCurrentDg = 0;
41 }
42
43 // ---------------------------------------------------------------------------------------------
44
DrawingGroupContainerSize()45 sal_uInt32 PptEscherEx::DrawingGroupContainerSize()
46 {
47 return ImplDggContainerSize() + 8;
48 }
49
WriteDrawingGroupContainer(SvStream & rSt)50 void PptEscherEx::WriteDrawingGroupContainer( SvStream& rSt )
51 {
52 sal_uInt32 nSize = DrawingGroupContainerSize();
53 rSt << (sal_uInt32)( 0xf | ( 1035 << 16 ) ) // EPP_PPDrawingGroup
54 << (sal_uInt32)( nSize - 8 );
55
56 ImplWriteDggContainer( rSt );
57 }
58
59 // ---------------------------------------------------------------------------------------------
60
ImplDggContainerSize()61 sal_uInt32 PptEscherEx::ImplDggContainerSize()
62 {
63 sal_uInt32 nSize;
64
65 nSize = mxGlobal->GetDggAtomSize();
66 nSize += mxGlobal->GetBlibStoreContainerSize();
67 nSize += ImplOptAtomSize();
68 nSize += ImplSplitMenuColorsAtomSize();
69
70 return nSize + 8;
71 }
72
ImplWriteDggContainer(SvStream & rSt)73 void PptEscherEx::ImplWriteDggContainer( SvStream& rSt )
74 {
75 sal_uInt32 nSize = ImplDggContainerSize();
76 if ( nSize )
77 {
78 rSt << (sal_uInt32)( 0xf | ( ESCHER_DggContainer << 16 ) )
79 << (sal_uInt32)( nSize - 8 );
80
81 mxGlobal->SetDggContainer();
82 mxGlobal->WriteDggAtom( rSt );
83 mxGlobal->WriteBlibStoreContainer( rSt );
84 ImplWriteOptAtom( rSt );
85 ImplWriteSplitMenuColorsAtom( rSt );
86 }
87 }
88
89 // ---------------------------------------------------------------------------------------------
90
91 #define ESCHER_OPT_COUNT 6
92
ImplOptAtomSize()93 sal_uInt32 PptEscherEx::ImplOptAtomSize()
94 {
95 sal_uInt32 nSize = 0;
96 if ( ESCHER_OPT_COUNT )
97 nSize = ( ESCHER_OPT_COUNT * 6 ) + 8;
98 return nSize;
99 }
100
ImplWriteOptAtom(SvStream & rSt)101 void PptEscherEx::ImplWriteOptAtom( SvStream& rSt )
102 {
103 sal_uInt32 nSize = ImplOptAtomSize();
104 if ( nSize )
105 {
106 rSt << (sal_uInt32)( ( ESCHER_OPT << 16 ) | ( ESCHER_OPT_COUNT << 4 ) | 0x3 )
107 << (sal_uInt32)( nSize - 8 )
108 << (sal_uInt16)ESCHER_Prop_fillColor << (sal_uInt32)0xffb800
109 << (sal_uInt16)ESCHER_Prop_fillBackColor << (sal_uInt32)0
110 << (sal_uInt16)ESCHER_Prop_fNoFillHitTest << (sal_uInt32)0x00100010
111 << (sal_uInt16)ESCHER_Prop_lineColor << (sal_uInt32)0x8000001
112 << (sal_uInt16)ESCHER_Prop_fNoLineDrawDash << (sal_uInt32)0x00080008
113 << (sal_uInt16)ESCHER_Prop_shadowColor << (sal_uInt32)0x8000002;
114 }
115 }
116
117 // ---------------------------------------------------------------------------------------------
118
119 #define ESCHER_SPLIT_MENU_COLORS_COUNT 4
120
ImplSplitMenuColorsAtomSize()121 sal_uInt32 PptEscherEx::ImplSplitMenuColorsAtomSize()
122 {
123 sal_uInt32 nSize = 0;
124 if ( ESCHER_SPLIT_MENU_COLORS_COUNT )
125 nSize = ( ESCHER_SPLIT_MENU_COLORS_COUNT << 2 ) + 8;
126 return nSize;
127 }
128
ImplWriteSplitMenuColorsAtom(SvStream & rSt)129 void PptEscherEx::ImplWriteSplitMenuColorsAtom( SvStream& rSt )
130 {
131 sal_uInt32 nSize = ImplSplitMenuColorsAtomSize();
132 if ( nSize )
133 {
134 rSt << (sal_uInt32)( ( ESCHER_SplitMenuColors << 16 ) | ( ESCHER_SPLIT_MENU_COLORS_COUNT << 4 ) )
135 << (sal_uInt32)( nSize - 8 )
136 << (sal_uInt32)0x08000004
137 << (sal_uInt32)0x08000001
138 << (sal_uInt32)0x08000002
139 << (sal_uInt32)0x100000f7;
140 }
141
142 }
143
144 // ---------------------------------------------------------------------------------------------
145
~PptEscherEx()146 PptEscherEx::~PptEscherEx()
147 {
148 }
149
150 // ---------------------------------------------------------------------------------------------
151
OpenContainer(sal_uInt16 n_EscherContainer,int nRecInstance)152 void PptEscherEx::OpenContainer( sal_uInt16 n_EscherContainer, int nRecInstance )
153 {
154 *mpOutStrm << (sal_uInt16)( ( nRecInstance << 4 ) | 0xf ) << n_EscherContainer << (sal_uInt32)0;
155 mOffsets.push_back( mpOutStrm->Tell() - 4 );
156 mRecTypes.push_back( n_EscherContainer );
157
158 switch( n_EscherContainer )
159 {
160 case ESCHER_DgContainer :
161 {
162 if ( !mbEscherDg )
163 {
164 mbEscherDg = sal_True;
165 mnCurrentDg = mxGlobal->GenerateDrawingId();
166 AddAtom( 8, ESCHER_Dg, 0, mnCurrentDg );
167 PtReplaceOrInsert( ESCHER_Persist_Dg | mnCurrentDg, mpOutStrm->Tell() );
168 *mpOutStrm << (sal_uInt32)0 // The number of shapes in this drawing
169 << (sal_uInt32)0; // The last MSOSPID given to an SP in this DG
170 }
171 }
172 break;
173
174 case ESCHER_SpgrContainer :
175 {
176 if ( mbEscherDg )
177 {
178 mbEscherSpgr = sal_True;
179 }
180 }
181 break;
182
183 case ESCHER_SpContainer :
184 {
185 }
186 break;
187
188 default:
189 break;
190 }
191 }
192
193 // ---------------------------------------------------------------------------------------------
194
CloseContainer()195 void PptEscherEx::CloseContainer()
196 {
197 /* SJ: #Issue 26747#
198 not creating group objects with a depth higher than 16, because then
199 PPT is having a big performance problem when starting a slide show
200 */
201 if ( ( mRecTypes.back() != ESCHER_SpgrContainer ) || ( mnGroupLevel < 12 ) )
202 {
203 sal_uInt32 nSize, nPos = mpOutStrm->Tell();
204 nSize = ( nPos - mOffsets.back() ) - 4;
205 mpOutStrm->Seek( mOffsets.back() );
206 *mpOutStrm << nSize;
207
208 switch( mRecTypes.back() )
209 {
210 case ESCHER_DgContainer :
211 {
212 if ( mbEscherDg )
213 {
214 mbEscherDg = sal_False;
215 if ( DoSeek( ESCHER_Persist_Dg | mnCurrentDg ) )
216 *mpOutStrm << mxGlobal->GetDrawingShapeCount( mnCurrentDg ) << mxGlobal->GetLastShapeId( mnCurrentDg );
217 }
218 }
219 break;
220
221 case ESCHER_SpgrContainer :
222 {
223 if ( mbEscherSpgr )
224 {
225 mbEscherSpgr = sal_False;
226
227 }
228 }
229 break;
230
231 default:
232 break;
233 }
234 mOffsets.pop_back();
235 mRecTypes.pop_back();
236 mpOutStrm->Seek( nPos );
237 }
238 }
239
240 // ---------------------------------------------------------------------------------------------
241
EnterGroup(Rectangle * pBoundRect,SvMemoryStream * pClientData)242 sal_uInt32 PptEscherEx::EnterGroup( Rectangle* pBoundRect, SvMemoryStream* pClientData )
243 {
244 sal_uInt32 nShapeId = 0;
245 /* SJ: #Issue 26747#
246 not creating group objects with a depth higher than 16, because then
247 PPT is having a big performance problem when starting a slide show
248 */
249 if ( mnGroupLevel < 12 )
250 {
251 Rectangle aRect;
252 if ( pBoundRect )
253 aRect = *pBoundRect;
254
255 OpenContainer( ESCHER_SpgrContainer );
256 OpenContainer( ESCHER_SpContainer );
257 AddAtom( 16, ESCHER_Spgr, 1 );
258 PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap | mnGroupLevel, mpOutStrm->Tell() );
259 *mpOutStrm << (sal_Int32)aRect.Left() // Bounding box fuer die Gruppierten shapes an die sie attached werden
260 << (sal_Int32)aRect.Top()
261 << (sal_Int32)aRect.Right()
262 << (sal_Int32)aRect.Bottom();
263
264 nShapeId = GenerateShapeId();
265 if ( !mnGroupLevel )
266 AddShape( ESCHER_ShpInst_Min, 5, nShapeId ); // Flags: Group | Patriarch
267 else
268 {
269 AddShape( ESCHER_ShpInst_Min, 0x201, nShapeId ); // Flags: Group | HaveAnchor
270 if ( mnGroupLevel == 1 )
271 {
272 AddAtom( 8, ESCHER_ClientAnchor );
273 PtReplaceOrInsert( ESCHER_Persist_Grouping_Logic | mnGroupLevel, mpOutStrm->Tell() );
274 *mpOutStrm << (sal_Int16)aRect.Top() << (sal_Int16)aRect.Left() << (sal_Int16)aRect.Right() << (sal_Int16)aRect.Bottom();
275 }
276 else
277 {
278 AddAtom( 16, ESCHER_ChildAnchor );
279 PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap | mnGroupLevel, mpOutStrm->Tell() );
280 *mpOutStrm << (sal_Int32)aRect.Left()
281 << (sal_Int32)aRect.Top()
282 << (sal_Int32)aRect.Right()
283 << (sal_Int32)aRect.Bottom();
284 }
285 }
286 if ( pClientData )
287 {
288 pClientData->Seek( STREAM_SEEK_TO_END );
289 sal_uInt32 nSize = pClientData->Tell();
290 if ( nSize )
291 {
292 *mpOutStrm << (sal_uInt32)( ( ESCHER_ClientData << 16 ) | 0xf )
293 << nSize;
294 mpOutStrm->Write( pClientData->GetData(), nSize );
295 }
296 }
297 CloseContainer(); // ESCHER_SpContainer
298 }
299 mnGroupLevel++;
300 return nShapeId;
301 }
302
303 // ---------------------------------------------------------------------------------------------
304