sc: factor out some more code
[LibreOffice.git] / sw / source / filter / ww8 / ww8scan.hxx
blob74f2efb2beadea4a44b7561befcfccc6dddb51eb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 #ifndef INCLUDED_SW_SOURCE_FILTER_WW8_WW8SCAN_HXX
21 #define INCLUDED_SW_SOURCE_FILTER_WW8_WW8SCAN_HXX
23 #include <cassert>
24 #include <cstddef>
25 #include <deque>
26 #include <memory>
27 #include <optional>
28 #include <stack>
29 #include <unordered_map>
30 #include <vector>
32 #include <osl/endian.h>
33 #include <tools/solar.h>
34 #include <tools/stream.hxx>
35 #include <rtl/ustring.hxx>
37 #include "ww8struc.hxx"
38 #include "types.hxx"
40 class SvStream;
42 //Commonly used string literals for stream and storage names in word docs
43 namespace SL
45 inline constexpr OUString aObjectPool = u"ObjectPool"_ustr;
46 inline constexpr OUString a1Table = u"1Table"_ustr;
47 inline constexpr OUString a0Table = u"0Table"_ustr;
48 inline constexpr OUString aData = u"Data"_ustr;
49 inline constexpr OUString aCheckBox = u"CheckBox"_ustr;
50 inline constexpr OUString aListBox = u"ListBox"_ustr;
51 inline constexpr OUString aTextField = u"TextField"_ustr;
52 inline constexpr OUString aMSMacroCmds = u"MSMacroCmds"_ustr;
55 struct SprmInfo
57 unsigned int nLen : 6;
58 unsigned int nVari : 2;
61 struct SprmInfoRow {
62 sal_uInt16 nId; ///< A ww8 sprm is hardcoded as 16bits
63 SprmInfo info;
66 class wwSprmSearcher {
67 public:
68 //see Read_AmbiguousSPRM for the bPatchCJK oddity
69 wwSprmSearcher(SprmInfoRow const * rows, std::size_t size, bool bPatchCJK = false) {
70 for (std::size_t i = 0; i != size; ++i) {
71 bool ins = map_.emplace(rows[i].nId, rows[i].info).second;
72 assert(ins); (void) ins;
74 if (bPatchCJK)
75 patchCJKVariant();
78 SprmInfo const * search(sal_uInt16 id) const {
79 Map::const_iterator i(map_.find(id));
80 return i == map_.end() ? nullptr : &i->second;
83 private:
84 typedef std::unordered_map<sal_uInt16, SprmInfo> Map;
86 Map map_;
88 void patchCJKVariant();
91 class WW8Fib;
93 struct SprmResult
95 const sal_uInt8* pSprm;
96 sal_Int32 nRemainingData;
97 SprmResult()
98 : pSprm(nullptr)
99 , nRemainingData(0)
102 SprmResult(const sal_uInt8* pInSprm, sal_Int32 nInRemainingData)
103 : pSprm(pInSprm)
104 , nRemainingData(nInRemainingData)
110 wwSprmParser knows how to take a sequence of bytes and split it up into
111 sprms and their arguments
113 class wwSprmParser
115 private:
116 ww::WordVersion meVersion;
117 sal_uInt8 mnDelta;
118 const wwSprmSearcher *mpKnownSprms;
119 static const wwSprmSearcher* GetWW8SprmSearcher();
120 static const wwSprmSearcher* GetWW6SprmSearcher(const WW8Fib& rFib);
121 static const wwSprmSearcher* GetWW2SprmSearcher();
123 SprmInfo GetSprmInfo(sal_uInt16 nId) const;
125 sal_uInt8 SprmDataOfs(sal_uInt16 nId) const;
127 public:
128 enum SprmType {L_FIX=0, L_VAR=1, L_VAR2=2};
130 //7- ids are very different to 8+ ones
131 explicit wwSprmParser(const WW8Fib& rFib);
132 /// Return the SPRM id at the beginning of this byte sequence
133 sal_uInt16 GetSprmId(const sal_uInt8* pSp) const;
135 sal_Int32 GetSprmSize(sal_uInt16 nId, const sal_uInt8* pSprm, sal_Int32 nRemLen) const;
137 /// Get known len of a sprms head, the bytes of the sprm id + any bytes
138 /// reserved to hold a variable length
139 sal_Int32 DistanceToData(sal_uInt16 nId) const;
141 /// Get len of a sprms data area, ignoring the bytes of the sprm id and
142 /// ignoring any len bytes. Reports the remaining data after those bytes
143 sal_uInt16 GetSprmTailLen(sal_uInt16 nId, const sal_uInt8* pSprm, sal_Int32 nRemLen) const;
145 /// The minimum acceptable sprm len possible for this type of parser
146 int MinSprmLen() const { return (IsSevenMinus(meVersion)) ? 2 : 3; }
148 /// Returns the offset to data of the first sprm of id nId, 0
149 // if not found. nLen must be the <= length of pSprms
150 SprmResult findSprmData(sal_uInt16 nId, sal_uInt8* pSprms, sal_Int32 nLen) const;
152 ww::WordVersion GetFIBVersion() const { return meVersion; }
155 //Read a Pascal-style, i.e. single byte string length followed
156 //by string contents
157 inline OUString read_uInt8_PascalString(SvStream& rStrm, rtl_TextEncoding eEnc)
159 return read_uInt8_lenPrefixed_uInt8s_ToOUString(rStrm, eEnc);
162 inline OUString read_uInt16_PascalString(SvStream& rStrm)
164 return read_uInt16_lenPrefixed_uInt16s_ToOUString(rStrm);
167 //Belt and Braces strings, i.e. Pascal-style strings followed by
168 //null termination, Spolsky calls them "fucked strings" FWIW
169 //http://www.joelonsoftware.com/articles/fog0000000319.html
170 OUString read_uInt8_BeltAndBracesString(SvStream& rStrm, rtl_TextEncoding eEnc);
171 OUString read_uInt16_BeltAndBracesString(SvStream& rStrm);
173 //--Line above which the code has meaningful comments
175 class WW8ScannerBase;
176 class WW8PLCFspecial;
177 struct WW8PLCFxDesc;
178 class WW8PLCFx_PCD;
181 reads array of strings (see MS documentation: String Table stored in File)
182 returns NOT the original pascal strings but an array of converted char*
184 attention: the *extra data* of each string are SKIPPED and ignored
186 void WW8ReadSTTBF(bool bVer8, SvStream& rStrm, sal_uInt32 nStart, sal_Int32 nLen,
187 sal_uInt16 nExtraLen, rtl_TextEncoding eCS, std::vector<OUString> &rArray,
188 std::vector<ww::bytes>* pExtraArray = nullptr, std::vector<OUString>* pValueArray = nullptr);
190 struct WW8FieldDesc
192 WW8_CP nLen; ///< total length (to skip over text)
193 WW8_CP nSCode; ///< start of instructions code
194 WW8_CP nLCode; ///< length
195 WW8_CP nSRes; ///< start of result
196 WW8_CP nLRes; ///< length ( == 0, if no result )
197 sal_uInt16 nId; ///< WW-id for fields
198 sal_uInt8 nOpt; ///< WW-Flags ( e.g.: changed by user )
199 bool bCodeNest:1; ///< instruction used recursively
200 bool bResNest:1; ///< instruction inserted into result
203 struct WW8PLCFxSave1
205 sal_uInt32 nPLCFxPos;
206 sal_uInt32 nPLCFxPos2; ///< for PLCF_Cp_Fkp: PieceIter-Pos
207 tools::Long nPLCFxMemOfs;
208 WW8_CP nStartCp; ///< for cp based iterator like PAP and CHP
209 tools::Long nCpOfs;
210 WW8_FC nStartFC;
211 WW8_CP nAttrStart;
212 WW8_CP nAttrEnd;
213 bool bLineEnd;
217 among others for fields, that is, the same number of attr as positions,
218 if Ctor-Param bNoEnd = false
220 class WW8PLCFspecial // iterator for PLCFs
222 private:
223 std::unique_ptr<sal_Int32[]> m_pPLCF_PosArray; ///< pointer to Pos-array and to the whole structure
224 sal_uInt8* m_pPLCF_Contents; ///< pointer to content-array-part of Pos-array
225 tools::Long m_nIMax; ///< number of elements
226 tools::Long m_nIdx; ///< marker where we currently are
227 sal_uInt32 m_nStru;
229 WW8PLCFspecial(const WW8PLCFspecial&) = delete;
230 WW8PLCFspecial& operator=(const WW8PLCFspecial&) = delete;
232 public:
233 WW8PLCFspecial(SvStream* pSt, sal_uInt32 nFilePos, sal_uInt32 nPLCF,
234 sal_uInt32 nStruct);
235 tools::Long GetIdx() const { return m_nIdx; }
236 void SetIdx( tools::Long nI ) { m_nIdx = nI; }
237 tools::Long GetIMax() const { return m_nIMax; }
238 bool SeekPos(tools::Long nPos); // walks over FC- or CP-value
239 // resp. next biggest value
240 bool SeekPosExact(tools::Long nPos);
241 sal_Int32 Where() const
242 { return ( m_nIdx >= m_nIMax ) ? SAL_MAX_INT32 : m_pPLCF_PosArray[m_nIdx]; }
243 bool Get(WW8_CP& rStart, void*& rpValue) const;
244 bool GetData(tools::Long nIdx, WW8_CP& rPos, void*& rpValue) const;
246 const void* GetData( tools::Long nInIdx ) const
248 return ( nInIdx >= m_nIMax ) ? nullptr
249 : static_cast<const void*>(&m_pPLCF_Contents[nInIdx * m_nStru]);
251 sal_Int32 GetPos( tools::Long nInIdx ) const
252 { return ( nInIdx >= m_nIMax ) ? SAL_MAX_INT32 : m_pPLCF_PosArray[nInIdx]; }
254 void advance()
256 if (m_nIdx <= m_nIMax)
257 ++m_nIdx;
261 /** simple Iterator for SPRMs */
262 class WW8SprmIter
264 private:
265 const wwSprmParser &mrSprmParser;
266 // these members will be updated
267 const sal_uInt8* m_pSprms; // remaining part of the SPRMs ( == start of current SPRM)
268 const sal_uInt8* m_pCurrentParams; // start of current SPRM's parameters
269 sal_uInt16 m_nCurrentId;
270 sal_Int32 m_nCurrentSize;
272 sal_Int32 m_nRemLen; // length of remaining SPRMs (including current SPRM)
274 void UpdateMyMembers();
276 public:
277 explicit WW8SprmIter(const sal_uInt8* pSprms_, sal_Int32 nLen_,
278 const wwSprmParser &rSprmParser);
279 void SetSprms(const sal_uInt8* pSprms_, sal_Int32 nLen_);
280 SprmResult FindSprm(sal_uInt16 nId, bool bFindFirst, const sal_uInt8* pNextByteMatch = nullptr);
281 void advance();
282 const sal_uInt8* GetSprms() const
283 { return ( m_pSprms && (0 < m_nRemLen) ) ? m_pSprms : nullptr; }
284 const sal_uInt8* GetCurrentParams() const { return m_pCurrentParams; }
285 sal_uInt16 GetCurrentId() const { return m_nCurrentId; }
286 sal_Int32 GetRemLen() const { return m_nRemLen; }
288 private:
289 WW8SprmIter(const WW8SprmIter&) = delete;
290 WW8SprmIter& operator=(const WW8SprmIter&) = delete;
293 /* among others for FKPs to normal attr., i.e. one less attr than positions */
294 class WW8PLCF // Iterator for PLCFs
296 private:
297 std::unique_ptr<WW8_CP[]> m_pPLCF_PosArray; // pointer to Pos-array and the whole structure
298 sal_uInt8* m_pPLCF_Contents; // pointer to content-array-part of Pos-array
299 sal_Int32 m_nIMax; // number of elements
300 sal_Int32 m_nIdx;
301 int m_nStru;
303 void ReadPLCF(SvStream& rSt, WW8_FC nFilePos, sal_uInt32 nPLCF);
306 If a PLC is missing in the doc and the FKPs stand alone,
307 we create a PLC with this:
309 void GeneratePLCF(SvStream& rSt, sal_Int32 nPN, sal_Int32 ncpN);
311 void MakeFailedPLCF();
313 void TruncToSortedRange();
314 public:
315 WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
316 WW8_CP nStartPos = -1);
319 the following ctor generates a PLC from nPN and ncpN, if necessary
321 WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
322 WW8_CP nStartPos, sal_Int32 nPN, sal_Int32 ncpN);
324 sal_Int32 GetIdx() const { return m_nIdx; }
325 void SetIdx( sal_Int32 nI ) { m_nIdx = nI; }
326 sal_Int32 GetIMax() const { return m_nIMax; }
327 bool SeekPos(WW8_CP nPos);
328 WW8_CP Where() const;
329 bool Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const;
330 void advance() { if( m_nIdx < m_nIMax ) ++m_nIdx; }
332 const void* GetData( sal_Int32 nInIdx ) const
334 return ( nInIdx >= m_nIMax ) ? nullptr :
335 static_cast<const void*>(&m_pPLCF_Contents[nInIdx * m_nStru]);
339 /* for Piece Table (.i.e. FastSave Table) */
340 class WW8PLCFpcd
342 friend class WW8PLCFpcd_Iter;
344 std::unique_ptr<WW8_CP[]> m_pPLCF_PosArray; // pointer to Pos-array and the whole structure
345 sal_uInt8* m_pPLCF_Contents; // pointer to content-array-part of Pos-array
346 sal_Int32 m_nIMax;
347 sal_uInt32 m_nStru;
349 WW8PLCFpcd(const WW8PLCFpcd&) = delete;
350 WW8PLCFpcd& operator=(const WW8PLCFpcd&) = delete;
352 void TruncToSortedRange();
354 public:
355 WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos, sal_uInt32 nPLCF,
356 sal_uInt32 nStruct);
359 /* multiple WW8PLCFpcd_Iter may point to the same WW8PLCFpcd !!! */
360 class WW8PLCFpcd_Iter
362 private:
363 WW8PLCFpcd& m_rPLCF;
364 tools::Long m_nIdx;
366 WW8PLCFpcd_Iter(const WW8PLCFpcd_Iter&) = delete;
367 WW8PLCFpcd_Iter& operator=(const WW8PLCFpcd_Iter&) = delete;
369 public:
370 WW8PLCFpcd_Iter( WW8PLCFpcd& rPLCFpcd, tools::Long nStartPos = -1 );
371 tools::Long GetIdx() const { return m_nIdx; }
372 void SetIdx( tools::Long nI ) { m_nIdx = nI; }
373 tools::Long GetIMax() const { return m_rPLCF.m_nIMax; }
374 bool SeekPos(tools::Long nPos);
375 sal_Int32 Where() const;
376 bool Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const;
377 void advance()
379 if( m_nIdx < m_rPLCF.m_nIMax )
380 ++m_nIdx;
384 // PLCF-type:
385 enum ePLCFT{ CHP=0, PAP, SEP, /*HED, FNR, ENR,*/ PLCF_END };
387 //It's hardcoded that eFTN be the first one: a very poor hack, needs to be fixed
388 enum eExtSprm : sal_uInt16 { eFTN = 256, eEDN = 257, eFLD = 258, eBKN = 259, eAND = 260, eATNBKN = 261, eFACTOIDBKN = 262 };
391 pure virtual:
393 class WW8PLCFx // virtual iterator for Piece Table Exceptions
395 private:
396 const WW8Fib& mrFib;
397 bool m_bIsSprm; // PLCF of Sprms or other stuff ( Footnote, ... )
398 WW8_FC m_nStartFc;
399 bool m_bDirty;
401 WW8PLCFx(const WW8PLCFx&) = delete;
402 WW8PLCFx& operator=(const WW8PLCFx&) = delete;
404 public:
405 WW8PLCFx(const WW8Fib& rFib, bool bSprm)
406 : mrFib(rFib)
407 , m_bIsSprm(bSprm)
408 , m_nStartFc(-1)
409 , m_bDirty(false)
412 virtual ~WW8PLCFx() {}
413 bool IsSprm() const { return m_bIsSprm; }
414 virtual sal_uInt32 GetIdx() const = 0;
415 virtual void SetIdx(sal_uInt32 nIdx) = 0;
416 virtual sal_uInt32 GetIdx2() const;
417 virtual void SetIdx2(sal_uInt32 nIdx);
418 virtual bool SeekPos(WW8_CP nCpPos) = 0;
419 virtual WW8_FC Where() = 0;
420 virtual void GetSprms( WW8PLCFxDesc* p );
421 virtual tools::Long GetNoSprms( WW8_CP& rStart, WW8_CP&, sal_Int32& rLen );
422 virtual void advance() = 0;
423 virtual sal_uInt16 GetIstd() const { return 0xffff; }
424 virtual void Save( WW8PLCFxSave1& rSave ) const;
425 virtual void Restore( const WW8PLCFxSave1& rSave );
426 ww::WordVersion GetFIBVersion() const;
427 const WW8Fib& GetFIB() const { return mrFib; }
428 void SetStartFc( WW8_FC nFc ) { m_nStartFc = nFc; }
429 WW8_FC GetStartFc() const { return m_nStartFc; }
430 void SetDirty(bool bIn) {m_bDirty=bIn;}
431 bool GetDirty() const {return m_bDirty;}
434 class WW8PLCFx_PCDAttrs : public WW8PLCFx
436 private:
437 WW8PLCFpcd_Iter* m_pPcdI;
438 WW8PLCFx_PCD* m_pPcd;
439 std::vector<std::unique_ptr<sal_uInt8[]>> const & mrGrpprls; // attribute of Piece-table
440 sal_uInt8 m_aShortSprm[4]; // mini storage: can contain ONE sprm with 1 byte param
442 WW8PLCFx_PCDAttrs(const WW8PLCFx_PCDAttrs&) = delete;
443 WW8PLCFx_PCDAttrs& operator=(const WW8PLCFx_PCDAttrs&) = delete;
445 public:
446 WW8PLCFx_PCDAttrs(const WW8Fib& rFib, WW8PLCFx_PCD* pPLCFx_PCD,
447 const WW8ScannerBase* pBase );
448 virtual sal_uInt32 GetIdx() const override;
449 virtual void SetIdx(sal_uInt32 nI) override;
450 virtual bool SeekPos(WW8_CP nCpPos) override;
451 virtual WW8_CP Where() override;
452 virtual void GetSprms( WW8PLCFxDesc* p ) override;
453 virtual void advance() override;
455 WW8PLCFpcd_Iter* GetIter() const { return m_pPcdI; }
458 class WW8PLCFx_PCD : public WW8PLCFx // iterator for Piece table
460 private:
461 std::unique_ptr<WW8PLCFpcd_Iter> m_pPcdI;
462 bool m_bVer67;
463 WW8_CP m_nClipStart;
465 WW8PLCFx_PCD(const WW8PLCFx_PCD&) = delete;
466 WW8PLCFx_PCD& operator=(const WW8PLCFx_PCD&) = delete;
468 public:
469 WW8PLCFx_PCD(const WW8Fib& rFib, WW8PLCFpcd* pPLCFpcd,
470 WW8_CP nStartCp, bool bVer67P);
471 virtual ~WW8PLCFx_PCD() override;
472 sal_uInt32 GetIMax() const;
473 virtual sal_uInt32 GetIdx() const override;
474 virtual void SetIdx(sal_uInt32 nI) override;
475 virtual bool SeekPos(WW8_CP nCpPos) override;
476 virtual WW8_CP Where() override;
477 virtual tools::Long GetNoSprms( WW8_CP& rStart, WW8_CP&, sal_Int32& rLen ) override;
478 virtual void advance() override;
479 WW8_CP CurrentPieceStartFc2Cp( WW8_FC nStartPos );
480 WW8_FC CurrentPieceStartCp2Fc( WW8_CP nCp );
481 static void CurrentPieceFc2Cp(WW8_CP& rStartPos, WW8_CP& rEndPos,
482 const WW8ScannerBase *pSBase);
483 WW8PLCFpcd_Iter* GetPLCFIter() { return m_pPcdI.get(); }
484 void SetClipStart(WW8_CP nIn) { m_nClipStart = nIn; }
485 WW8_CP GetClipStart() const { return m_nClipStart; }
487 static sal_Int32 TransformPieceAddress(tools::Long nfc, bool& bIsUnicodeAddress)
489 bIsUnicodeAddress = 0 == (0x40000000 & nfc);
490 return bIsUnicodeAddress ? nfc : (nfc & 0x3fffFFFF) / 2;
495 Iterator for Piece Table Exceptions of Fkps
496 works only with FCs, not with CPs ! ( Low-Level )
498 class WW8PLCFx_Fc_FKP : public WW8PLCFx
500 public:
501 class WW8Fkp // Iterator for Formatted Disk Page
503 private:
504 class Entry
506 public:
507 WW8_FC mnFC;
509 sal_uInt8* mpData;
510 sal_uInt16 mnLen;
511 sal_uInt16 mnIStd; // only for Fkp.Papx (actually Style-Nr)
512 bool mbMustDelete;
514 explicit Entry(WW8_FC nFC) : mnFC(nFC), mpData(nullptr), mnLen(0),
515 mnIStd(0), mbMustDelete(false) {}
516 Entry(const Entry &rEntry);
517 ~Entry();
518 bool operator<(const Entry& rEntry) const;
519 Entry& operator=(const Entry& rEntry);
522 sal_uInt8 maRawData[512];
523 std::vector<Entry> maEntries;
525 tools::Long m_nItemSize; // either 1 Byte or a complete BX
527 // Offset in Stream where last read of 512 bytes took place
528 tools::Long m_nFilePos;
529 sal_uInt8 mnIdx; // Pos marker
530 ePLCFT m_ePLCF;
531 sal_uInt8 mnIMax; // number of entries
532 int mnMustRemainCached; // after SaveAllPLCFx, before RestoreAllPLCFx
534 wwSprmParser maSprmParser;
536 //Fill in an Entry with sanity testing
537 void FillEntry(Entry &rEntry, std::size_t nDataOffset, sal_uInt16 nLen);
539 public:
540 WW8Fkp (const WW8Fib& rFib, SvStream* pFKPStrm,
541 SvStream* pDataStrm, tools::Long _nFilePos, tools::Long nItemSiz, ePLCFT ePl,
542 WW8_FC nStartFc);
543 void Reset(WW8_FC nPos);
544 tools::Long GetFilePos() const { return m_nFilePos; }
545 sal_uInt8 GetIdx() const { return mnIdx; }
546 void SetIdx(sal_uInt8 nI);
547 bool SeekPos(WW8_FC nFc);
548 WW8_FC Where() const
550 return (mnIdx < mnIMax) ? maEntries[mnIdx].mnFC : WW8_FC_MAX;
552 void advance()
554 if (mnIdx < mnIMax)
555 ++mnIdx;
557 sal_uInt8* Get( WW8_FC& rStart, WW8_FC& rEnd, sal_Int32& rLen ) const;
558 sal_uInt16 GetIstd() const { return maEntries[mnIdx].mnIStd; }
561 returns a real pointer to the Sprm of type nId,
562 if such a thing is in the Fkp.
564 sal_uInt8* GetLenAndIStdAndSprms(sal_Int32& rLen) const;
567 calls GetLenAndIStdAndSprms()...
568 2020 bFindFirst note: Normally the last SPRM takes effect, so I don't know why HasSprm always returned the first value!
569 I don't dare to change the default due to regression potential (and slower in the few cases looking for a boolean result),
570 but first thing to try is use FindFirst as false.
572 SprmResult HasSprm(sal_uInt16 nId, bool bFindFirst = true);
573 void HasSprm(sal_uInt16 nId, std::vector<SprmResult> &rResult);
575 const wwSprmParser &GetSprmParser() const { return maSprmParser; }
577 void IncMustRemainCache() { ++mnMustRemainCached; }
578 bool IsMustRemainCache() const { return mnMustRemainCached > 0; }
579 void DecMustRemainCache() { --mnMustRemainCached; }
582 private:
583 SvStream* m_pFKPStrm; // input file
584 SvStream* m_pDataStrm; // input file
585 std::unique_ptr<WW8PLCF> m_pPLCF;
586 protected:
587 WW8Fkp* m_pFkp;
588 private:
591 Keep a cache of eMaxCache entries of previously seen pFkps, which
592 speeds up considerably table parsing and load save plcfs for what turn
593 out to be small text frames, which frames generally are
595 size : cache hits
596 cache all : 19168 pap, 48 chp
597 == 100 : 19166 pap, 48 chp
598 == 50 : 18918 pap, 48 chp
599 == 10 : 18549 pap, 47 chp
600 == 5 : 18515 pap, 47 chp
602 std::deque<std::unique_ptr<WW8Fkp>> maFkpCache;
603 enum Limits {eMaxCache = 50000};
605 bool NewFkp();
607 WW8PLCFx_Fc_FKP(const WW8PLCFx_Fc_FKP&) = delete;
608 WW8PLCFx_Fc_FKP& operator=(const WW8PLCFx_Fc_FKP&) = delete;
610 protected:
611 ePLCFT m_ePLCF;
612 std::unique_ptr<WW8PLCFx_PCDAttrs> m_pPCDAttrs;
614 public:
615 WW8PLCFx_Fc_FKP( SvStream* pSt, SvStream* pTableSt, SvStream* pDataSt,
616 const WW8Fib& rFib, ePLCFT ePl, WW8_FC nStartFcL );
617 virtual ~WW8PLCFx_Fc_FKP() override;
618 virtual sal_uInt32 GetIdx() const override;
619 virtual void SetIdx(sal_uInt32 nIdx) override;
620 virtual bool SeekPos(WW8_FC nFcPos) override;
621 virtual WW8_FC Where() override;
622 sal_uInt8* GetSprmsAndPos( WW8_FC& rStart, WW8_FC& rEnd, sal_Int32& rLen );
623 virtual void advance() override;
624 virtual sal_uInt16 GetIstd() const override;
625 void GetPCDSprms( WW8PLCFxDesc& rDesc );
626 SprmResult HasSprm(sal_uInt16 nId, bool bFindFirst = true);
627 void HasSprm(sal_uInt16 nId, std::vector<SprmResult> &rResult);
628 bool HasFkp() const { return (nullptr != m_pFkp); }
631 /// iterator for Piece Table Exceptions of Fkps works on CPs (high-level)
632 class WW8PLCFx_Cp_FKP : public WW8PLCFx_Fc_FKP
634 private:
635 const WW8ScannerBase& m_rSBase;
636 std::unique_ptr<WW8PLCFx_PCD> m_pPcd;
637 WW8PLCFpcd_Iter *m_pPieceIter;
638 WW8_CP m_nAttrStart, m_nAttrEnd;
639 bool m_bLineEnd : 1;
640 bool m_bComplex : 1;
642 WW8PLCFx_Cp_FKP(const WW8PLCFx_Cp_FKP&) = delete;
643 WW8PLCFx_Cp_FKP& operator=(const WW8PLCFx_Cp_FKP&) = delete;
645 public:
646 WW8PLCFx_Cp_FKP( SvStream* pSt, SvStream* pTableSt, SvStream* pDataSt,
647 const WW8ScannerBase& rBase, ePLCFT ePl );
648 virtual ~WW8PLCFx_Cp_FKP() override;
649 void ResetAttrStartEnd();
650 sal_uInt32 GetPCDIdx() const;
651 virtual sal_uInt32 GetIdx2() const override;
652 virtual void SetIdx2(sal_uInt32 nIdx) override;
653 virtual bool SeekPos(WW8_CP nCpPos) override;
654 virtual WW8_CP Where() override;
655 virtual void GetSprms( WW8PLCFxDesc* p ) override;
656 virtual void advance() override;
657 virtual void Save( WW8PLCFxSave1& rSave ) const override;
658 virtual void Restore( const WW8PLCFxSave1& rSave ) override;
661 /// Iterator for Piece Table Exceptions of Sepx
662 class WW8PLCFx_SEPX : public WW8PLCFx
664 private:
665 wwSprmParser maSprmParser;
666 SvStream* m_pStrm;
667 std::unique_ptr<WW8PLCF> m_pPLCF;
668 std::unique_ptr<sal_uInt8[]> m_pSprms;
669 sal_uInt16 m_nArrMax;
670 sal_uInt16 m_nSprmSiz;
672 WW8PLCFx_SEPX(const WW8PLCFx_SEPX&) = delete;
673 WW8PLCFx_SEPX& operator=(const WW8PLCFx_SEPX&) = delete;
675 public:
676 WW8PLCFx_SEPX( SvStream* pSt, SvStream* pTablexySt, const WW8Fib& rFib,
677 WW8_CP nStartCp );
678 virtual ~WW8PLCFx_SEPX() override;
679 virtual sal_uInt32 GetIdx() const override;
680 virtual void SetIdx(sal_uInt32 nIdx) override;
681 virtual bool SeekPos(WW8_CP nCpPos) override;
682 virtual WW8_CP Where() override;
683 virtual void GetSprms( WW8PLCFxDesc* p ) override;
684 virtual void advance() override;
685 SprmResult HasSprm( sal_uInt16 nId ) const;
686 SprmResult HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const;
687 SprmResult HasSprm( sal_uInt16 nId, const sal_uInt8* pOtherSprms,
688 tools::Long nOtherSprmSiz ) const;
689 bool Find4Sprms(sal_uInt16 nId1, sal_uInt16 nId2, sal_uInt16 nId3, sal_uInt16 nId4,
690 SprmResult& r1, SprmResult& r2, SprmResult& r3, SprmResult& r4) const;
693 /// iterator for footnotes/endnotes and comments
694 class WW8PLCFx_SubDoc : public WW8PLCFx
696 private:
697 std::unique_ptr<WW8PLCF> m_pRef;
698 std::unique_ptr<WW8PLCF> m_pText;
700 WW8PLCFx_SubDoc(const WW8PLCFx_SubDoc&) = delete;
701 WW8PLCFx_SubDoc& operator=(const WW8PLCFx_SubDoc&) = delete;
703 public:
704 WW8PLCFx_SubDoc(SvStream* pSt, const WW8Fib& rFib, WW8_CP nStartCp,
705 tools::Long nFcRef, tools::Long nLenRef, tools::Long nFcText, tools::Long nLenText, tools::Long nStruc);
706 virtual ~WW8PLCFx_SubDoc() override;
707 virtual sal_uInt32 GetIdx() const override;
708 virtual void SetIdx(sal_uInt32 nIdx) override;
709 virtual bool SeekPos(WW8_CP nCpPos) override;
710 virtual WW8_CP Where() override;
712 // returns reference descriptors
713 const void* GetData() const
715 return m_pRef ? m_pRef->GetData( m_pRef->GetIdx() ) : nullptr;
718 virtual void GetSprms(WW8PLCFxDesc* p) override;
719 virtual void advance() override;
720 tools::Long Count() const { return m_pRef ? m_pRef->GetIMax() : 0; }
723 /// Iterator for fields
724 class WW8PLCFx_FLD : public WW8PLCFx
726 private:
727 std::unique_ptr<WW8PLCFspecial> m_pPLCF;
728 const WW8Fib& m_rFib;
729 WW8PLCFx_FLD(const WW8PLCFx_FLD&) = delete;
730 WW8PLCFx_FLD& operator=(const WW8PLCFx_FLD &) = delete;
732 public:
733 WW8PLCFx_FLD(SvStream* pSt, const WW8Fib& rMyFib, short nType);
734 virtual ~WW8PLCFx_FLD() override;
735 virtual sal_uInt32 GetIdx() const override;
736 virtual void SetIdx(sal_uInt32 nIdx) override;
737 virtual bool SeekPos(WW8_CP nCpPos) override;
738 virtual WW8_CP Where() override;
739 virtual void GetSprms(WW8PLCFxDesc* p) override;
740 virtual void advance() override;
741 bool StartPosIsFieldStart();
742 bool EndPosIsFieldEnd(WW8_CP&);
743 bool GetPara(tools::Long nIdx, WW8FieldDesc& rF);
746 enum eBookStatus { BOOK_NORMAL = 0, BOOK_IGNORE = 0x1, BOOK_FIELD = 0x2 };
748 /// Iterator for Booknotes
749 class WW8PLCFx_Book : public WW8PLCFx
751 private:
752 std::unique_ptr<WW8PLCFspecial> m_pBook[2]; // Start and End Position
753 std::vector<OUString> m_aBookNames; // Name
754 std::vector<eBookStatus> m_aStatus;
755 tools::Long m_nIMax; // Number of Booknotes
756 sal_uInt16 m_nIsEnd;
757 sal_Int32 m_nBookmarkId; // counter incremented by GetUniqueBookmarkName.
759 WW8PLCFx_Book(const WW8PLCFx_Book&) = delete;
760 WW8PLCFx_Book& operator=(const WW8PLCFx_Book&) = delete;
762 public:
763 WW8PLCFx_Book(SvStream* pTableSt,const WW8Fib& rFib);
764 virtual ~WW8PLCFx_Book() override;
765 tools::Long GetIMax() const { return m_nIMax; }
766 virtual sal_uInt32 GetIdx() const override;
767 virtual void SetIdx(sal_uInt32 nI) override;
768 virtual sal_uInt32 GetIdx2() const override;
769 virtual void SetIdx2(sal_uInt32 nIdx) override;
770 virtual bool SeekPos(WW8_CP nCpPos) override;
771 virtual WW8_CP Where() override;
772 virtual tools::Long GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen ) override;
773 virtual void advance() override;
774 const OUString* GetName() const;
775 WW8_CP GetStartPos() const
776 { return m_nIsEnd ? WW8_CP_MAX : m_pBook[0]->Where(); }
777 tools::Long GetLen() const;
778 bool GetIsEnd() const { return m_nIsEnd != 0; }
779 tools::Long GetHandle() const;
780 void SetStatus( sal_uInt16 nIndex, eBookStatus eStat );
781 void MapName(OUString& rName);
782 OUString GetBookmark(tools::Long nStart,tools::Long nEnd, sal_uInt16 &nIndex);
783 eBookStatus GetStatus() const;
784 OUString GetUniqueBookmarkName(const OUString &rSuggestedName);
787 /// Handles the import of PlcfAtnBkf and PlcfAtnBkl: start / end position of annotation marks.
788 class WW8PLCFx_AtnBook : public WW8PLCFx
790 private:
791 /// Start and end positions.
792 std::unique_ptr<WW8PLCFspecial> m_pBook[2];
793 /// Number of annotation marks
794 sal_Int32 m_nIMax;
795 bool m_bIsEnd;
797 WW8PLCFx_AtnBook(const WW8PLCFx_AtnBook&) = delete;
798 WW8PLCFx_AtnBook& operator=(const WW8PLCFx_AtnBook&) = delete;
800 public:
801 WW8PLCFx_AtnBook(SvStream* pTableSt,const WW8Fib& rFib);
802 virtual ~WW8PLCFx_AtnBook() override;
803 virtual sal_uInt32 GetIdx() const override;
804 virtual void SetIdx(sal_uInt32 nI) override;
805 virtual sal_uInt32 GetIdx2() const override;
806 virtual void SetIdx2(sal_uInt32 nIdx) override;
807 virtual bool SeekPos(WW8_CP nCpPos) override;
808 virtual WW8_CP Where() override;
809 virtual tools::Long GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen ) override;
810 virtual void advance() override;
812 /// Handle is the unique ID of an annotation mark.
813 tools::Long getHandle() const;
814 bool getIsEnd() const;
817 /// Handles the import of PlcfBkfFactoid and PlcfBklFactoid: start / end position of factoids.
818 class WW8PLCFx_FactoidBook : public WW8PLCFx
820 private:
821 /// Start and end positions.
822 std::unique_ptr<WW8PLCFspecial> m_pBook[2];
823 /// Number of factoid marks
824 sal_Int32 m_nIMax;
825 bool m_bIsEnd;
827 WW8PLCFx_FactoidBook(const WW8PLCFx_FactoidBook&) = delete;
828 WW8PLCFx_FactoidBook& operator=(const WW8PLCFx_FactoidBook&) = delete;
830 public:
831 WW8PLCFx_FactoidBook(SvStream* pTableSt,const WW8Fib& rFib);
832 virtual ~WW8PLCFx_FactoidBook() override;
833 virtual sal_uInt32 GetIdx() const override;
834 virtual void SetIdx(sal_uInt32 nI) override;
835 virtual sal_uInt32 GetIdx2() const override;
836 virtual void SetIdx2(sal_uInt32 nIdx) override;
837 virtual bool SeekPos(WW8_CP nCpPos) override;
838 virtual WW8_CP Where() override;
839 virtual tools::Long GetNoSprms(WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen) override;
840 virtual void advance() override;
842 /// Handle is the unique ID of a factoid mark.
843 tools::Long getHandle() const;
844 bool getIsEnd() const;
848 this is what we use outside:
850 struct WW8PLCFManResult
852 WW8_CP nCpPos; // attribute starting position
853 tools::Long nMemLen; // length for previous
854 tools::Long nCp2OrIdx; // footnote-textpos or index in PLCF
855 WW8_CP nCurrentCp; // only used by caller
856 const sal_uInt8* pMemPos;// Mem-Pos for Sprms
857 sal_uInt16 nSprmId; // Sprm-Id ( 0 = invalid Id -> skip! )
858 // (2..255) or pseudo-Sprm-Id (256..260)
859 // from Winword-Ver8 Sprm-Id (800..) resp.
860 sal_uInt8 nFlags; // start of paragraph or section
863 enum ManMaskTypes
865 MAN_MASK_NEW_PAP = 1, // new line
866 MAN_MASK_NEW_SEP = 2 // new section
869 enum ManTypes // enums for PLCFMan-ctor
871 MAN_MAINTEXT = 0, MAN_FTN = 1, MAN_EDN = 2, MAN_HDFT = 3, MAN_AND = 4,
872 MAN_TXBX = 5, MAN_TXBX_HDFT = 6
876 this is what the manager uses inside:
878 struct WW8PLCFxDesc
880 WW8PLCFx* pPLCFx;
881 std::optional<std::stack<sal_uInt16>> xIdStack; // memory for Attr-Id for Attr-end(s)
882 const sal_uInt8* pMemPos;// where are the Sprm(s)
883 tools::Long nOrigSprmsLen;
885 WW8_CP nStartPos;
886 WW8_CP nEndPos;
888 WW8_CP nOrigStartPos;
889 WW8_CP nOrigEndPos; // The ending character position of a paragraph is
890 // always one before the end reported in the FKP,
891 // also a character run that ends on the same location
892 // as the paragraph mark is adjusted to end just before
893 // the paragraph mark so as to handle their close
894 // first. The value being used to determining where the
895 // properties end is in nEndPos, but the original
896 // unadjusted end character position is important as
897 // it can be used as the beginning cp of the next set
898 // of properties
900 WW8_CP nCp2OrIdx; // where are the NoSprm(s)
901 sal_Int32 nSprmsLen; // how many bytes for further Sprms / length of footnote
902 tools::Long nCpOfs; // for Offset Header .. Footnote
903 bool bFirstSprm; // for recognizing the first Sprm of a group
904 bool bRealLineEnd; // false for Pap-Piece-end
905 sal_Int16 nRelativeJustify;
906 void Save( WW8PLCFxSave1& rSave ) const;
907 void Restore( const WW8PLCFxSave1& rSave );
908 //With nStartPos set to WW8_CP_MAX then in the case of a pap or chp
909 //GetSprms will not search for the sprms, but instead take the
910 //existing ones.
911 WW8PLCFxDesc()
912 : pPLCFx(nullptr)
913 , pMemPos(nullptr)
914 , nOrigSprmsLen(0)
915 , nStartPos(WW8_CP_MAX)
916 , nEndPos(WW8_CP_MAX)
917 , nOrigStartPos(WW8_CP_MAX)
918 , nOrigEndPos(WW8_CP_MAX)
919 , nCp2OrIdx(WW8_CP_MAX)
920 , nSprmsLen(0)
921 , nCpOfs(0)
922 , bFirstSprm(false)
923 , bRealLineEnd(false)
924 , nRelativeJustify(-1)
927 void ReduceByOffset();
930 struct WW8PLCFxSaveAll;
931 class WW8PLCFMan
933 public:
934 enum WW8PLCFManLimits {MAN_PLCF_COUNT = 12};
936 private:
937 wwSprmParser maSprmParser;
938 WW8_CP m_nCpO; //< Origin Cp -- the basis for nNewCp
940 WW8_CP m_nLineEnd; // points *after* the <CR>
941 sal_uInt16 m_nPLCF; // this many PLCFs are managed
942 ManTypes m_nManType;
943 bool mbDoingDrawTextBox; //Normally we adjust the end of attributes
944 //so that the end of a paragraph occurs
945 //before the para end mark, but for
946 //drawboxes we want the true offsets
948 WW8PLCFxDesc m_aD[MAN_PLCF_COUNT];
949 WW8PLCFxDesc *m_pChp, *m_pPap, *m_pSep, *m_pField, *m_pFootnote, *m_pEdn, *m_pBkm, *m_pPcd,
950 *m_pPcdA, *m_pAnd, *m_pAtnBkm, *m_pFactoidBkm;
951 WW8PLCFspecial *m_pFdoa, *m_pTxbx, *m_pTxbxBkd,*m_pMagicTables, *m_pSubdocs;
952 sal_uInt8* m_pExtendedAtrds;
954 const WW8Fib* m_pWwFib;
956 sal_uInt16 WhereIdx(bool* pbStart, WW8_CP * pPos=nullptr) const;
957 void AdjustEnds(WW8PLCFxDesc& rDesc);
958 void GetNewSprms(WW8PLCFxDesc& rDesc);
959 static void GetNewNoSprms(WW8PLCFxDesc& rDesc);
960 void GetSprmStart(short nIdx, WW8PLCFManResult* pRes) const;
961 void GetSprmEnd(short nIdx, WW8PLCFManResult* pRes) const;
962 void GetNoSprmStart(short nIdx, WW8PLCFManResult* pRes) const;
963 void GetNoSprmEnd(short nIdx, WW8PLCFManResult* pRes) const;
964 void AdvSprm(short nIdx, bool bStart);
965 void AdvNoSprm(short nIdx, bool bStart);
966 sal_uInt16 GetId(const WW8PLCFxDesc* p ) const;
968 bool IsSprmLegalForCategory(sal_uInt16 nSprmId, short nIdx) const;
970 public:
971 WW8PLCFMan(const WW8ScannerBase* pBase, ManTypes nType, tools::Long nStartCp,
972 bool bDoingDrawTextBox = false);
973 ~WW8PLCFMan();
976 Where asks on which following position any Attr changes...
978 WW8_CP Where() const;
980 bool Get(WW8PLCFManResult* pResult) const;
981 void advance();
982 sal_uInt16 GetColl() const; // index of actual Style
983 WW8PLCFx_FLD* GetField() const;
984 WW8PLCFx_SubDoc* GetEdn() const { return static_cast<WW8PLCFx_SubDoc*>(m_pEdn->pPLCFx); }
985 WW8PLCFx_SubDoc* GetFootnote() const { return static_cast<WW8PLCFx_SubDoc*>(m_pFootnote->pPLCFx); }
986 WW8PLCFx_SubDoc* GetAtn() const { return static_cast<WW8PLCFx_SubDoc*>(m_pAnd->pPLCFx); }
987 WW8PLCFx_Book* GetBook() const { return static_cast<WW8PLCFx_Book*>(m_pBkm->pPLCFx); }
988 WW8PLCFx_AtnBook* GetAtnBook() const { return static_cast<WW8PLCFx_AtnBook*>(m_pAtnBkm->pPLCFx); }
989 WW8PLCFx_FactoidBook* GetFactoidBook() const { return static_cast<WW8PLCFx_FactoidBook*>(m_pFactoidBkm->pPLCFx); }
990 tools::Long GetCpOfs() const { return m_pChp->nCpOfs; } // for Header/Footer...
992 /* asks, if *current paragraph* has an Sprm of this type */
993 SprmResult HasParaSprm(sal_uInt16 nId) const;
995 /* asks, if *current textrun* has an Sprm of this type */
996 SprmResult HasCharSprm(sal_uInt16 nId) const;
997 void HasCharSprm(sal_uInt16 nId, std::vector<SprmResult> &rResult) const;
999 WW8PLCFx_Cp_FKP* GetChpPLCF() const
1000 { return static_cast<WW8PLCFx_Cp_FKP*>(m_pChp->pPLCFx); }
1001 WW8PLCFx_Cp_FKP* GetPapPLCF() const
1002 { return static_cast<WW8PLCFx_Cp_FKP*>(m_pPap->pPLCFx); }
1003 WW8PLCFx_SEPX* GetSepPLCF() const
1004 { return static_cast<WW8PLCFx_SEPX*>(m_pSep->pPLCFx); }
1005 WW8PLCFxDesc* GetPap() const { return m_pPap; }
1006 void TransferOpenSprms(std::stack<sal_uInt16> &rStack);
1007 void SeekPos( tools::Long nNewCp );
1008 void SaveAllPLCFx( WW8PLCFxSaveAll& rSave ) const;
1009 void RestoreAllPLCFx( const WW8PLCFxSaveAll& rSave );
1010 WW8PLCFspecial* GetFdoa() const { return m_pFdoa; }
1011 WW8PLCFspecial* GetTxbx() const { return m_pTxbx; }
1012 WW8PLCFspecial* GetTxbxBkd() const { return m_pTxbxBkd; }
1013 WW8PLCFspecial* GetMagicTables() const { return m_pMagicTables; }
1014 WW8PLCFspecial* GetWkbPLCF() const { return m_pSubdocs; }
1015 sal_uInt8* GetExtendedAtrds() const { return m_pExtendedAtrds; }
1016 ManTypes GetManType() const { return m_nManType; }
1017 bool GetDoingDrawTextBox() const { return mbDoingDrawTextBox; }
1020 struct WW8PLCFxSaveAll
1022 WW8PLCFxSave1 aS[WW8PLCFMan::MAN_PLCF_COUNT] = {};
1023 WW8PLCFxSaveAll() = default;
1026 class WW8ScannerBase
1028 friend WW8PLCFx_PCDAttrs::WW8PLCFx_PCDAttrs(const WW8Fib& rFib,
1029 WW8PLCFx_PCD* pPLCFx_PCD, const WW8ScannerBase* pBase );
1030 friend WW8PLCFx_Cp_FKP::WW8PLCFx_Cp_FKP( SvStream*, SvStream*, SvStream*,
1031 const WW8ScannerBase&, ePLCFT );
1033 friend WW8PLCFMan::WW8PLCFMan(const WW8ScannerBase*, ManTypes, tools::Long, bool);
1034 friend class SwWW8FltControlStack;
1036 private:
1037 WW8Fib* m_pWw8Fib;
1038 std::unique_ptr<WW8PLCFx_Cp_FKP> m_pChpPLCF; // Character-Attrs
1039 std::unique_ptr<WW8PLCFx_Cp_FKP> m_pPapPLCF; // Paragraph-Attrs
1040 std::unique_ptr<WW8PLCFx_SEPX> m_pSepPLCF; // Section-Attrs
1041 std::unique_ptr<WW8PLCFx_SubDoc> m_pFootnotePLCF; // Footnotes
1042 std::unique_ptr<WW8PLCFx_SubDoc> m_pEdnPLCF; // EndNotes
1043 std::unique_ptr<WW8PLCFx_SubDoc> m_pAndPLCF; // Comments
1044 std::unique_ptr<WW8PLCFx_FLD> m_pFieldPLCF; // Fields in Main Text
1045 std::unique_ptr<WW8PLCFx_FLD> m_pFieldHdFtPLCF; // Fields in Header / Footer
1046 std::unique_ptr<WW8PLCFx_FLD> m_pFieldTxbxPLCF; // Fields in Textboxes in Main Text
1047 std::unique_ptr<WW8PLCFx_FLD> m_pFieldTxbxHdFtPLCF; // Fields in Textboxes in Header / Footer
1048 std::unique_ptr<WW8PLCFx_FLD> m_pFieldFootnotePLCF; // Fields in Footnotes
1049 std::unique_ptr<WW8PLCFx_FLD> m_pFieldEdnPLCF; // Fields in Endnotes
1050 std::unique_ptr<WW8PLCFx_FLD> m_pFieldAndPLCF; // Fields in Comments
1051 std::unique_ptr<WW8PLCFspecial> m_pMainFdoa; // Graphic Primitives in Main Text
1052 std::unique_ptr<WW8PLCFspecial> m_pHdFtFdoa; // Graphic Primitives in Header / Footer
1053 std::unique_ptr<WW8PLCFspecial> m_pMainTxbx; // Textboxes in Main Text
1054 std::unique_ptr<WW8PLCFspecial> m_pMainTxbxBkd; // Break-Descriptors for them
1055 std::unique_ptr<WW8PLCFspecial> m_pHdFtTxbx; // TextBoxes in Header / Footer
1056 std::unique_ptr<WW8PLCFspecial> m_pHdFtTxbxBkd; // Break-Descriptors for previous
1057 std::unique_ptr<WW8PLCFspecial> m_pMagicTables; // Break-Descriptors for them
1058 std::unique_ptr<WW8PLCFspecial> m_pSubdocs; // subdoc references in master document
1059 std::unique_ptr<sal_uInt8[]>
1060 m_pExtendedAtrds; // Extended ATRDs
1061 std::unique_ptr<WW8PLCFx_Book> m_pBook; // Bookmarks
1062 std::unique_ptr<WW8PLCFx_AtnBook> m_pAtnBook; // Annotationmarks
1063 /// Smart tag bookmarks.
1064 std::unique_ptr<WW8PLCFx_FactoidBook> m_pFactoidBook;
1066 std::unique_ptr<WW8PLCFpcd> m_pPiecePLCF; // for FastSave ( Basis-PLCF without iterator )
1067 std::unique_ptr<WW8PLCFpcd_Iter> m_pPieceIter; // for FastSave ( iterator for previous )
1068 std::unique_ptr<WW8PLCFx_PCD> m_pPLCFx_PCD; // ditto
1069 std::unique_ptr<WW8PLCFx_PCDAttrs> m_pPLCFx_PCDAttrs;
1070 std::vector<std::unique_ptr<sal_uInt8[]>> m_aPieceGrpprls; // attributes of Piece-Table
1072 std::unique_ptr<WW8PLCFpcd> OpenPieceTable( SvStream* pStr, const WW8Fib* pWwF );
1074 WW8ScannerBase(const WW8ScannerBase&) = delete;
1075 WW8ScannerBase& operator=(const WW8ScannerBase&) = delete;
1077 public:
1078 WW8ScannerBase( SvStream* pSt, SvStream* pTableSt, SvStream* pDataSt,
1079 WW8Fib* pWwF );
1080 ~WW8ScannerBase();
1081 bool AreThereFootnotes() const { return m_pFootnotePLCF->Count() > 0; };
1082 bool AreThereEndnotes() const { return m_pEdnPLCF->Count() > 0; };
1084 //If you use WW8Fc2Cp you are almost certainly doing the wrong thing
1085 //when it comes to fastsaved files, avoid like the plague. For export
1086 //given that we never write fastsaved files you can use it, otherwise
1087 //I will beat you with a stick
1088 WW8_CP WW8Fc2Cp(WW8_FC nFcPos) const ;
1089 WW8_FC WW8Cp2Fc(WW8_CP nCpPos, bool* pIsUnicode = nullptr,
1090 WW8_CP* pNextPieceCp = nullptr, bool* pTestFlag = nullptr) const;
1092 sal_Int32 WW8ReadString(SvStream& rStrm, OUString& rStr, WW8_CP nCurrentStartCp,
1093 tools::Long nTotalLen, rtl_TextEncoding eEnc ) const;
1097 /** FIB - the File Information Block
1099 The FIB contains a "magic word" and pointers to the various other parts of
1100 the file, as well as information about the length of the file.
1101 The FIB starts at the beginning of the file.
1103 class WW8Fib
1105 private:
1106 sal_Unicode m_nNumDecimalSep = u'\0';
1108 public:
1110 Program-Version asked for by us:
1111 in Ctor we check if it matches the value of nFib
1113 6 == "WinWord 6 or WinWord 95",
1114 7 == "only WinWord 95"
1115 8 == "WinWord 97 or newer"
1117 sal_uInt8 m_nVersion = 0;
1119 error status
1121 ErrCode m_nFibError;
1123 data read from FIB by Ctor
1124 (corresponds only approximately to the real structure
1125 of the Winword-FIB)
1127 sal_uInt16 m_wIdent = 0; // 0x0 int magic number
1129 File Information Block (FIB) values:
1130 WinWord 1.0 = 33
1131 WinWord 2.0 = 45
1132 WinWord 6.0c for 16bit = 101
1133 Word 6/32 bit = 104
1134 Word 95 = 104
1135 Word 97 = 193
1136 Word 2000 = 217
1137 Word 2002 = 257
1138 Word 2003 = 268
1139 Word 2007 = 274
1141 sal_uInt16 m_nFib = 0; // 0x2 FIB version written
1142 sal_uInt16 m_nProduct = 0; // 0x4 product version written by
1143 LanguageType m_lid; // 0x6 language stamp---localized version;
1144 WW8_PN m_pnNext = 0; // 0x8
1146 bool m_fDot :1 /*= false*/; // 0xa 0001
1147 bool m_fGlsy :1 /*= false*/;
1148 bool m_fComplex :1 /*= false*/; // 0004 when 1, file is in complex, fast-saved format.
1149 bool m_fHasPic :1 /*= false*/; // 0008 file contains 1 or more pictures
1150 sal_uInt16 m_cQuickSaves :4 /*= 0*/; // 00F0 count of times file was quicksaved
1151 bool m_fEncrypted :1 /*= false*/; //0100 1 if file is encrypted, 0 if not
1152 bool m_fWhichTableStm :1 /*= false*/; //0200 When 0, this fib refers to the table stream
1153 bool m_fReadOnlyRecommended :1 /*= false*/;
1154 bool m_fWriteReservation :1 /*= false*/;
1155 // named "0Table", when 1, this fib refers to the
1156 // table stream named "1Table". Normally, a file
1157 // will have only one table stream, but under unusual
1158 // circumstances a file may have table streams with
1159 // both names. In that case, this flag must be used
1160 // to decide which table stream is valid.
1162 bool m_fExtChar :1 /*= false*/; // 1000 =1, when using extended character set in file
1163 bool m_fFarEast :1 /*= false*/; // 4000 =1, probably, when far-East language variants of Word is used to create a file #i90932#
1165 bool m_fObfuscated :1 /*= false*/; // 8000=1. specifies whether the document is obfuscated using XOR obfuscation. otherwise this bit MUST be ignored.
1167 sal_uInt16 m_nFibBack = 0; // 0xc
1168 sal_uInt16 m_nHash = 0; // 0xe file encrypted hash
1169 sal_uInt16 m_nKey = 0; // 0x10 file encrypted key
1170 sal_uInt8 m_envr = 0; // 0x12 environment in which file was created
1171 // 0 created by Win Word / 1 created by Mac Word
1172 bool m_fMac :1 /*= false*/; // 0x13 when 1, this file was last saved in the Mac environment
1173 bool m_fEmptySpecial :1 /*= false*/;
1174 bool m_fLoadOverridePage :1 /*= false*/;
1175 bool m_fFuturesavedUndo :1 /*= false*/;
1176 bool m_fWord97Saved :1 /*= false*/;
1177 bool m_fWord2000Saved :1 /*= false*/;
1178 sal_uInt8 :2;
1180 sal_uInt16 m_chse = 0; // 0x14 default extended character set id for text in document stream. (overridden by chp.chse)
1181 // 0 = ANSI / 256 Macintosh character set.
1182 sal_uInt16 m_chseTables = 0; // 0x16 default extended character set id for text in
1183 // internal data structures: 0 = ANSI, 256 = Macintosh
1184 WW8_FC m_fcMin = 0; // 0x18 file offset of first character of text
1185 WW8_FC m_fcMac = 0; // 0x1c file offset of last character of text + 1
1187 // start of WW8 section
1188 sal_uInt16 m_csw = 0; // Count of fields in the array of "shorts"
1190 // marker: "rgsw" Beginning of the array of shorts
1191 sal_uInt16 m_wMagicCreated = 0; // unique number Identifying the File's creator
1192 // 0x6A62 is the creator ID for Word and is reserved.
1193 // Other creators should choose a different value.
1194 sal_uInt16 m_wMagicRevised = 0; // identifies the File's last modifier
1195 sal_uInt16 m_wMagicCreatedPrivate = 0; // private data
1196 sal_uInt16 m_wMagicRevisedPrivate = 0; // private data
1198 LanguageType m_lidFE; // Language id if document was written by Far East version
1199 // of Word (i.e. FIB.fFarEast is on)
1200 sal_uInt16 m_clw = 0; // Number of fields in the array of longs
1202 // end of WW8 section
1204 // Marker: "rglw" Beginning of the array of longs
1205 WW8_FC m_cbMac = 0; // 0x20 file offset of last byte written to file + 1.
1207 // WW8_FC u4[4]; // 0x24
1208 WW8_CP m_ccpText = 0; // 0x34 length of main document text stream
1209 WW8_CP m_ccpFootnote = 0; // 0x38 length of footnote subdocument text stream
1210 WW8_CP m_ccpHdr = 0; // 0x3c length of header subdocument text stream
1211 WW8_CP m_ccpMcr = 0; // 0x40 length of macro subdocument text stream
1212 WW8_CP m_ccpAtn = 0; // 0x44 length of annotation subdocument text stream
1213 WW8_CP m_ccpEdn = 0; // 0x48 length of endnote subdocument text stream
1214 WW8_CP m_ccpTxbx = 0; // 0x4c length of textbox subdocument text stream
1215 WW8_CP m_ccpHdrTxbx = 0; // 0x50 length of header textbox subdocument text stream
1217 // start of WW8 section
1218 sal_Int32 m_pnFbpChpFirst = 0; // when there was insufficient memory for Word to expand
1219 // the PLCFbte at save time, the PLCFbte is written
1220 // to the file in a linked list of 512-byte pieces
1221 // starting with this pn.
1222 sal_Int32 m_pnFbpPapFirst = 0; // when there was insufficient memory for Word to expand
1223 // the PLCFbte at save time, the PLCFbte is written to
1224 // the file in a linked list of 512-byte pieces
1225 // starting with this pn
1227 sal_Int32 m_pnFbpLvcFirst = 0; // when there was insufficient memory for Word to expand
1228 // the PLCFbte at save time, the PLCFbte is written to
1229 // the file in a linked list of 512-byte pieces
1230 // starting with this pn
1231 sal_Int32 m_pnLvcFirst = 0; // the page number of the lowest numbered page in the
1232 // document that records LVC FKP information
1233 sal_Int32 m_cpnBteLvc = 0; // count of LVC FKPs recorded in file. In non-complex
1234 // files if the number of entries in the PLCFbtePapx is
1235 // less than this, the PLCFbtePapx is incomplete.
1236 sal_Int32 m_fcIslandFirst = 0; // ?
1237 sal_Int32 m_fcIslandLim = 0; // ?
1238 sal_uInt16 m_cfclcb = 0; // Number of fields in the array of FC/LCB pairs.
1239 /// Specifies the count of 16-bit values corresponding to fibRgCswNew that follow.
1240 sal_uInt16 m_cswNew = 0;
1242 // end of WW8 section
1244 // Marker: "rgfclcb" Beginning of array of FC/LCB pairs.
1245 WW8_FC m_fcStshfOrig = 0; // file offset of original allocation for STSH in table
1246 // stream. During fast save Word will attempt to reuse
1247 // this allocation if STSH is small enough to fit.
1248 sal_Int32 m_lcbStshfOrig = 0; // 0x5c count of bytes of original STSH allocation
1249 WW8_FC m_fcStshf = 0; // 0x60 file offset of STSH in file.
1250 sal_Int32 m_lcbStshf = 0; // 0x64 count of bytes of current STSH allocation
1251 WW8_FC m_fcPlcffndRef = 0; // 0x68 file offset of footnote reference PLCF.
1252 sal_Int32 m_lcbPlcffndRef = 0; // 0x6c count of bytes of footnote reference PLCF
1253 // == 0 if no footnotes defined in document.
1255 WW8_FC m_fcPlcffndText = 0; // 0x70 file offset of footnote text PLCF.
1256 sal_Int32 m_lcbPlcffndText = 0; // 0x74 count of bytes of footnote text PLCF.
1257 // == 0 if no footnotes defined in document
1259 WW8_FC m_fcPlcfandRef = 0; // 0x78 file offset of annotation reference PLCF.
1260 sal_Int32 m_lcbPlcfandRef = 0; // 0x7c count of bytes of annotation reference PLCF.
1262 WW8_FC m_fcPlcfandText = 0; // 0x80 file offset of annotation text PLCF.
1263 sal_Int32 m_lcbPlcfandText = 0; // 0x84 count of bytes of the annotation text PLCF
1265 WW8_FC m_fcPlcfsed = 0; // 8x88 file offset of section descriptor PLCF.
1266 sal_Int32 m_lcbPlcfsed = 0; // 0x8c count of bytes of section descriptor PLCF.
1268 WW8_FC m_fcPlcfpad = 0; // 0x90 file offset of paragraph descriptor PLCF
1269 sal_Int32 m_lcbPlcfpad = 0; // 0x94 count of bytes of paragraph descriptor PLCF.
1270 // ==0 if file was never viewed in Outline view.
1271 // Should not be written by third party creators
1273 WW8_FC m_fcPlcfphe = 0; // 0x98 file offset of PLCF of paragraph heights.
1274 sal_Int32 m_lcbPlcfphe = 0; // 0x9c count of bytes of paragraph height PLCF.
1275 // ==0 when file is non-complex.
1277 WW8_FC m_fcSttbfglsy = 0; // 0xa0 file offset of glossary string table.
1278 sal_Int32 m_lcbSttbfglsy = 0; // 0xa4 count of bytes of glossary string table.
1279 // == 0 for non-glossary documents.
1280 // !=0 for glossary documents.
1282 WW8_FC m_fcPlcfglsy = 0; // 0xa8 file offset of glossary PLCF.
1283 sal_Int32 m_lcbPlcfglsy = 0; // 0xac count of bytes of glossary PLCF.
1284 // == 0 for non-glossary documents.
1285 // !=0 for glossary documents.
1287 WW8_FC m_fcPlcfhdd = 0; // 0xb0 byte offset of header PLCF.
1288 sal_Int32 m_lcbPlcfhdd = 0; // 0xb4 count of bytes of header PLCF.
1289 // == 0 if document contains no headers
1291 WW8_FC m_fcPlcfbteChpx = 0; // 0xb8 file offset of character property bin table.PLCF.
1292 sal_Int32 m_lcbPlcfbteChpx = 0;// 0xbc count of bytes of character property bin table PLCF.
1294 WW8_FC m_fcPlcfbtePapx = 0; // 0xc0 file offset of paragraph property bin table.PLCF.
1295 sal_Int32 m_lcbPlcfbtePapx = 0;// 0xc4 count of bytes of paragraph property bin table PLCF.
1297 WW8_FC m_fcPlcfsea = 0; // 0xc8 file offset of PLCF reserved for private use. The SEA is 6 bytes long.
1298 sal_Int32 m_lcbPlcfsea = 0; // 0xcc count of bytes of private use PLCF.
1300 WW8_FC m_fcSttbfffn = 0; // 0xd0 file offset of font information STTBF. See the FFN file structure definition.
1301 sal_Int32 m_lcbSttbfffn = 0; // 0xd4 count of bytes in sttbfffn.
1303 WW8_FC m_fcPlcffldMom = 0; // 0xd8 offset in doc stream to the PLCF of field positions in the main document.
1304 sal_Int32 m_lcbPlcffldMom = 0; // 0xdc
1306 WW8_FC m_fcPlcffldHdr = 0; // 0xe0 offset in doc stream to the PLCF of field positions in the header subdocument.
1307 sal_Int32 m_lcbPlcffldHdr = 0; // 0xe4
1309 WW8_FC m_fcPlcffldFootnote = 0; // 0xe8 offset in doc stream to the PLCF of field positions in the footnote subdocument.
1310 sal_Int32 m_lcbPlcffldFootnote = 0; // 0xec
1312 WW8_FC m_fcPlcffldAtn = 0; // 0xf0 offset in doc stream to the PLCF of field positions in the annotation subdocument.
1313 sal_Int32 m_lcbPlcffldAtn = 0; // 0xf4
1315 WW8_FC m_fcPlcffldMcr = 0; // 0xf8 offset in doc stream to the PLCF of field positions in the macro subdocument.
1316 sal_Int32 m_lcbPlcffldMcr = 0; // 9xfc
1318 WW8_FC m_fcSttbfbkmk = 0; // 0x100 offset in document stream of the STTBF that records bookmark names in the main document
1319 sal_Int32 m_lcbSttbfbkmk = 0; // 0x104
1321 WW8_FC m_fcPlcfbkf = 0; // 0x108 offset in document stream of the PLCF that records the beginning CP offsets of bookmarks in the main document. See BKF
1322 sal_Int32 m_lcbPlcfbkf = 0; // 0x10c
1324 WW8_FC m_fcPlcfbkl = 0; // 0x110 offset in document stream of the PLCF that records the ending CP offsets of bookmarks recorded in the main document. See the BKL structure definition.
1325 sal_Int32 m_lcbPlcfbkl = 0; // 0x114 sal_Int32
1327 WW8_FC m_fcCmds = 0; // 0x118 FC
1328 sal_uInt32 m_lcbCmds = 0; // 0x11c
1330 WW8_FC m_fcPlcfmcr = 0; // 0x120 FC
1331 sal_Int32 m_lcbPlcfmcr = 0; // 0x124
1333 WW8_FC m_fcSttbfmcr = 0; // 0x128 FC
1334 sal_Int32 m_lcbSttbfmcr = 0; // 0x12c
1336 WW8_FC m_fcPrDrvr = 0; // 0x130 file offset of the printer driver information (names of drivers, port etc...)
1337 sal_Int32 m_lcbPrDrvr = 0; // 0x134 count of bytes of the printer driver information (names of drivers, port etc...)
1339 WW8_FC m_fcPrEnvPort = 0; // 0x138 file offset of the print environment in portrait mode.
1340 sal_Int32 m_lcbPrEnvPort = 0; // 0x13c count of bytes of the print environment in portrait mode.
1342 WW8_FC m_fcPrEnvLand = 0; // 0x140 file offset of the print environment in landscape mode.
1343 sal_Int32 m_lcbPrEnvLand = 0; // 0x144 count of bytes of the print environment in landscape mode.
1345 WW8_FC m_fcWss = 0; // 0x148 file offset of Window Save State data structure. See WSS.
1346 sal_Int32 m_lcbWss = 0; // 0x14c count of bytes of WSS. ==0 if unable to store the window state.
1348 WW8_FC m_fcDop = 0; // 0x150 file offset of document property data structure.
1349 sal_uInt32 m_lcbDop = 0; // 0x154 count of bytes of document properties.
1350 // cbDOP is 84 when nFib < 103
1352 WW8_FC m_fcSttbfAssoc = 0; // 0x158 offset to STTBF of associated strings. See STTBFASSOC.
1353 sal_Int32 m_lcbSttbfAssoc = 0; // 0x15C
1355 WW8_FC m_fcClx = 0; // 0x160 file offset of beginning of information for complex files.
1356 sal_Int32 m_lcbClx = 0; // 0x164 count of bytes of complex file information. 0 if file is non-complex.
1358 WW8_FC m_fcPlcfpgdFootnote = 0; // 0x168 file offset of page descriptor PLCF for footnote subdocument.
1359 sal_Int32 m_lcbPlcfpgdFootnote = 0; // 0x16C count of bytes of page descriptor PLCF for footnote subdocument.
1360 // ==0 if document has not been paginated. The length of the PGD is 8 bytes.
1362 WW8_FC m_fcAutosaveSource = 0; // 0x170 file offset of the name of the original file.
1363 sal_Int32 m_lcbAutosaveSource = 0; // 0x174 count of bytes of the name of the original file.
1365 WW8_FC m_fcGrpStAtnOwners = 0; // 0x178 group of strings recording the names of the owners of annotations
1366 sal_Int32 m_lcbGrpStAtnOwners = 0; // 0x17C count of bytes of the group of strings
1368 WW8_FC m_fcSttbfAtnbkmk = 0; // 0x180 file offset of the sttbf that records names of bookmarks in the annotation subdocument
1369 sal_Int32 m_lcbSttbfAtnbkmk = 0; // 0x184 length in bytes of the sttbf that records names of bookmarks in the annotation subdocument
1371 // end of WW67 section
1373 WW8_FC m_fcPlcfdoaMom = 0; // 0x192 file offset of the FDOA (drawn object) PLCF for main document.
1374 // ==0 if document has no drawn objects. The length of the FDOA is 6 bytes.
1375 // unused starting from Ver8
1376 sal_Int32 m_lcbPlcfdoaMom = 0; // 0x196 length in bytes of the FDOA PLCF of the main document
1377 // unused starting from Ver8
1378 WW8_FC m_fcPlcfdoaHdr = 0; // 0x19A file offset of the FDOA (drawn object) PLCF for the header document.
1379 // ==0 if document has no drawn objects. The length of the FDOA is 6 bytes.
1380 // unused starting from Ver8
1381 sal_Int32 m_lcbPlcfdoaHdr = 0; // 0x19E length in bytes of the FDOA PLCF of the header document
1382 // unused starting from Ver8
1384 WW8_FC m_fcPlcfspaMom = 0; // offset in table stream of the FSPA PLCF for main document.
1385 // == 0 if document has no office art objects
1386 // was empty reserve in Ver67
1387 sal_Int32 m_lcbPlcfspaMom = 0; // length in bytes of the FSPA PLCF of the main document
1388 // was empty reserve in Ver67
1389 WW8_FC m_fcPlcfspaHdr = 0; // offset in table stream of the FSPA PLCF for header document.
1390 // == 0 if document has no office art objects
1391 // was empty reserve in Ver67
1392 sal_Int32 m_lcbPlcfspaHdr = 0; // length in bytes of the FSPA PLCF of the header document
1393 // was empty reserve in Ver67
1395 WW8_FC m_fcPlcfAtnbkf = 0; // 0x1B2 file offset of BKF (bookmark first) PLCF of the annotation subdocument
1396 sal_Int32 m_lcbPlcfAtnbkf = 0; // 0x1B6 length in bytes of BKF (bookmark first) PLCF of the annotation subdocument
1398 WW8_FC m_fcPlcfAtnbkl = 0; // 0x1BA file offset of BKL (bookmark last) PLCF of the annotation subdocument
1399 sal_Int32 m_lcbPlcfAtnbkl = 0; // 0x1BE length in bytes of BKL (bookmark first) PLCF of the annotation subdocument
1401 WW8_FC m_fcPms = 0; // 0x1C2 file offset of PMS (Print Merge State) information block
1402 sal_Int32 m_lcbPMS = 0; // 0x1C6 length in bytes of PMS
1404 WW8_FC m_fcFormFieldSttbf = 0; // 0x1CA file offset of form field Sttbf which contains strings used in form field dropdown controls
1405 sal_Int32 m_lcbFormFieldSttbf = 0; // 0x1CE length in bytes of form field Sttbf
1407 WW8_FC m_fcPlcfendRef = 0; // 0x1D2 file offset of PLCFendRef which points to endnote references in the main document stream
1408 sal_Int32 m_lcbPlcfendRef = 0; // 0x1D6
1410 WW8_FC m_fcPlcfendText = 0; // 0x1DA file offset of PLCFendRef which points to endnote text in the endnote document
1411 // stream which corresponds with the PLCFendRef
1412 sal_Int32 m_lcbPlcfendText = 0; // 0x1DE
1414 WW8_FC m_fcPlcffldEdn = 0; // 0x1E2 offset to PLCF of field positions in the endnote subdoc
1415 sal_Int32 m_lcbPlcffldEdn = 0; // 0x1E6
1417 WW8_FC m_fcPlcfpgdEdn = 0; // 0x1EA offset to PLCF of page boundaries in the endnote subdoc.
1418 sal_Int32 m_lcbPlcfpgdEdn = 0; // 0x1EE
1420 WW8_FC m_fcDggInfo = 0; // offset in table stream of the office art object table data.
1421 // The format of office art object table data is found in a separate document.
1422 // was empty reserve in Ver67
1423 sal_Int32 m_lcbDggInfo = 0; // length in bytes of the office art object table data
1424 // was empty reserve in Ver67
1426 WW8_FC m_fcSttbfRMark = 0; // 0x1fa offset to STTBF that records the author abbreviations...
1427 sal_Int32 m_lcbSttbfRMark = 0; // 0x1fe
1428 WW8_FC m_fcSttbfCaption = 0; // 0x202 offset to STTBF that records caption titles...
1429 sal_Int32 m_lcbSttbfCaption = 0; // 0x206
1430 WW8_FC m_fcSttbAutoCaption = 0; // offset in table stream to the STTBF that records the object names and
1431 // indices into the caption STTBF for objects which get auto captions.
1432 sal_Int32 m_lcbSttbAutoCaption = 0; // 0x20e
1434 WW8_FC m_fcPlcfwkb = 0; // 0x212 offset to PLCF that describes the boundaries of contributing documents...
1435 sal_Int32 m_lcbPlcfwkb = 0; // 0x216
1437 WW8_FC m_fcPlcfspl = 0; // offset in table stream of PLCF (of SPLS structures) that records spell check state
1438 // was empty reserve in Ver67
1439 sal_Int32 m_lcbPlcfspl = 0; // was empty reserve in Ver67
1441 WW8_FC m_fcPlcftxbxText = 0; // 0x222 ...PLCF of beginning CP in the text box subdoc
1442 sal_Int32 m_lcbPlcftxbxText = 0; // 0x226
1443 WW8_FC m_fcPlcffldTxbx = 0; // 0x22a ...PLCF of field boundaries recorded in the textbox subdoc.
1444 sal_Int32 m_lcbPlcffldTxbx = 0; // 0x22e
1445 WW8_FC m_fcPlcfHdrtxbxText = 0;// 0x232 ...PLCF of beginning CP in the header text box subdoc
1446 sal_Int32 m_lcbPlcfHdrtxbxText = 0;// 0x236
1447 WW8_FC m_fcPlcffldHdrTxbx = 0;// 0x23a ...PLCF of field boundaries recorded in the header textbox subdoc.
1448 sal_Int32 m_lcbPlcffldHdrTxbx = 0;// 0x23e
1449 WW8_FC m_fcStwUser = 0;
1450 sal_uInt32 m_lcbStwUser = 0;
1451 WW8_FC m_fcSttbttmbd = 0;
1452 sal_uInt32 m_lcbSttbttmbd = 0;
1454 WW8_FC m_fcSttbFnm = 0; // 0x02da offset in the table stream of masters subdocument names
1455 sal_Int32 m_lcbSttbFnm = 0; // 0x02de length
1458 special list handling for WW8
1460 WW8_FC m_fcPlcfLst = 0; // 0x02e2 offset in the table stream of list format information.
1461 sal_Int32 m_lcbPlcfLst = 0; // 0x02e6 length
1462 WW8_FC m_fcPlfLfo = 0; // 0x02ea offset in the table stream of list format override information.
1463 sal_Int32 m_lcbPlfLfo = 0; // 0x02ee length
1465 special Break handling for text-box-stories in WW8
1467 WW8_FC m_fcPlcftxbxBkd = 0; // 0x02f2 PLCF for TextBox-Break-descriptors in the Maintext
1468 sal_Int32 m_lcbPlcftxbxBkd = 0; // 0x02f6
1469 WW8_FC m_fcPlcfHdrtxbxBkd = 0;// 0x02fa PLCF for TextBox-Break-descriptors in the Header-/Footer- area
1470 sal_Int32 m_lcbPlcfHdrtxbxBkd = 0;// 0x02fe
1472 // 0x302 - 372 == ignore
1474 ListNames (skip to here!)
1476 WW8_FC m_fcSttbListNames = 0;// 0x0372 PLCF for Listname Table
1477 sal_Int32 m_lcbSttbListNames = 0;// 0x0376
1479 WW8_FC m_fcPlcfTch = 0;
1480 sal_Int32 m_lcbPlcfTch = 0;
1482 // 0x38A - 41A == ignore
1483 WW8_FC m_fcAtrdExtra = 0;
1484 sal_uInt32 m_lcbAtrdExtra = 0;
1486 // 0x422 - 0x429 == ignore
1488 /// 0x42a smart-tag bookmark string table offset.
1489 WW8_FC m_fcSttbfBkmkFactoid = 0;
1490 /// 0x42e smart-tag bookmark string table length.
1491 sal_uInt32 m_lcbSttbfBkmkFactoid = 0;
1492 /// 0x432 smart-tag bookmark starts offset.
1493 WW8_FC m_fcPlcfBkfFactoid = 0;
1494 /// 0x436 smart-tag bookmark ends length.
1495 sal_uInt32 m_lcbPlcfBkfFactoid = 0;
1497 // 0x43a - 0x441 == ignore
1499 /// 0x442 smart-tag bookmark ends offset.
1500 WW8_FC m_fcPlcfBklFactoid = 0;
1501 /// 0x446 smart-tag bookmark ends length.
1502 sal_uInt32 m_lcbPlcfBklFactoid = 0;
1503 /// 0x44a smart tag data offset.
1504 WW8_FC m_fcFactoidData = 0;
1505 /// 0x44e smart tag data length.
1506 sal_uInt32 m_lcbFactoidData = 0;
1508 // 0x452 - 0x4b9 == ignore
1510 /// 0x4ba Plcffactoid offset.
1511 WW8_FC m_fcPlcffactoid = 0;
1512 /// 0x4be Plcffactoid offset.
1513 sal_uInt32 m_lcbPlcffactoid = 0;
1515 // 0x4bf - 0x4d4 == ignore
1517 WW8_FC m_fcHplxsdr = 0; //bizarrely, word xp seems to require this set to shows dates from AtrdExtra
1518 sal_uInt32 m_lcbHplxsdr = 0;
1521 general variables that were used for Ver67 and Ver8,
1522 even though they had different sizes in the corresponding files:
1524 sal_Int32 m_pnChpFirst = 0;
1525 sal_Int32 m_pnPapFirst = 0;
1526 sal_Int32 m_cpnBteChp = 0;
1527 sal_Int32 m_cpnBtePap = 0;
1529 The actual nFib, moved here because some readers assumed
1530 they couldn't read any format with nFib > some constant
1532 sal_uInt16 m_nFib_actual = 0; // 0x05bc #i56856#
1534 WW8Fib(SvStream& rStrm, sal_uInt8 nWantedVersion,sal_uInt32 nOffset=0);
1535 explicit WW8Fib(sal_uInt8 nVersion, bool bDot = false);
1537 void WriteHeader(SvStream& rStrm);
1538 void Write(SvStream& rStrm);
1539 static rtl_TextEncoding GetFIBCharset(sal_uInt16 chs, LanguageType nLidLocale);
1540 ww::WordVersion GetFIBVersion() const;
1541 bool GetBaseCp(ManTypes nType, WW8_CP * cp) const;
1542 sal_Unicode getNumDecimalSep() const { return m_nNumDecimalSep;}
1545 class WW8Style
1547 protected:
1548 WW8Fib& m_rFib;
1549 SvStream& m_rStream;
1551 sal_uInt16 m_cstd; // Count of styles in stylesheet
1552 sal_uInt16 m_cbSTDBaseInFile; // Length of STD Base as stored in a file
1553 sal_uInt16 m_fStdStylenamesWritten : 1; // Are built-in stylenames stored?
1554 sal_uInt16 : 15; // Spare flags
1555 sal_uInt16 m_stiMaxWhenSaved; // Max sti known when file was written
1556 sal_uInt16 m_istdMaxFixedWhenSaved; // How many fixed-index istds are there?
1557 sal_uInt16 m_nVerBuiltInNamesWhenSaved; // Current version of built-in stylenames
1558 // ftc used by StandardChpStsh for this document
1559 sal_uInt16 m_ftcAsci;
1560 // CJK ftc used by StandardChpStsh for this document
1561 sal_uInt16 m_ftcFE;
1562 // CTL/Other ftc used by StandardChpStsh for this document
1563 sal_uInt16 m_ftcOther;
1564 // CTL ftc used by StandardChpStsh for this document
1565 sal_uInt16 m_ftcBi;
1567 //No copying
1568 WW8Style(const WW8Style&);
1569 WW8Style& operator=(const WW8Style&);
1571 public:
1572 WW8Style( SvStream& rSt, WW8Fib& rFibPara );
1573 std::unique_ptr<WW8_STD> Read1STDFixed(sal_uInt16& rSkip);
1574 std::unique_ptr<WW8_STD> Read1Style(sal_uInt16& rSkip, OUString* pString);
1575 sal_uInt16 GetCount() const { return m_cstd; }
1578 class WW8Fonts final
1580 private:
1581 WW8Fonts(const WW8Fonts&) = delete;
1582 WW8Fonts& operator=(const WW8Fonts&) = delete;
1584 std::vector<WW8_FFN> m_aFontA; // Array of Pointers to Font Description
1586 public:
1587 WW8Fonts( SvStream& rSt, WW8Fib const & rFib );
1588 const WW8_FFN* GetFont( sal_uInt16 nNum ) const;
1589 sal_uInt16 GetMax() const { return m_aFontA.size(); }
1592 typedef sal_uInt8 HdFtFlags;
1593 namespace nsHdFtFlags
1595 const HdFtFlags WW8_HEADER_EVEN = 0x01;
1596 const HdFtFlags WW8_HEADER_ODD = 0x02;
1597 const HdFtFlags WW8_FOOTER_EVEN = 0x04;
1598 const HdFtFlags WW8_FOOTER_ODD = 0x08;
1599 const HdFtFlags WW8_HEADER_FIRST = 0x10;
1600 const HdFtFlags WW8_FOOTER_FIRST = 0x20;
1603 /// Document Properties
1604 struct WW8Dop
1606 public:
1607 /* Error Status */
1608 ErrCode nDopError;
1610 Corresponds only roughly to the actual structure of the Winword DOP,
1611 the winword FIB version matters to what exists.
1613 bool fFacingPages : 1 /*= false*/; // 1 when facing pages should be printed
1615 bool fWidowControl : 1 /*= false*/; //a: orig 97 docs say
1616 // 1 when widow control is in effect. 0 when widow control disabled.
1617 //b: MS-DOC: Word Binary File Format (.doc) Structure Specification 2008 says
1618 // B - unused1 (1 bit): Undefined and MUST be ignored.
1620 bool fPMHMainDoc : 1 /*= false*/; // 1 when doc is a main doc for Print Merge Helper, 0 when not; default=0
1621 sal_uInt16 grfSuppression : 2 /*= 0*/; // 0 Default line suppression storage; 0= form letter line suppression; 1= no line suppression; default=0
1622 sal_uInt16 fpc : 2 /*= 0*/; // 1 footnote position code: 0 as endnotes, 1 at bottom of page, 2 immediately beneath text
1623 sal_uInt16 : 1; // 0 unused
1625 sal_uInt16 grpfIhdt : 8 /*= 0*/; // 0 specification of document headers and footers. See explanation under Headers and Footers topic.
1627 sal_uInt16 rncFootnote : 2 /*= 0*/; // 0 restart index for footnotes, 0 don't restart note numbering, 1 section, 2 page
1628 sal_uInt16 nFootnote : 14 /*= 0*/; // 1 initial footnote number for document
1629 bool fOutlineDirtySave : 1 /*= false*/; // when 1, indicates that information in the hPLCFpad should be refreshed since outline has been dirtied
1630 sal_uInt16 : 7; // reserved
1631 bool fOnlyMacPics : 1 /*= false*/; // when 1, Word believes all pictures recorded in the document were created on a Macintosh
1632 bool fOnlyWinPics : 1 /*= false*/; // when 1, Word believes all pictures recorded in the document were created in Windows
1633 bool fLabelDoc : 1 /*= false*/; // when 1, document was created as a print merge labels document
1634 bool fHyphCapitals : 1 /*= false*/; // when 1, Word is allowed to hyphenate words that are capitalized. When 0, capitalized may not be hyphenated
1635 bool fAutoHyphen : 1 /*= false*/; // when 1, Word will hyphenate newly typed text as a background task
1636 bool fFormNoFields : 1 /*= false*/;
1637 bool fLinkStyles : 1 /*= false*/; // when 1, Word will merge styles from its template
1638 bool fRevMarking : 1 /*= false*/; // when 1, Word will mark revisions as the document is edited
1639 bool fBackup : 1 /*= false*/; // always make backup when document saved when 1.
1640 bool fExactCWords : 1 /*= false*/;
1641 bool fPagHidden : 1 /*= false*/;
1642 bool fPagResults : 1 /*= false*/;
1643 bool fLockAtn : 1 /*= false*/; // when 1, annotations are locked for editing
1644 bool fMirrorMargins : 1 /*= false*/; // swap margins on left/right pages when 1.
1645 bool fReadOnlyRecommended : 1 /*= false*/;// user has recommended that this doc be opened read-only when 1
1646 bool fDfltTrueType : 1 /*= false*/; // when 1, use TrueType fonts by default (flag obeyed only when doc was created by WinWord 2.x)
1647 bool fPagSuppressTopSpacing : 1 /*= false*/;//when 1, file created with SUPPRESSTOPSPACING=YES in win.ini. (flag obeyed only when doc was created by WinWord 2.x).
1648 bool fProtEnabled : 1 /*= false*/; // when 1, document is protected from edit operations
1649 bool fDispFormFieldSel : 1 /*= false*/;// when 1, restrict selections to occur only within form fields
1650 bool fRMView : 1 /*= false*/; // when 1, show revision markings on screen
1651 bool fRMPrint : 1 /*= false*/; // when 1, print revision marks when document is printed
1652 bool fWriteReservation : 1 /*= false*/;
1653 bool fLockRev : 1 /*= false*/; // when 1, the current revision marking state is locked
1654 bool fEmbedFonts : 1 /*= false*/; // when 1, document contains embedded True Type fonts
1655 // compatibility options
1656 bool copts_fNoTabForInd : 1 /*= false*/; // when 1, don't add automatic tab stops for hanging indent
1657 bool copts_fNoSpaceRaiseLower : 1 /*= false*/; // when 1, don't add extra space for raised or lowered characters
1658 bool copts_fSuppressSpbfAfterPgBrk : 1 /*= false*/; // when 1, suppress the paragraph Space Before and Space After options after a page break
1659 bool copts_fWrapTrailSpaces : 1 /*= false*/; // when 1, wrap trailing spaces at the end of a line to the next line
1660 bool copts_fMapPrintTextColor : 1 /*= false*/; // when 1, print colors as black on non-color printers
1661 bool copts_fNoColumnBalance : 1 /*= false*/; // when 1, don't balance columns for Continuous Section starts
1662 bool copts_fConvMailMergeEsc : 1 /*= false*/;
1663 bool copts_fSuppressTopSpacing : 1 /*= false*/; // when 1, suppress extra line spacing at top of page
1664 bool copts_fOrigWordTableRules : 1 /*= false*/; // when 1, combine table borders like Word 5.x for the Macintosh
1665 bool copts_fTransparentMetafiles : 1 /*= false*/; // when 1, don't blank area between metafile pictures
1666 bool copts_fShowBreaksInFrames : 1 /*= false*/; // when 1, show hard page or column breaks in frames
1667 bool copts_fSwapBordersFacingPgs : 1 /*= false*/; // when 1, swap left and right pages on odd facing pages
1668 bool copts_fExpShRtn : 1 /*= false*/; // when 1, expand character spaces on the line ending SHIFT+RETURN // #i56856#
1670 sal_Int16 dxaTab = 0; // 720 twips - default tab width
1671 sal_uInt16 wSpare = 0;
1672 sal_uInt16 dxaHotZ = 0; // width of hyphenation hot zone measured in twips
1673 sal_uInt16 cConsecHypLim = 0; // number of lines allowed to have consecutive hyphens
1674 sal_uInt16 wSpare2 = 0; // reserved
1675 sal_Int32 dttmCreated = 0; // DTTM date and time document was created
1676 sal_Int32 dttmRevised = 0; // DTTM date and time document was last revised
1677 sal_Int32 dttmLastPrint = 0; // DTTM date and time document was last printed
1678 sal_Int16 nRevision = 0; // number of times document has been revised since its creation
1679 sal_Int32 tmEdited = 0; // time document was last edited
1680 sal_Int32 cWords = 0; // count of words tallied by last Word Count execution
1681 sal_Int32 cCh = 0; // count of characters tallied by last Word Count execution
1682 sal_Int16 cPg = 0; // count of pages tallied by last Word Count execution
1683 sal_Int32 cParas = 0; // count of paragraphs tallied by last Word Count execution
1684 sal_uInt16 rncEdn : 2 /*= 0*/; // restart endnote number code: 0 don't restart endnote numbering, 1 section, 2 page
1685 sal_uInt16 nEdn : 14 /*= 0*/; // beginning endnote number
1686 sal_uInt16 epc : 2 /*= 0*/; // endnote position code: 0 at end of section, 3 at end of document
1688 bool fPrintFormData : 1 /*= false*/; // only print data inside of form fields
1689 bool fSaveFormData : 1 /*= false*/; // only save document data that is inside of a form field.
1690 bool fShadeFormData : 1 /*= false*/; // shade form fields
1691 sal_uInt16 : 2; // reserved
1692 bool fWCFootnoteEdn : 1 /*= false*/; // when 1, include footnotes and endnotes in word count
1693 sal_Int32 cLines = 0; // count of lines tallied by last Word Count operation
1694 sal_Int32 cWordsFootnoteEnd = 0; // count of words in footnotes and endnotes tallied by last Word Count operation
1695 sal_Int32 cChFootnoteEdn = 0; // count of characters in footnotes and endnotes tallied by last Word Count operation
1696 sal_Int16 cPgFootnoteEdn = 0; // count of pages in footnotes and endnotes tallied by last Word Count operation
1697 sal_Int32 cParasFootnoteEdn = 0; // count of paragraphs in footnotes and endnotes tallied by last Word Count operation
1698 sal_Int32 cLinesFootnoteEdn = 0; // count of paragraphs in footnotes and endnotes tallied by last Word Count operation
1699 sal_Int32 lKeyProtDoc = 0; // document protection password key, only valid if dop.fProtEnabled, dop.fLockAtn or dop.fLockRev are 1.
1700 sal_uInt16 wvkSaved : 3 /*= 0*/; // document view kind: 0 Normal view, 1 Outline view, 2 Page View
1701 sal_uInt16 wScaleSaved : 9 /*= 0*/; ///< Specifies the zoom percentage that was in use when the document was saved.
1702 sal_uInt16 zkSaved : 2 /*= 0*/; // document zoom type: 0 percent, 1 whole/entire page, 2 page width, 3 text width/optimal
1703 bool fRotateFontW6 : 1 /*= false*/;
1704 bool iGutterPos : 1 /*= false*/;
1706 // this should be the end for nFib < 103, otherwise the file is broken!
1709 for nFib >= 103 it continues:
1711 bool fNoTabForInd : 1 /*= false*/; // see above in compatibility options
1712 bool fNoSpaceRaiseLower : 1 /*= false*/; // see above
1713 bool fSuppressSpbfAfterPageBreak : 1 /*= false*/; // see above
1714 bool fWrapTrailSpaces : 1 /*= false*/; // see above
1715 bool fMapPrintTextColor : 1 /*= false*/; // see above
1716 bool fNoColumnBalance : 1 /*= false*/; // see above
1717 bool fConvMailMergeEsc : 1 /*= false*/; // see above
1718 bool fSuppressTopSpacing : 1 /*= false*/; // see above
1719 bool fOrigWordTableRules : 1 /*= false*/; // see above
1720 bool fTransparentMetafiles : 1 /*= false*/; // see above
1721 bool fShowBreaksInFrames : 1 /*= false*/; // see above
1722 bool fSwapBordersFacingPgs : 1 /*= false*/; // see above
1723 bool fCompatibilityOptions_Unknown1_13 : 1 /*= false*/; // #i78591#
1724 bool fExpShRtn : 1 /*= false*/; // #i78591# and #i56856#
1725 bool fCompatibilityOptions_Unknown1_15 : 1 /*= false*/; // #i78591#
1726 bool fCompatibilityOptions_Unknown1_16 : 1 /*= false*/; // #i78591#
1727 bool fSuppressTopSpacingMac5 : 1 /*= false*/; // Suppress extra line spacing at top
1728 // of page like MacWord 5.x
1729 bool fTruncDxaExpand : 1 /*= false*/; // Expand/Condense by whole number of points
1730 bool fPrintBodyBeforeHdr : 1 /*= false*/; // Print body text before header/footer
1731 bool fNoLeading : 1 /*= false*/; // Don't add extra spacebetween rows of text
1732 bool fCompatibilityOptions_Unknown1_21 : 1 /*= false*/; // #i78591#
1733 bool fMWSmallCaps : 1 /*= false*/; // Use larger small caps like MacWord 5.x
1734 bool fCompatibilityOptions_Unknown1_23 : 1 /*= false*/; // #i78591#
1735 bool fCompatibilityOptions_Unknown1_24 : 1 /*= false*/; // #i78591#
1736 bool fCompatibilityOptions_Unknown1_25 : 1 /*= false*/; // #i78591#
1737 bool fCompatibilityOptions_Unknown1_26 : 1 /*= false*/; // #i78591#
1738 bool fCompatibilityOptions_Unknown1_27 : 1 /*= false*/; // #i78591#
1739 bool fCompatibilityOptions_Unknown1_28 : 1 /*= false*/; // #i78591#
1740 bool fCompatibilityOptions_Unknown1_29 : 1 /*= false*/; // #i78591#
1741 bool fCompatibilityOptions_Unknown1_30 : 1 /*= false*/; // #i78591#
1742 bool fCompatibilityOptions_Unknown1_31 : 1 /*= false*/; // #i78591#
1743 bool fUsePrinterMetrics : 1 /*= false*/; //The magic option
1745 // this should be the end for nFib <= 105, otherwise the file is broken!
1748 for nFib > 105 it continues:
1750 sal_Int16 adt = 0; // Autoformat Document Type:
1751 // 0 for normal.
1752 // 1 for letter, and
1753 // 2 for email.
1754 WW8DopTypography doptypography = {}; // see WW8STRUC.HXX
1755 WW8_DOGRID dogrid = {}; // see WW8STRUC.HXX
1756 sal_uInt16 : 1; // reserved
1757 sal_uInt16 lvl : 4 /*= 0*/; // Which outline levels are showing in outline view
1758 sal_uInt16 : 4; // reserved
1759 bool fHtmlDoc : 1 /*= false*/; // This file is based upon an HTML file
1760 sal_uInt16 : 1; // reserved
1761 bool fSnapBorder : 1 /*= false*/; // Snap table and page borders to page border
1762 bool fIncludeHeader : 1 /*= false*/; // Place header inside page border
1763 bool fIncludeFooter : 1 /*= false*/; // Place footer inside page border
1764 bool fForcePageSizePag : 1 /*= false*/; // Are we in online view
1765 bool fMinFontSizePag : 1 /*= false*/; // Are we auto-promoting fonts to >= hpsZoomFontPag?
1766 bool fHaveVersions : 1 /*= false*/; // versioning is turned on
1767 bool fAutoVersion : 1 /*= false*/; // autoversioning is enabled
1768 sal_uInt16 : 14; // reserved
1769 // Skip 12 Bytes here: ASUMI
1770 sal_Int32 cChWS = 0;
1771 sal_Int32 cChWSFootnoteEdn = 0;
1772 sal_Int32 grfDocEvents = 0;
1773 // Skip 4+30+8 Bytes here
1774 sal_Int32 cDBC = 0;
1775 sal_Int32 cDBCFootnoteEdn = 0;
1776 // Skip 4 Bytes here
1777 sal_Int16 nfcFootnoteRef = 0;
1778 sal_Int16 nfcEdnRef = 0;
1779 sal_Int16 hpsZoomFontPag = 0;
1780 sal_Int16 dywDispPag = 0;
1782 // [MS-DOC] 2.7.11 Copts A..H
1783 bool fCompatibilityOptions_Unknown2_1 : 1 /*= false*/; // #i78591#
1784 bool fCompatibilityOptions_Unknown2_2 : 1 /*= false*/; // #i78591#
1785 bool fDontUseHTMLAutoSpacing : 1 /*= false*/;
1786 bool fCompatibilityOptions_Unknown2_4 : 1 /*= false*/; // #i78591#
1787 bool fCompatibilityOptions_Unknown2_5 : 1 /*= false*/; // #i78591#
1788 bool fCompatibilityOptions_Unknown2_6 : 1 /*= false*/; // #i78591#
1789 bool fCompatibilityOptions_Unknown2_7 : 1 /*= false*/; // #i78591#
1790 bool fCompatibilityOptions_Unknown2_8 : 1 /*= false*/; // #i78591#
1792 // [MS-DOC] 2.7.11 Copts I..P
1793 bool fCompatibilityOptions_Unknown2_9 : 1 /*= false*/; // #i78591#
1794 bool fCompatibilityOptions_Unknown2_10 : 1 /*= false*/; // #i78591#
1795 bool fDontBreakWrappedTables : 1 /*= false*/; // #i78591#
1796 bool fCompatibilityOptions_Unknown2_12 : 1 /*= false*/; // #i78591#
1797 bool fCompatibilityOptions_Unknown2_13 : 1 /*= false*/; // #i78591#
1798 bool fCompatibilityOptions_Unknown2_14 : 1 /*= false*/; // #i78591#
1799 bool fCompatibilityOptions_Unknown2_15 : 1 /*= false*/; // #i78591#
1801 // [MS-DOC] 2.7.11 Copts Q..X
1802 bool fCompatibilityOptions_Unknown2_16 : 1 /*= false*/; // #i78591#
1803 bool fCompatibilityOptions_Unknown2_17 : 1 /*= false*/; // #i78591#
1804 bool fCompatibilityOptions_Unknown2_18 : 1 /*= false*/; // #i78591#
1805 bool fCompatibilityOptions_Unknown2_19 : 1 /*= false*/; // #i78591#
1806 bool fCompatibilityOptions_Unknown2_20 : 1 /*= false*/; // #i78591#
1807 bool fCompatibilityOptions_Unknown2_21 : 1 /*= false*/; // #i78591#
1808 bool fCompatibilityOptions_Unknown2_22 : 1 /*= false*/; // #i78591#
1809 bool fCompatibilityOptions_Unknown2_23 : 1 /*= false*/; // #i78591#
1811 // [MS-DOC] 2.7.11 Copts Y..f
1812 bool fCompatibilityOptions_Unknown2_24 : 1 /*= false*/; // #i78591#
1813 bool fCompatibilityOptions_Unknown2_25 : 1 /*= false*/; // #i78591#
1814 bool fCompatibilityOptions_Unknown2_26 : 1 /*= false*/; // #i78591#
1815 bool fCompatibilityOptions_Unknown2_27 : 1 /*= false*/; // #i78591#
1816 bool fCompatibilityOptions_Unknown2_28 : 1 /*= false*/; // #i78591#
1817 bool fCompatibilityOptions_Unknown2_29 : 1 /*= false*/; // #i78591#
1818 bool fCompatibilityOptions_Unknown2_30 : 1 /*= false*/; // #i78591#
1819 bool fCompatibilityOptions_Unknown2_31 : 1 /*= false*/; // #i78591#
1821 // [MS-DOC] 2.7.11 Copts g
1822 bool fCompatibilityOptions_Unknown2_32 : 1 /*= false*/; // #i78591#
1824 sal_uInt16 fUnknown3 : 15 /*= 0*/;
1825 bool fUseBackGroundInAllmodes : 1 /*= false*/;
1827 bool fDoNotEmbedSystemFont : 1 /*= false*/;
1828 bool fWordCompat : 1 /*= false*/;
1829 bool fLiveRecover : 1 /*= false*/;
1830 bool fEmbedFactoids : 1 /*= false*/;
1831 bool fFactoidXML : 1 /*= false*/;
1832 bool fFactoidAllDone : 1 /*= false*/;
1833 bool fFolioPrint : 1 /*= false*/;
1834 bool fReverseFolio : 1 /*= false*/;
1835 sal_uInt16 iTextLineEnding : 3 /*= 0*/;
1836 bool fHideFcc : 1 /*= false*/;
1837 bool fAcetateShowMarkup : 1 /*= false*/;
1838 bool fAcetateShowAtn : 1 /*= false*/;
1839 bool fAcetateShowInsDel : 1 /*= false*/;
1840 bool fAcetateShowProps : 1 /*= false*/;
1842 bool bUseThaiLineBreakingRules = false;
1844 /* Constructor for importing, needs to know the version of word used */
1845 WW8Dop(SvStream& rSt, sal_Int16 nFib, sal_Int32 nPos, sal_uInt32 nSize);
1847 /* Constructs default DOP suitable for exporting */
1848 WW8Dop();
1849 void Write(SvStream& rStrm, WW8Fib& rFib) const;
1851 sal_uInt32 GetCompatibilityOptions() const;
1852 void SetCompatibilityOptions(sal_uInt32 a32Bit);
1853 // i#78591#
1854 sal_uInt32 GetCompatibilityOptions2() const;
1855 void SetCompatibilityOptions2(sal_uInt32 a32Bit);
1858 class WW8PLCF_HdFt
1860 private:
1861 WW8PLCF m_aPLCF;
1862 short m_nIdxOffset;
1864 public:
1865 WW8PLCF_HdFt( SvStream* pSt, WW8Fib const & rFib, WW8Dop const & rDop );
1866 bool GetTextPos(sal_uInt8 grpfIhdt, sal_uInt8 nWhich, WW8_CP& rStart, WW8_CP& rLen);
1867 void GetTextPosExact(short nIdx, WW8_CP& rStart, WW8_CP& rLen);
1868 void UpdateIndex( sal_uInt8 grpfIhdt );
1871 Word2CHPX ReadWord2Chpx(SvStream &rSt, std::size_t nOffset, sal_uInt8 nSize);
1872 std::vector<sal_uInt8> ChpxToSprms(const Word2CHPX &rChpx);
1874 [[nodiscard]] bool checkRead(SvStream &rSt, void *pDest, sal_uInt32 nLength);
1876 //MS has a (slightly) inaccurate view of how many twips
1877 //are in the default letter size of a page
1878 const sal_uInt16 lLetterWidth = 12242;
1879 const sal_uInt16 lLetterHeight = 15842;
1881 #ifdef OSL_BIGENDIAN
1882 void swapEndian(sal_Unicode *pString);
1883 #endif
1885 #endif
1887 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */