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 PptEscherEx::PptEscherEx( SvStream
& rOutStrm
, const OUString
& rBaseURI
) :
23 EscherEx( std::make_shared
<EscherExGlobal
>( ), &rOutStrm
)
25 mxGlobal
->SetBaseURI( rBaseURI
);
29 sal_uInt32
PptEscherEx::DrawingGroupContainerSize()
31 return ImplDggContainerSize() + 8;
34 void PptEscherEx::WriteDrawingGroupContainer( SvStream
& rSt
)
36 sal_uInt32 nSize
= DrawingGroupContainerSize();
37 rSt
.WriteUInt32( 0xf | ( 1035 << 16 ) ) // EPP_PPDrawingGroup
38 .WriteUInt32( nSize
- 8 );
40 ImplWriteDggContainer( rSt
);
43 sal_uInt32
PptEscherEx::ImplDggContainerSize()
47 nSize
= mxGlobal
->GetDggAtomSize();
48 nSize
+= mxGlobal
->GetBlibStoreContainerSize();
49 nSize
+= ImplOptAtomSize();
50 nSize
+= ImplSplitMenuColorsAtomSize();
55 void PptEscherEx::ImplWriteDggContainer( SvStream
& rSt
)
57 sal_uInt32 nSize
= ImplDggContainerSize();
60 rSt
.WriteUInt32( 0xf | ( ESCHER_DggContainer
<< 16 ) )
61 .WriteUInt32( nSize
- 8 );
63 mxGlobal
->SetDggContainer();
64 mxGlobal
->WriteDggAtom( rSt
);
65 mxGlobal
->WriteBlibStoreContainer( rSt
);
66 ImplWriteOptAtom( rSt
);
67 ImplWriteSplitMenuColorsAtom( rSt
);
71 #define ESCHER_OPT_COUNT 6
73 sal_uInt32
PptEscherEx::ImplOptAtomSize()
76 if ( ESCHER_OPT_COUNT
!= 0 )
77 nSize
= ( ESCHER_OPT_COUNT
* 6 ) + 8;
81 void PptEscherEx::ImplWriteOptAtom( SvStream
& rSt
)
83 sal_uInt32 nSize
= ImplOptAtomSize();
86 rSt
.WriteUInt32( ( ESCHER_OPT
<< 16 ) | ( ESCHER_OPT_COUNT
<< 4 ) | 0x3 )
87 .WriteUInt32( nSize
- 8 )
88 .WriteUInt16( ESCHER_Prop_fillColor
) .WriteUInt32( 0xffb800 )
89 .WriteUInt16( ESCHER_Prop_fillBackColor
) .WriteUInt32( 0 )
90 .WriteUInt16( ESCHER_Prop_fNoFillHitTest
) .WriteUInt32( 0x00100010 )
91 .WriteUInt16( ESCHER_Prop_lineColor
) .WriteUInt32( 0x8000001 )
92 .WriteUInt16( ESCHER_Prop_fNoLineDrawDash
) .WriteUInt32( 0x00080008 )
93 .WriteUInt16( ESCHER_Prop_shadowColor
) .WriteUInt32( 0x8000002 );
97 #define ESCHER_SPLIT_MENU_COLORS_COUNT 4
99 sal_uInt32
PptEscherEx::ImplSplitMenuColorsAtomSize()
101 sal_uInt32 nSize
= 0;
102 if ( ESCHER_SPLIT_MENU_COLORS_COUNT
!= 0 )
103 nSize
= ( ESCHER_SPLIT_MENU_COLORS_COUNT
<< 2 ) + 8;
107 void PptEscherEx::ImplWriteSplitMenuColorsAtom( SvStream
& rSt
)
109 sal_uInt32 nSize
= ImplSplitMenuColorsAtomSize();
112 rSt
.WriteUInt32( ( ESCHER_SplitMenuColors
<< 16 ) | ( ESCHER_SPLIT_MENU_COLORS_COUNT
<< 4 ) )
113 .WriteUInt32( nSize
- 8 )
114 .WriteUInt32( 0x08000004 )
115 .WriteUInt32( 0x08000001 )
116 .WriteUInt32( 0x08000002 )
117 .WriteUInt32( 0x100000f7 );
122 PptEscherEx::~PptEscherEx()
126 void PptEscherEx::OpenContainer( sal_uInt16 n_EscherContainer
, int nRecInstance
)
128 mpOutStrm
->WriteUInt16( ( nRecInstance
<< 4 ) | 0xf ).WriteUInt16( n_EscherContainer
).WriteUInt32( 0 );
129 mOffsets
.push_back( mpOutStrm
->Tell() - 4 );
130 mRecTypes
.push_back( n_EscherContainer
);
132 switch( n_EscherContainer
)
134 case ESCHER_DgContainer
:
139 mnCurrentDg
= mxGlobal
->GenerateDrawingId();
140 AddAtom( 8, ESCHER_Dg
, 0, mnCurrentDg
);
141 PtReplaceOrInsert( ESCHER_Persist_Dg
| mnCurrentDg
, mpOutStrm
->Tell() );
142 mpOutStrm
->WriteUInt32( 0 ) // The number of shapes in this drawing
143 .WriteUInt32( 0 ); // The last MSOSPID given to an SP in this DG
148 case ESCHER_SpgrContainer
:
162 void PptEscherEx::CloseContainer()
165 not creating group objects with a depth higher than 16, because then
166 PPT is having a big performance problem when starting a slide show
168 if ( ( mRecTypes
.back() == ESCHER_SpgrContainer
) && ( mnGroupLevel
>= 12 ) )
171 sal_uInt32 nSize
, nPos
= mpOutStrm
->Tell();
172 nSize
= ( nPos
- mOffsets
.back() ) - 4;
173 mpOutStrm
->Seek( mOffsets
.back() );
174 mpOutStrm
->WriteUInt32( nSize
);
176 switch( mRecTypes
.back() )
178 case ESCHER_DgContainer
:
183 if ( DoSeek( ESCHER_Persist_Dg
| mnCurrentDg
) )
184 mpOutStrm
->WriteUInt32( mxGlobal
->GetDrawingShapeCount( mnCurrentDg
) ).WriteUInt32( mxGlobal
->GetLastShapeId( mnCurrentDg
) );
189 case ESCHER_SpgrContainer
:
193 mbEscherSpgr
= false;
202 mRecTypes
.pop_back();
203 mpOutStrm
->Seek( nPos
);
206 sal_uInt32
PptEscherEx::EnterGroup( ::tools::Rectangle
const * pBoundRect
, SvMemoryStream
* pClientData
)
208 sal_uInt32 nShapeId
= 0;
210 not creating group objects with a depth higher than 16, because then
211 PPT is having a big performance problem when starting a slide show
213 if ( mnGroupLevel
< 12 )
215 ::tools::Rectangle aRect
;
219 OpenContainer( ESCHER_SpgrContainer
);
220 OpenContainer( ESCHER_SpContainer
);
221 AddAtom( 16, ESCHER_Spgr
, 1 );
222 PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap
| mnGroupLevel
, mpOutStrm
->Tell() );
223 mpOutStrm
->WriteInt32( aRect
.Left() ) // bounding box for the grouped shapes to which they are attached
224 .WriteInt32( aRect
.Top() )
225 .WriteInt32( aRect
.Right() )
226 .WriteInt32( aRect
.Bottom() );
228 nShapeId
= GenerateShapeId();
230 AddShape( ESCHER_ShpInst_Min
, ShapeFlag::Group
| ShapeFlag::Patriarch
, nShapeId
);
233 AddShape( ESCHER_ShpInst_Min
, ShapeFlag::HaveAnchor
| ShapeFlag::Group
, nShapeId
);
234 if ( mnGroupLevel
== 1 )
236 AddAtom( 8, ESCHER_ClientAnchor
);
237 PtReplaceOrInsert( ESCHER_Persist_Grouping_Logic
| mnGroupLevel
, mpOutStrm
->Tell() );
238 mpOutStrm
->WriteInt16( aRect
.Top() ).WriteInt16( aRect
.Left() ).WriteInt16( aRect
.Right() ).WriteInt16( aRect
.Bottom() );
242 AddAtom( 16, ESCHER_ChildAnchor
);
243 PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap
| mnGroupLevel
, mpOutStrm
->Tell() );
244 mpOutStrm
->WriteInt32( aRect
.Left() )
245 .WriteInt32( aRect
.Top() )
246 .WriteInt32( aRect
.Right() )
247 .WriteInt32( aRect
.Bottom() );
252 sal_uInt32 nSize
= pClientData
->TellEnd();
255 mpOutStrm
->WriteUInt32( ( ESCHER_ClientData
<< 16 ) | 0xf )
256 .WriteUInt32( nSize
);
257 mpOutStrm
->WriteBytes(pClientData
->GetData(), nSize
);
260 CloseContainer(); // ESCHER_SpContainer
266 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */