LibreOffice Module sd (master) 1
escherex.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include "escherex.hxx"
21
22PptEscherEx::PptEscherEx( SvStream& rOutStrm, const OUString& rBaseURI ) :
23 EscherEx( std::make_shared<EscherExGlobal>( ), &rOutStrm )
24{
25 mxGlobal->SetBaseURI( rBaseURI );
26 mnCurrentDg = 0;
27}
28
30{
31 return ImplDggContainerSize() + 8;
32}
33
35{
36 sal_uInt32 nSize = DrawingGroupContainerSize();
37 rSt.WriteUInt32( 0xf | ( 1035 << 16 ) ) // EPP_PPDrawingGroup
38 .WriteUInt32( nSize - 8 );
39
41}
42
44{
45 sal_uInt32 nSize;
46
47 nSize = mxGlobal->GetDggAtomSize();
48 nSize += mxGlobal->GetBlibStoreContainerSize();
49 nSize += ImplOptAtomSize();
51
52 return nSize + 8;
53}
54
56{
57 sal_uInt32 nSize = ImplDggContainerSize();
58 if ( nSize )
59 {
60 rSt.WriteUInt32( 0xf | ( ESCHER_DggContainer << 16 ) )
61 .WriteUInt32( nSize - 8 );
62
63 mxGlobal->SetDggContainer();
64 mxGlobal->WriteDggAtom( rSt );
65 mxGlobal->WriteBlibStoreContainer( rSt );
66 ImplWriteOptAtom( rSt );
68 }
69}
70
71#define ESCHER_OPT_COUNT 6
72
74{
75 sal_uInt32 nSize = 0;
76 if ( ESCHER_OPT_COUNT != 0 )
77 nSize = ( ESCHER_OPT_COUNT * 6 ) + 8;
78 return nSize;
79}
80
82{
83 sal_uInt32 nSize = ImplOptAtomSize();
84 if ( nSize )
85 {
86 rSt.WriteUInt32( ( ESCHER_OPT << 16 ) | ( ESCHER_OPT_COUNT << 4 ) | 0x3 )
87 .WriteUInt32( nSize - 8 )
94 }
95}
96
97#define ESCHER_SPLIT_MENU_COLORS_COUNT 4
98
100{
101 sal_uInt32 nSize = 0;
103 nSize = ( ESCHER_SPLIT_MENU_COLORS_COUNT << 2 ) + 8;
104 return nSize;
105}
106
108{
109 sal_uInt32 nSize = ImplSplitMenuColorsAtomSize();
110 if ( nSize )
111 {
113 .WriteUInt32( nSize - 8 )
114 .WriteUInt32( 0x08000004 )
115 .WriteUInt32( 0x08000001 )
116 .WriteUInt32( 0x08000002 )
117 .WriteUInt32( 0x100000f7 );
118 }
119
120}
121
123{
124}
125
126void PptEscherEx::OpenContainer( sal_uInt16 n_EscherContainer, int nRecInstance )
127{
128 mpOutStrm->WriteUInt16( ( nRecInstance << 4 ) | 0xf ).WriteUInt16( n_EscherContainer ).WriteUInt32( 0 );
129 mOffsets.push_back( mpOutStrm->Tell() - 4 );
130 mRecTypes.push_back( n_EscherContainer );
131
132 switch( n_EscherContainer )
133 {
134 case ESCHER_DgContainer :
135 {
136 if ( !mbEscherDg )
137 {
138 mbEscherDg = true;
139 mnCurrentDg = mxGlobal->GenerateDrawingId();
140 AddAtom( 8, ESCHER_Dg, 0, mnCurrentDg );
142 mpOutStrm->WriteUInt32( 0 ) // The number of shapes in this drawing
143 .WriteUInt32( 0 ); // The last MSOSPID given to an SP in this DG
144 }
145 }
146 break;
147
149 {
150 if ( mbEscherDg )
151 {
152 mbEscherSpgr = true;
153 }
154 }
155 break;
156
157 default:
158 break;
159 }
160}
161
163{
164 /* SJ: #Issue 26747#
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
167 */
168 if ( ( mRecTypes.back() == ESCHER_SpgrContainer ) && ( mnGroupLevel >= 12 ) )
169 return;
170
171 sal_uInt32 nSize, nPos = mpOutStrm->Tell();
172 nSize = ( nPos - mOffsets.back() ) - 4;
173 mpOutStrm->Seek( mOffsets.back() );
174 mpOutStrm->WriteUInt32( nSize );
175
176 switch( mRecTypes.back() )
177 {
178 case ESCHER_DgContainer :
179 {
180 if ( mbEscherDg )
181 {
182 mbEscherDg = false;
184 mpOutStrm->WriteUInt32( mxGlobal->GetDrawingShapeCount( mnCurrentDg ) ).WriteUInt32( mxGlobal->GetLastShapeId( mnCurrentDg ) );
185 }
186 }
187 break;
188
190 {
191 if ( mbEscherSpgr )
192 {
193 mbEscherSpgr = false;
194 }
195 }
196 break;
197
198 default:
199 break;
200 }
201 mOffsets.pop_back();
202 mRecTypes.pop_back();
203 mpOutStrm->Seek( nPos );
204}
205
206sal_uInt32 PptEscherEx::EnterGroup( ::tools::Rectangle const * pBoundRect, SvMemoryStream* pClientData )
207{
208 sal_uInt32 nShapeId = 0;
209 /* SJ: #Issue 26747#
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
212 */
213 if ( mnGroupLevel < 12 )
214 {
215 ::tools::Rectangle aRect;
216 if ( pBoundRect )
217 aRect = *pBoundRect;
218
221 AddAtom( 16, ESCHER_Spgr, 1 );
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() );
227
228 nShapeId = GenerateShapeId();
229 if ( !mnGroupLevel )
230 AddShape( ESCHER_ShpInst_Min, ShapeFlag::Group | ShapeFlag::Patriarch, nShapeId );
231 else
232 {
233 AddShape( ESCHER_ShpInst_Min, ShapeFlag::HaveAnchor | ShapeFlag::Group, nShapeId );
234 if ( mnGroupLevel == 1 )
235 {
238 mpOutStrm->WriteInt16( aRect.Top() ).WriteInt16( aRect.Left() ).WriteInt16( aRect.Right() ).WriteInt16( aRect.Bottom() );
239 }
240 else
241 {
244 mpOutStrm ->WriteInt32( aRect.Left() )
245 .WriteInt32( aRect.Top() )
246 .WriteInt32( aRect.Right() )
247 .WriteInt32( aRect.Bottom() );
248 }
249 }
250 if ( pClientData )
251 {
252 sal_uInt32 nSize = pClientData->TellEnd();
253 if ( nSize )
254 {
255 mpOutStrm->WriteUInt32( ( ESCHER_ClientData << 16 ) | 0xf )
256 .WriteUInt32( nSize );
257 mpOutStrm->WriteBytes(pClientData->GetData(), nSize);
258 }
259 }
260 CloseContainer(); // ESCHER_SpContainer
261 }
262 mnGroupLevel++;
263 return nShapeId;
264}
265
266/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt32 mnGroupLevel
bool mbEscherSpgr
sal_uInt32 mnCurrentDg
bool mbEscherDg
virtual void AddShape(sal_uInt32 nShpInstance, ShapeFlag nFlagIds, sal_uInt32 nShapeID=0)
void AddAtom(sal_uInt32 nAtomSitze, sal_uInt16 nRecType, int nRecVersion=0, int nRecInstance=0)
bool DoSeek(sal_uInt32 nKey)
SvStream * mpOutStrm
virtual sal_uInt32 GenerateShapeId()
std::shared_ptr< EscherExGlobal > mxGlobal
std::vector< sal_uInt32 > mOffsets
std::vector< sal_uInt16 > mRecTypes
void PtReplaceOrInsert(sal_uInt32 nID, sal_uInt32 nOfs)
void WriteDrawingGroupContainer(SvStream &rSt)
Definition: escherex.cxx:34
sal_uInt32 DrawingGroupContainerSize()
Definition: escherex.cxx:29
void CloseContainer() override
Definition: escherex.cxx:162
static sal_uInt32 ImplSplitMenuColorsAtomSize()
Definition: escherex.cxx:99
static sal_uInt32 ImplOptAtomSize()
Definition: escherex.cxx:73
sal_uInt32 ImplDggContainerSize()
Definition: escherex.cxx:43
void OpenContainer(sal_uInt16 n_EscherContainer, int nRecInstance=0) override
Definition: escherex.cxx:126
static void ImplWriteOptAtom(SvStream &rSt)
Definition: escherex.cxx:81
void ImplWriteDggContainer(SvStream &rSt)
Definition: escherex.cxx:55
sal_uInt32 EnterGroup(::tools::Rectangle const *pBoundRect, SvMemoryStream *pClientData)
Definition: escherex.cxx:206
PptEscherEx(SvStream &rOut, const OUString &)
Definition: escherex.cxx:22
virtual ~PptEscherEx() override
Definition: escherex.cxx:122
static void ImplWriteSplitMenuColorsAtom(SvStream &rSt)
Definition: escherex.cxx:107
const void * GetData()
virtual sal_uInt64 TellEnd() override
SvStream & WriteInt32(sal_Int32 nInt32)
sal_uInt64 Tell() const
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStream & WriteInt16(sal_Int16 nInt16)
SvStream & WriteUInt16(sal_uInt16 nUInt16)
SvStream & WriteUInt32(sal_uInt32 nUInt32)
sal_uInt64 Seek(sal_uInt64 nPos)
constexpr tools::Long Top() const
constexpr tools::Long Right() const
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
#define ESCHER_SPLIT_MENU_COLORS_COUNT
Definition: escherex.cxx:97
#define ESCHER_OPT_COUNT
Definition: escherex.cxx:71
#define ESCHER_Prop_lineColor
#define ESCHER_SplitMenuColors
#define ESCHER_Prop_fNoFillHitTest
#define ESCHER_ClientData
#define ESCHER_Prop_fNoLineDrawDash
#define ESCHER_ChildAnchor
#define ESCHER_OPT
#define ESCHER_Dg
#define ESCHER_Prop_shadowColor
#define ESCHER_DgContainer
#define ESCHER_ShpInst_Min
#define ESCHER_Spgr
#define ESCHER_Persist_Grouping_Snap
#define ESCHER_ClientAnchor
#define ESCHER_Persist_Grouping_Logic
#define ESCHER_SpgrContainer
#define ESCHER_Prop_fillBackColor
#define ESCHER_Persist_Dg
#define ESCHER_SpContainer
#define ESCHER_DggContainer
#define ESCHER_Prop_fillColor
sal_uInt16 nPos
std::shared_ptr< T > make_shared(Args &&... args)