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 .
22 #include <doctok/resourceids.hxx>
23 #include <resourcemodel/WW8ResourceModel.hxx>
24 #include "doctok/resources.hxx"
26 namespace writerfilter
{
29 typedef boost::shared_ptr
<WW8Value
> WW8ValueSharedPointer_t
;
31 DffRecord::DffRecord(WW8Stream
& rStream
, sal_uInt32 nOffset
,
33 : WW8StructBase(rStream
, nOffset
, nCount
), bInitialized(false)
37 DffRecord::DffRecord(WW8StructBase
* pParent
, sal_uInt32 nOffset
,
39 : WW8StructBase(pParent
, nOffset
, nCount
), bInitialized(false)
43 Records_t::iterator
DffRecord::begin()
48 return mRecords
.begin();
51 Records_t::iterator
DffRecord::end()
56 return mRecords
.end();
59 bool DffRecord::isContainer() const
61 return getVersion() == 0xf;
64 sal_uInt32
DffRecord::calcSize() const
66 sal_uInt32 nResult
= 0;
68 switch (getRecordType())
75 nResult
= getU32(0x4) + 8;
83 nResult
= getU32(0x4);
93 sal_uInt32
DffRecord::getVersion() const
95 return getU8(0x0) & 0xf;
98 sal_uInt32
DffRecord::getInstance() const
100 return (getU16(0x0) & 0xfff0) >> 4;
103 sal_uInt32
DffRecord::getRecordType() const
108 void DffRecord::initChildren()
112 sal_uInt32 nOffset
= 8;
113 sal_uInt32 nCount
= calcSize();
115 while (nCount
- nOffset
>= 8)
117 sal_uInt32 nSize
= 0;
118 boost::shared_ptr
<DffRecord
> pRec
119 (createDffRecord(this, nOffset
, &nSize
));
124 mRecords
.push_back(pRec
);
133 Records_t
DffRecord::findRecords(sal_uInt32 nType
, bool bRecursive
, bool bAny
)
137 findRecords(nType
, aResult
, bRecursive
, bAny
);
142 void DffRecord::findRecords
143 (sal_uInt32 nType
, Records_t
& rRecords
, bool bRecursive
, bool bAny
)
145 Records_t::iterator aIt
= begin();
149 Pointer_t pPointer
= *aIt
;
150 if (bAny
|| pPointer
->getRecordType() == nType
)
151 rRecords
.push_back(pPointer
);
154 pPointer
->findRecords(nType
, rRecords
, bRecursive
,
161 void DffRecord::resolveChildren(Properties
& rHandler
)
163 Records_t::iterator aIt
;
164 for (aIt
= begin(); aIt
!= end(); ++aIt
)
166 rHandler
.sprm(**aIt
);
170 void DffRecord::resolveLocal(Properties
&)
174 void DffRecord::resolve(Properties
& rHandler
)
176 WW8Value::Pointer_t pVal
= createValue(getRecordType());
177 rHandler
.attribute(NS_rtf::LN_dfftype
, *pVal
);
179 pVal
= createValue(getInstance());
180 rHandler
.attribute(NS_rtf::LN_dffinstance
, *pVal
);
182 pVal
= createValue(getVersion());
183 rHandler
.attribute(NS_rtf::LN_dffversion
, *pVal
);
185 pVal
= createValue(getU32(0x0));
186 rHandler
.attribute(NS_rtf::LN_dffheader
, *pVal
);
190 resolveChildren(rHandler
);
193 resolveLocal(rHandler
);
195 WW8BinaryObjReference::Pointer_t pBinObjRef
196 (new WW8BinaryObjReference(this, 0, getCount()));
197 WW8Sprm
aSprm(pBinObjRef
);
199 rHandler
.sprm(aSprm
);
202 sal_uInt32
DffRecord::getShapeType()
204 sal_uInt32 nResult
= 0;
206 Records_t aRecords
= findRecords(0xf00a);
208 if (!aRecords
.empty())
210 DffFSP
* pDffFSP
= dynamic_cast<DffFSP
*>((*aRecords
.begin()).get());
211 nResult
= pDffFSP
->get_shptype();
217 sal_uInt32
DffRecord::getShapeId()
219 sal_uInt32 nResult
= 0;
221 Records_t aRecords
= findRecords(0xf00a);
223 if (!aRecords
.empty())
225 DffFSP
* pDffFSP
= dynamic_cast<DffFSP
*>((*aRecords
.begin()).get());
226 nResult
= pDffFSP
->get_shpid();
232 class DffOPTHandler
: public Properties
234 map
<int, WW8ValueSharedPointer_t
> mMap
;
238 DffOPTHandler() : nId(0) {}
239 virtual ~DffOPTHandler() {}
241 virtual void attribute(Id name
, Value
& val
)
245 case NS_rtf::LN_shppid
:
248 case NS_rtf::LN_shpvalue
:
250 WW8Value
& rTmpVal
= dynamic_cast<WW8Value
&>(val
);
251 WW8ValueSharedPointer_t
252 pVal(dynamic_cast<WW8Value
*>(rTmpVal
.clone()));
258 virtual void sprm(Sprm
& /*sprm_*/)
262 WW8ValueSharedPointer_t
& getValue(int nId_
)
269 sal_uInt32
DffRecord::getShapeBid()
271 sal_uInt32 nResult
= 0;
273 if (getShapeType() == 75)
275 Records_t aRecords
= findRecords(0xf00b);
277 if (!aRecords
.empty())
279 DffOPTHandler aHandler
;
280 DffOPT
* pOpts
= dynamic_cast<DffOPT
*>((*aRecords
.begin()).get());
282 sal_uInt32 nCount
= pOpts
->get_property_count();
284 for (sal_uInt32 n
= 0; n
< nCount
; ++n
)
286 pOpts
->get_property(n
)->resolve(aHandler
);
289 WW8ValueSharedPointer_t pVal
= aHandler
.getValue(260);
291 if (pVal
.get() != NULL
)
292 nResult
= pVal
->getInt();
299 string
DffRecord::getType() const
304 Value::Pointer_t
DffRecord::getValue()
306 return Value::Pointer_t();
309 writerfilter::Reference
<BinaryObj
>::Pointer_t
DffRecord::getBinary()
311 return writerfilter::Reference
<BinaryObj
>::Pointer_t();
314 writerfilter::Reference
<Stream
>::Pointer_t
DffRecord::getStream()
316 return writerfilter::Reference
<Stream
>::Pointer_t();
319 writerfilter::Reference
<Properties
>::Pointer_t
DffRecord::getProps()
321 return writerfilter::Reference
<Properties
>::Pointer_t(this->clone());
324 string
DffRecord::toString() const
328 snprintf(sBuffer
, sizeof(sBuffer
),
329 "<dffrecord type=\"%" SAL_PRIuUINT32
"\" instance=\"%" SAL_PRIuUINT32
"\" version=\"%" SAL_PRIuUINT32
"\">\n",
330 getRecordType(), getInstance(), getVersion());
331 string aResult
= sBuffer
;
335 aResult
+= mSequence
.toString();
338 WW8StructBase::Sequence
aSeq(mSequence
, 0, 8);
339 aResult
+= aSeq
.toString();
342 aResult
+= "</dffrecord>";
347 string
DffRecord::getName() const
352 Sprm::Kind
DffRecord::getKind()
354 return Sprm::UNKNOWN
;
357 DffBlock::DffBlock(WW8Stream
& rStream
, sal_uInt32 nOffset
,
358 sal_uInt32 nCount
, sal_uInt32 nPadding
)
359 : WW8StructBase(rStream
, nOffset
, nCount
), bInitialized(false),
364 DffBlock::DffBlock(WW8StructBase
* pParent
, sal_uInt32 nOffset
,
365 sal_uInt32 nCount
, sal_uInt32 nPadding
)
366 : WW8StructBase(pParent
, nOffset
, nCount
), bInitialized(false),
371 DffBlock::DffBlock(const DffBlock
& rSrc
)
372 : WW8StructBase(rSrc
), writerfilter::Reference
<Properties
>(rSrc
),
373 bInitialized(false), mnPadding(rSrc
.mnPadding
)
377 void DffBlock::initChildren()
379 sal_uInt32 nOffset
= 0;
380 sal_uInt32 nCount
= getCount();
382 while (nOffset
< nCount
)
384 sal_uInt32 nSize
= 0;
385 DffRecord::Pointer_t pDffRecord
386 (createDffRecord(this, nOffset
, &nSize
));
391 mRecords
.push_back(pDffRecord
);
393 nOffset
+= nSize
+ mnPadding
;
399 Records_t
DffBlock::findRecords(sal_uInt32 nType
, bool bRecursive
, bool bAny
)
403 findRecords(nType
, aResult
, bRecursive
, bAny
);
408 void DffBlock::findRecords
409 (sal_uInt32 nType
, Records_t
& rRecords
, bool bRecursive
, bool bAny
)
411 Records_t::iterator aIt
= begin();
415 DffRecord::Pointer_t
pPointer(*aIt
);
417 if (bAny
|| pPointer
->getRecordType() == nType
)
418 rRecords
.push_back(pPointer
);
421 pPointer
->findRecords(nType
, rRecords
, bRecursive
,
428 void DffBlock::resolve(Properties
& rHandler
)
430 Records_t::iterator aIt
;
432 for (aIt
= begin(); aIt
!= end(); ++aIt
)
434 DffRecord
* pDff
= aIt
->get();
435 rHandler
.sprm(*pDff
);
439 DffRecord::Pointer_t
DffBlock::getShape(sal_uInt32 nSpid
)
441 DffRecord::Pointer_t pResult
;
443 Records_t aRecords
= findRecords(0xf004);
444 Records_t::iterator aIt
;
445 for (aIt
= aRecords
.begin(); aIt
!= aRecords
.end(); ++aIt
)
447 DffRecord::Pointer_t pPointer
= *aIt
;
449 Records_t aFSPs
= pPointer
->findRecords(0xf00a);
450 Records_t::iterator aItFSP
= aFSPs
.begin();
452 if (aItFSP
!= aFSPs
.end())
454 DffFSP
* pFSP
= dynamic_cast<DffFSP
*>((*aItFSP
).get());
456 if (pFSP
->get_shpid() == nSpid
)
468 DffRecord::Pointer_t
DffBlock::getBlip(sal_uInt32 nBlip
)
470 DffRecord::Pointer_t pResult
;
476 Records_t aRecords
= findRecords(0xf007);
478 if (nBlip
< aRecords
.size())
480 pResult
= aRecords
[nBlip
];
487 Records_t::iterator
DffBlock::begin()
492 return mRecords
.begin();
495 Records_t::iterator
DffBlock::end()
500 return mRecords
.end();
503 string
DffBlock::getType() const
510 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */