LibreOffice Module sw (master) 1
ww8scan.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 <memory>
21#include "ww8scan.hxx"
22#include "ww8par.hxx"
23
24#include <cassert>
25#include <cstddef>
26#include <cstring>
27#include <algorithm>
28
30#include "sprmids.hxx"
31#include <rtl/tencinfo.h>
32#include <sal/macros.h>
33#include <sal/log.hxx>
34#include <osl/diagnose.h>
35
36#include <swerror.h>
37
38#include <comphelper/string.hxx>
40#include <i18nlangtag/lang.h>
41#include <o3tl/safeint.hxx>
42#include <tools/stream.hxx>
43
44#include <vcl/settings.hxx>
45#include <vcl/svapp.hxx>
46
47#ifdef DEBUGSPRMREADER
48#include <stdio.h>
49#endif
50
51using namespace ::com::sun::star::lang;
52
53namespace
54{
63 bool TestBeltAndBraces(SvStream& rStrm)
64 {
65 bool bRet = false;
66 sal_uInt32 nOldPos = rStrm.Tell();
67 sal_uInt16 nBelt(0);
68 rStrm.ReadUInt16( nBelt );
69 nBelt *= sizeof(sal_Unicode);
70 if (rStrm.good() && (rStrm.remainingSize() >= (nBelt + sizeof(sal_Unicode))))
71 {
72 rStrm.SeekRel(nBelt);
73 if (rStrm.good())
74 {
75 sal_Unicode cBraces(0);
76 rStrm.ReadUtf16( cBraces );
77 if (rStrm.good() && cBraces == 0)
78 bRet = true;
79 }
80 }
81 rStrm.Seek(nOldPos);
82 return bRet;
83 }
84}
85
87{
88 //double lock me
89 // WW2 Sprms
90 static const SprmInfoRow aSprms[] =
91 {
92 { 0, { 0, L_FIX} }, // "Default-sprm", will be skipped
93 { 2, { 1, L_FIX} }, // "sprmPIstd", pap.istd (style code)
94 { 3, { 0, L_VAR} }, // "sprmPIstdPermute pap.istd permutation
95 { 4, { 1, L_FIX} }, // "sprmPIncLv1" pap.istddifference
96 { 5, { 1, L_FIX} }, // "sprmPJc" pap.jc (justification)
97 { 6, { 1, L_FIX} }, // "sprmPFSideBySide" pap.fSideBySide
98 { 7, { 1, L_FIX} }, // "sprmPFKeep" pap.fKeep
99 { 8, { 1, L_FIX} }, // "sprmPFKeepFollow " pap.fKeepFollow
100 { 9, { 1, L_FIX} }, // "sprmPPageBreakBefore" pap.fPageBreakBefore
101 { 10, { 1, L_FIX} }, // "sprmPBrcl" pap.brcl
102 { 11, { 1, L_FIX} }, // "sprmPBrcp" pap.brcp
103 { 12, { 1, L_FIX} }, // "sprmPNfcSeqNumb" pap.nfcSeqNumb
104 { 13, { 1, L_FIX} }, // "sprmPNoSeqNumb" pap.nnSeqNumb
105 { 14, { 1, L_FIX} }, // "sprmPFNoLineNumb" pap.fNoLnn
106 { 15, { 0, L_VAR} }, // "?sprmPChgTabsPapx" pap.itbdMac, ...
107 { 16, { 2, L_FIX} }, // "sprmPDxaRight" pap.dxaRight
108 { 17, { 2, L_FIX} }, // "sprmPDxaLeft" pap.dxaLeft
109 { 18, { 2, L_FIX} }, // "sprmPNest" pap.dxaLeft
110 { 19, { 2, L_FIX} }, // "sprmPDxaLeft1" pap.dxaLeft1
111 { 20, { 2, L_FIX} }, // "sprmPDyaLine" pap.lspd an LSPD
112 { 21, { 2, L_FIX} }, // "sprmPDyaBefore" pap.dyaBefore
113 { 22, { 2, L_FIX} }, // "sprmPDyaAfter" pap.dyaAfter
114 { 23, { 0, L_VAR} }, // "?sprmPChgTabs" pap.itbdMac, pap.rgdxaTab, ...
115 { 24, { 1, L_FIX} }, // "sprmPFInTable" pap.fInTable
116 { 25, { 1, L_FIX} }, // "sprmPTtp" pap.fTtp
117 { 26, { 2, L_FIX} }, // "sprmPDxaAbs" pap.dxaAbs
118 { 27, { 2, L_FIX} }, // "sprmPDyaAbs" pap.dyaAbs
119 { 28, { 2, L_FIX} }, // "sprmPDxaWidth" pap.dxaWidth
120 { 29, { 1, L_FIX} }, // "sprmPPc" pap.pcHorz, pap.pcVert
121 { 30, { 2, L_FIX} }, // "sprmPBrcTop10" pap.brcTop BRC10
122 { 31, { 2, L_FIX} }, // "sprmPBrcLeft10" pap.brcLeft BRC10
123 { 32, { 2, L_FIX} }, // "sprmPBrcBottom10" pap.brcBottom BRC10
124 { 33, { 2, L_FIX} }, // "sprmPBrcRight10" pap.brcRight BRC10
125 { 34, { 2, L_FIX} }, // "sprmPBrcBetween10" pap.brcBetween BRC10
126 { 35, { 2, L_FIX} }, // "sprmPBrcBar10" pap.brcBar BRC10
127 { 36, { 2, L_FIX} }, // "sprmPFromText10" pap.dxaFromText dxa
128 { 37, { 1, L_FIX} }, // "sprmPWr" pap.wr wr
129 { 38, { 2, L_FIX} }, // "sprmPBrcTop" pap.brcTop BRC
130 { 39, { 2, L_FIX} }, // "sprmPBrcLeft" pap.brcLeft BRC
131 { 40, { 2, L_FIX} }, // "sprmPBrcBottom" pap.brcBottom BRC
132 { 41, { 2, L_FIX} }, // "sprmPBrcRight" pap.brcRight BRC
133 { 42, { 2, L_FIX} }, // "sprmPBrcBetween" pap.brcBetween BRC
134 { 43, { 2, L_FIX} }, // "sprmPBrcBar" pap.brcBar BRC word
135 { 44, { 1, L_FIX} }, // "sprmPFNoAutoHyph" pap.fNoAutoHyph
136 { 45, { 2, L_FIX} }, // "sprmPWHeightAbs" pap.wHeightAbs w
137 { 46, { 2, L_FIX} }, // "sprmPDcs" pap.dcs DCS
138 { 47, { 2, L_FIX} }, // "sprmPShd" pap.shd SHD
139 { 48, { 2, L_FIX} }, // "sprmPDyaFromText" pap.dyaFromText dya
140 { 49, { 2, L_FIX} }, // "sprmPDxaFromText" pap.dxaFromText dxa
141 { 50, { 1, L_FIX} }, // "sprmPFBiDi" pap.fBiDi 0 or 1 byte
142 { 51, { 1, L_FIX} }, // "sprmPFWidowControl" pap.fWidowControl 0 or 1 byte
143 { 52, { 0, L_FIX} }, // "?sprmPRuler 52"
144 { 53, { 1, L_FIX} }, // "sprmCFStrikeRM" chp.fRMarkDel 1 or 0 bit
145 { 54, { 1, L_FIX} }, // "sprmCFRMark" chp.fRMark 1 or 0 bit
146 { 55, { 1, L_FIX} }, // "sprmCFFieldVanish" chp.fFieldVanish 1 or 0 bit
147 { 57, { 0, L_VAR} }, // "sprmCDefault" whole CHP
148 { 58, { 0, L_FIX} }, // "sprmCPlain" whole CHP
149 { 60, { 1, L_FIX} }, // "sprmCFBold" chp.fBold 0,1, 128, or 129
150 { 61, { 1, L_FIX} }, // "sprmCFItalic" chp.fItalic 0,1, 128, or 129
151 { 62, { 1, L_FIX} }, // "sprmCFStrike" chp.fStrike 0,1, 128, or 129
152 { 63, { 1, L_FIX} }, // "sprmCFOutline" chp.fOutline 0,1, 128, or 129
153 { 64, { 1, L_FIX} }, // "sprmCFShadow" chp.fShadow 0,1, 128, or 129
154 { 65, { 1, L_FIX} }, // "sprmCFSmallCaps" chp.fSmallCaps 0,1, 128, or 129
155 { 66, { 1, L_FIX} }, // "sprmCFCaps" chp.fCaps 0,1, 128, or 129
156 { 67, { 1, L_FIX} }, // "sprmCFVanish" chp.fVanish 0,1, 128, or 129
157 { 68, { 2, L_FIX} }, // "sprmCFtc" chp.ftc ftc word
158 { 69, { 1, L_FIX} }, // "sprmCKul" chp.kul kul byte
159 { 70, { 3, L_FIX} }, // "sprmCSizePos" chp.hps, chp.hpsPos
160 { 71, { 2, L_FIX} }, // "sprmCDxaSpace" chp.dxaSpace dxa
161 { 72, { 2, L_FIX} }, // "sprmCLid" chp.lid LID
162 { 73, { 1, L_FIX} }, // "sprmCIco" chp.ico ico byte
163 { 74, { 1, L_FIX} }, // "sprmCHps" chp.hps hps !word!
164 { 75, { 1, L_FIX} }, // "sprmCHpsInc" chp.hps
165 { 76, { 1, L_FIX} }, // "sprmCHpsPos" chp.hpsPos hps !word!
166 { 77, { 1, L_FIX} }, // "sprmCHpsPosAdj" chp.hpsPos hps
167 { 78, { 0, L_VAR} }, // "?sprmCMajority" chp.fBold, chp.fItalic, ...
168 { 80, { 1, L_FIX} }, // "sprmCFBoldBi" chp.fBoldBi
169 { 81, { 1, L_FIX} }, // "sprmCFItalicBi" chp.fItalicBi
170 { 82, { 2, L_FIX} }, // "sprmCFtcBi" chp.ftcBi
171 { 83, { 2, L_FIX} }, // "sprmClidBi" chp.lidBi
172 { 84, { 1, L_FIX} }, // "sprmCIcoBi" chp.icoBi
173 { 85, { 1, L_FIX} }, // "sprmCHpsBi" chp.hpsBi
174 { 86, { 1, L_FIX} }, // "sprmCFBiDi" chp.fBiDi
175 { 87, { 1, L_FIX} }, // "sprmCFDiacColor" chp.fDiacUSico
176 { 94, { 1, L_FIX} }, // "sprmPicBrcl" pic.brcl brcl (see PIC definition)
177 { 95, {12, L_VAR} }, // "sprmPicScale" pic.mx, pic.my, pic.dxaCropleft,
178 { 96, { 2, L_FIX} }, // "sprmPicBrcTop" pic.brcTop BRC word
179 { 97, { 2, L_FIX} }, // "sprmPicBrcLeft" pic.brcLeft BRC word
180 { 98, { 2, L_FIX} }, // "sprmPicBrcBottom" pic.brcBottom BRC word
181 { 99, { 2, L_FIX} }, // "sprmPicBrcRight" pic.brcRight BRC word
182 {112, { 1, L_FIX} }, // "sprmSFRTLGutter", set to one if gutter is on
183 {114, { 1, L_FIX} }, // "sprmSFBiDi" ;;;
184 {115, { 2, L_FIX} }, // "sprmSDmBinFirst" sep.dmBinFirst word
185 {116, { 2, L_FIX} }, // "sprmSDmBinOther" sep.dmBinOther word
186 {117, { 1, L_FIX} }, // "sprmSBkc" sep.bkc bkc byte
187 {118, { 1, L_FIX} }, // "sprmSFTitlePage" sep.fTitlePage 0 or 1 byte
188 {119, { 2, L_FIX} }, // "sprmSCcolumns" sep.ccolM1 # of cols - 1 word
189 {120, { 2, L_FIX} }, // "sprmSDxaColumns" sep.dxaColumns dxa word
190 {121, { 1, L_FIX} }, // "sprmSFAutoPgn" sep.fAutoPgn obsolete byte
191 {122, { 1, L_FIX} }, // "sprmSNfcPgn" sep.nfcPgn nfc byte
192 {123, { 2, L_FIX} }, // "sprmSDyaPgn" sep.dyaPgn dya short
193 {124, { 2, L_FIX} }, // "sprmSDxaPgn" sep.dxaPgn dya short
194 {125, { 1, L_FIX} }, // "sprmSFPgnRestart" sep.fPgnRestart 0 or 1 byte
195 {126, { 1, L_FIX} }, // "sprmSFEndnote" sep.fEndnote 0 or 1 byte
196 {127, { 1, L_FIX} }, // "sprmSLnc" sep.lnc lnc byte
197 {128, { 1, L_FIX} }, // "sprmSGprfIhdt" sep.grpfIhdt grpfihdt
198 {129, { 2, L_FIX} }, // "sprmSNLnnMod" sep.nLnnMod non-neg int. word
199 {130, { 2, L_FIX} }, // "sprmSDxaLnn" sep.dxaLnn dxa word
200 {131, { 2, L_FIX} }, // "sprmSDyaHdrTop" sep.dyaHdrTop dya word
201 {132, { 2, L_FIX} }, // "sprmSDyaHdrBottom" sep.dyaHdrBottom dya word
202 {133, { 1, L_FIX} }, // "sprmSLBetween" sep.fLBetween 0 or 1 byte
203 {134, { 1, L_FIX} }, // "sprmSVjc" sep.vjc vjc byte
204 {135, { 2, L_FIX} }, // "sprmSLnnMin" sep.lnnMin lnn word
205 {136, { 2, L_FIX} }, // "sprmSPgnStart" sep.pgnStart pgn word
206 {137, { 1, L_FIX} }, // "sprmSBOrientation" sep.dmOrientPage dm byte
207 {138, { 1, L_FIX} }, // "sprmSFFacingCol" ;;;
208 {139, { 2, L_FIX} }, // "sprmSXaPage" sep.xaPage xa word
209 {140, { 2, L_FIX} }, // "sprmSYaPage" sep.yaPage ya word
210 {141, { 2, L_FIX} }, // "sprmSDxaLeft" sep.dxaLeft dxa word
211 {142, { 2, L_FIX} }, // "sprmSDxaRight" sep.dxaRight dxa word
212 {143, { 2, L_FIX} }, // "sprmSDyaTop" sep.dyaTop dya word
213 {144, { 2, L_FIX} }, // "sprmSDyaBottom" sep.dyaBottom dya word
214 {145, { 2, L_FIX} }, // "sprmSDzaGutter" sep.dzaGutter dza word
215 {146, { 2, L_FIX} }, // "sprmTJc" tap.jc jc (low order byte is significant)
216 {147, { 2, L_FIX} }, // "sprmTDxaLeft" tap.rgdxaCenter dxa word
217 {148, { 2, L_FIX} }, // "sprmTDxaGapHalf" tap.dxaGapHalf, tap.rgdxaCenter
218 {149, { 1, L_FIX} }, // "sprmTFBiDi" ;;;
219 {152, { 0, L_VAR2} },// "sprmTDefTable10" tap.rgdxaCenter, tap.rgtc complex
220 {153, { 2, L_FIX} }, // "sprmTDyaRowHeight" tap.dyaRowHeight dya word
221 {154, { 0, L_VAR2} },// "sprmTDefTable" tap.rgtc complex
222 {155, { 1, L_VAR} }, // "sprmTDefTableShd" tap.rgshd complex
223 {157, { 5, L_FIX} }, // "sprmTSetBrc" tap.rgtc[].rgbrc complex 5 bytes
224 {158, { 4, L_FIX} }, // "sprmTInsert" tap.rgdxaCenter,tap.rgtc complex
225 {159, { 2, L_FIX} }, // "sprmTDelete" tap.rgdxaCenter, tap.rgtc complex
226 {160, { 4, L_FIX} }, // "sprmTDxaCol" tap.rgdxaCenter complex
227 {161, { 2, L_FIX} }, // "sprmTMerge" tap.fFirstMerged, tap.fMerged complex
228 {162, { 2, L_FIX} }, // "sprmTSplit" tap.fFirstMerged, tap.fMerged complex
229 {163, { 5, L_FIX} }, // "sprmTSetBrc10" tap.rgtc[].rgbrc complex 5 bytes
230 {164, { 4, L_FIX} }, // "sprmTSetShd", tap.rgshd complex 4 bytes
231 };
232
233 static wwSprmSearcher aSprmSrch(aSprms, SAL_N_ELEMENTS(aSprms));
234 return &aSprmSrch;
235};
236
238{
239 //double lock me
240 // WW7- Sprms
241 static const SprmInfoRow aSprms[] =
242 {
243 { 0, { 0, L_FIX} }, // "Default-sprm", is skipped
244 {NS_sprm::v6::sprmPIstd, { 2, L_FIX} }, // pap.istd (style code)
245 {NS_sprm::v6::sprmPIstdPermute, { 3, L_VAR} }, // pap.istd permutation
246 {NS_sprm::v6::sprmPIncLv1, { 1, L_FIX} }, // pap.istddifference
247 {NS_sprm::v6::sprmPJc, { 1, L_FIX} }, // pap.jc (justification)
248 {NS_sprm::v6::sprmPFSideBySide, { 1, L_FIX} }, // pap.fSideBySide
249 {NS_sprm::v6::sprmPFKeep, { 1, L_FIX} }, // pap.fKeep
250 {NS_sprm::v6::sprmPFKeepFollow, { 1, L_FIX} }, // pap.fKeepFollow
251 {NS_sprm::v6::sprmPPageBreakBefore, { 1, L_FIX} }, // pap.fPageBreakBefore
252 {NS_sprm::v6::sprmPBrcl, { 1, L_FIX} }, // pap.brcl
253 {NS_sprm::v6::sprmPBrcp, { 1, L_FIX} }, // pap.brcp
254 {NS_sprm::v6::sprmPAnld, { 0, L_VAR} }, // pap.anld (ANLD structure)
255 {NS_sprm::v6::sprmPNLvlAnm, { 1, L_FIX} }, // pap.nLvlAnm nn
256 {NS_sprm::v6::sprmPFNoLineNumb, { 1, L_FIX} }, // pap.fNoLnn
257 {NS_sprm::v6::sprmPChgTabsPapx, { 0, L_VAR} }, // pap.itbdMac, ...
258 {NS_sprm::v6::sprmPDxaRight, { 2, L_FIX} }, // pap.dxaRight
259 {NS_sprm::v6::sprmPDxaLeft, { 2, L_FIX} }, // pap.dxaLeft
260 {NS_sprm::v6::sprmPNest, { 2, L_FIX} }, // pap.dxaLeft
261 {NS_sprm::v6::sprmPDxaLeft1, { 2, L_FIX} }, // pap.dxaLeft1
262 {NS_sprm::v6::sprmPDyaLine, { 4, L_FIX} }, // pap.lspd an LSPD
263 {NS_sprm::v6::sprmPDyaBefore, { 2, L_FIX} }, // pap.dyaBefore
264 {NS_sprm::v6::sprmPDyaAfter, { 2, L_FIX} }, // pap.dyaAfter
265 {NS_sprm::v6::sprmPChgTabs, { 0, L_VAR} }, // pap.itbdMac, pap.rgdxaTab, ...
266 {NS_sprm::v6::sprmPFInTable, { 1, L_FIX} }, // pap.fInTable
267 {NS_sprm::v6::sprmPTtp, { 1, L_FIX} }, // pap.fTtp
268 {NS_sprm::v6::sprmPDxaAbs, { 2, L_FIX} }, // pap.dxaAbs
269 {NS_sprm::v6::sprmPDyaAbs, { 2, L_FIX} }, // pap.dyaAbs
270 {NS_sprm::v6::sprmPDxaWidth, { 2, L_FIX} }, // pap.dxaWidth
271 {NS_sprm::v6::sprmPPc, { 1, L_FIX} }, // pap.pcHorz, pap.pcVert
272 {NS_sprm::v6::sprmPBrcTop10, { 2, L_FIX} }, // pap.brcTop BRC10
273 {NS_sprm::v6::sprmPBrcLeft10, { 2, L_FIX} }, // pap.brcLeft BRC10
274 {NS_sprm::v6::sprmPBrcBottom10, { 2, L_FIX} }, // pap.brcBottom BRC10
275 {NS_sprm::v6::sprmPBrcRight10, { 2, L_FIX} }, // pap.brcRight BRC10
276 {NS_sprm::v6::sprmPBrcBetween10, { 2, L_FIX} }, // pap.brcBetween BRC10
277 {NS_sprm::v6::sprmPBrcBar10, { 2, L_FIX} }, // pap.brcBar BRC10
278 {NS_sprm::v6::sprmPFromText10, { 2, L_FIX} }, // pap.dxaFromText dxa
279 {NS_sprm::v6::sprmPWr, { 1, L_FIX} }, // pap.wr wr
280 {NS_sprm::v6::sprmPBrcTop, { 2, L_FIX} }, // pap.brcTop BRC
281 {NS_sprm::v6::sprmPBrcLeft, { 2, L_FIX} }, // pap.brcLeft BRC
282 {NS_sprm::v6::sprmPBrcBottom, { 2, L_FIX} }, // pap.brcBottom BRC
283 {NS_sprm::v6::sprmPBrcRight, { 2, L_FIX} }, // pap.brcRight BRC
284 {NS_sprm::v6::sprmPBrcBetween, { 2, L_FIX} }, // pap.brcBetween BRC
285 {NS_sprm::v6::sprmPBrcBar, { 2, L_FIX} }, // pap.brcBar BRC word
286 {NS_sprm::v6::sprmPFNoAutoHyph, { 1, L_FIX} }, // pap.fNoAutoHyph
287 {NS_sprm::v6::sprmPWHeightAbs, { 2, L_FIX} }, // pap.wHeightAbs w
288 {NS_sprm::v6::sprmPDcs, { 2, L_FIX} }, // pap.dcs DCS
289 {NS_sprm::v6::sprmPShd, { 2, L_FIX} }, // pap.shd SHD
290 {NS_sprm::v6::sprmPDyaFromText, { 2, L_FIX} }, // pap.dyaFromText dya
291 {NS_sprm::v6::sprmPDxaFromText, { 2, L_FIX} }, // pap.dxaFromText dxa
292 {NS_sprm::v6::sprmPFLocked, { 1, L_FIX} }, // pap.fLocked 0 or 1 byte
293 {NS_sprm::v6::sprmPFWidowControl, { 1, L_FIX} }, // pap.fWidowControl 0 or 1 byte
295 { 64, { 0, L_VAR} }, // rtl property ?
296 {NS_sprm::v6::sprmCFStrikeRM, { 1, L_FIX} }, // chp.fRMarkDel 1 or 0 bit
297 {NS_sprm::v6::sprmCFRMark, { 1, L_FIX} }, // chp.fRMark 1 or 0 bit
298 {NS_sprm::v6::sprmCFFldVanish, { 1, L_FIX} }, // chp.fFieldVanish 1 or 0 bit
299 {NS_sprm::v6::sprmCPicLocation, { 0, L_VAR} }, // chp.fcPic and chp.fSpec
300 {NS_sprm::v6::sprmCIbstRMark, { 2, L_FIX} }, // chp.ibstRMark index into sttbRMark
301 {NS_sprm::v6::sprmCDttmRMark, { 4, L_FIX} }, // chp.dttm DTTM long
302 {NS_sprm::v6::sprmCFData, { 1, L_FIX} }, // chp.fData 1 or 0 bit
303 {NS_sprm::v6::sprmCRMReason, { 2, L_FIX} }, // chp.idslRMReason an index to a table
304 {NS_sprm::v6::sprmCChse, { 3, L_FIX} }, // chp.fChsDiff and chp.chse
305 {NS_sprm::v6::sprmCSymbol, { 0, L_VAR} }, // chp.fSpec, chp.chSym and chp.ftcSym
306 {NS_sprm::v6::sprmCFOle2, { 1, L_FIX} }, // chp.fOle2 1 or 0 bit
307 { 77, { 0, L_VAR} }, // unknown
308 { 79, { 0, L_VAR} }, // unknown
309 {NS_sprm::v6::sprmCIstd, { 2, L_FIX} }, // chp.istd istd, see stylesheet definition
310 {NS_sprm::v6::sprmCIstdPermute, { 0, L_VAR} }, // chp.istd permutation vector
311 {NS_sprm::v6::sprmCDefault, { 0, L_VAR} }, // whole CHP
312 {NS_sprm::v6::sprmCPlain, { 0, L_FIX} }, // whole CHP
313 {NS_sprm::v6::sprmCFBold, { 1, L_FIX} }, // chp.fBold 0,1, 128, or 129
314 {NS_sprm::v6::sprmCFItalic, { 1, L_FIX} }, // chp.fItalic 0,1, 128, or 129
315 {NS_sprm::v6::sprmCFStrike, { 1, L_FIX} }, // chp.fStrike 0,1, 128, or 129
316 {NS_sprm::v6::sprmCFOutline, { 1, L_FIX} }, // chp.fOutline 0,1, 128, or 129
317 {NS_sprm::v6::sprmCFShadow, { 1, L_FIX} }, // chp.fShadow 0,1, 128, or 129
318 {NS_sprm::v6::sprmCFSmallCaps, { 1, L_FIX} }, // chp.fSmallCaps 0,1, 128, or 129
319 {NS_sprm::v6::sprmCFCaps, { 1, L_FIX} }, // chp.fCaps 0,1, 128, or 129
320 {NS_sprm::v6::sprmCFVanish, { 1, L_FIX} }, // chp.fVanish 0,1, 128, or 129
321 {NS_sprm::v6::sprmCFtc, { 2, L_FIX} }, // chp.ftc ftc word
322 {NS_sprm::v6::sprmCKul, { 1, L_FIX} }, // chp.kul kul byte
323 {NS_sprm::v6::sprmCSizePos, { 3, L_FIX} }, // chp.hps, chp.hpsPos
324 {NS_sprm::v6::sprmCDxaSpace, { 2, L_FIX} }, // chp.dxaSpace dxa
325 {NS_sprm::v6::sprmCLid, { 2, L_FIX} }, // chp.lid LID
326 {NS_sprm::v6::sprmCIco, { 1, L_FIX} }, // chp.ico ico byte
327 {NS_sprm::v6::sprmCHps, { 2, L_FIX} }, // chp.hps hps !word!
328 {NS_sprm::v6::sprmCHpsInc, { 1, L_FIX} }, // chp.hps
329 {NS_sprm::v6::sprmCHpsPos, { 2, L_FIX} }, // chp.hpsPos hps !word!
330 {NS_sprm::v6::sprmCHpsPosAdj, { 1, L_FIX} }, // chp.hpsPos hps
331 {NS_sprm::v6::sprmCMajority, { 0, L_VAR} }, // chp.fBold, chp.fItalic, ...
332 {NS_sprm::v6::sprmCIss, { 1, L_FIX} }, // chp.iss iss
333 {NS_sprm::v6::sprmCHpsNew50, { 0, L_VAR} }, // chp.hps hps variable width
334 {NS_sprm::v6::sprmCHpsInc1, { 0, L_VAR} }, // chp.hps complex
335 {NS_sprm::v6::sprmCHpsKern, { 2, L_FIX} }, // chp.hpsKern hps
336 {NS_sprm::v6::sprmCMajority50, { 0, L_VAR} }, // chp.fBold, chp.fItalic, ...
337 {NS_sprm::v6::sprmCHpsMul, { 2, L_FIX} }, // chp.hps percentage to grow hps
338 {NS_sprm::v6::sprmCCondHyhen, { 2, L_FIX} }, // chp.ysri ysri
339 {111, { 0, L_VAR} }, // sprmCFBoldBi or font code
340 {112, { 0, L_VAR} }, // sprmCFItalicBi or font code
341 {113, { 0, L_VAR} }, // ww7 rtl font
342 {114, { 0, L_VAR} }, // ww7 lid
343 {115, { 0, L_VAR} }, // ww7 CJK font
344 {116, { 0, L_VAR} }, // ww7 fontsize
345 {NS_sprm::v6::sprmCFSpec, { 1, L_FIX} }, // chp.fSpec 1 or 0 bit
346 {NS_sprm::v6::sprmCFObj, { 1, L_FIX} }, // chp.fObj 1 or 0 bit
347 {NS_sprm::v6::sprmPicBrcl, { 1, L_FIX} }, // pic.brcl brcl (see PIC definition)
348 {NS_sprm::v6::sprmPicScale, {12, L_VAR} }, // pic.mx, pic.my, pic.dxaCropleft,
349 {NS_sprm::v6::sprmPicBrcTop, { 2, L_FIX} }, // pic.brcTop BRC word
350 {NS_sprm::v6::sprmPicBrcLeft, { 2, L_FIX} }, // pic.brcLeft BRC word
351 {NS_sprm::v6::sprmPicBrcBottom, { 2, L_FIX} }, // pic.brcBottom BRC word
352 {NS_sprm::v6::sprmPicBrcRight, { 2, L_FIX} }, // pic.brcRight BRC word
353 {NS_sprm::v6::sprmSScnsPgn, { 1, L_FIX} }, // sep.cnsPgn cns byte
354 {NS_sprm::v6::sprmSiHeadingPgn, { 1, L_FIX} }, // sep.iHeadingPgn
355 {NS_sprm::v6::sprmSOlstAnm, { 0, L_VAR} }, // sep.olstAnm OLST variable length
356 {NS_sprm::v6::sprmSDxaColWidth, { 3, L_FIX} }, // sep.rgdxaColWidthSpacing complex
357 {NS_sprm::v6::sprmSDxaColSpacing, { 3, L_FIX} }, // sep.rgdxaColWidthSpacing
358 {NS_sprm::v6::sprmSFEvenlySpaced, { 1, L_FIX} }, // sep.fEvenlySpaced 1 or 0
359 {NS_sprm::v6::sprmSFProtected, { 1, L_FIX} }, // sep.fUnlocked 1 or 0 byte
360 {NS_sprm::v6::sprmSDmBinFirst, { 2, L_FIX} }, // sep.dmBinFirst word
361 {NS_sprm::v6::sprmSDmBinOther, { 2, L_FIX} }, // sep.dmBinOther word
362 {NS_sprm::v6::sprmSBkc, { 1, L_FIX} }, // sep.bkc bkc byte
363 {NS_sprm::v6::sprmSFTitlePage, { 1, L_FIX} }, // sep.fTitlePage 0 or 1 byte
364 {NS_sprm::v6::sprmSCcolumns, { 2, L_FIX} }, // sep.ccolM1 # of cols - 1 word
365 {NS_sprm::v6::sprmSDxaColumns, { 2, L_FIX} }, // sep.dxaColumns dxa word
366 {NS_sprm::v6::sprmSFAutoPgn, { 1, L_FIX} }, // sep.fAutoPgn obsolete byte
367 {NS_sprm::v6::sprmSNfcPgn, { 1, L_FIX} }, // sep.nfcPgn nfc byte
368 {NS_sprm::v6::sprmSDyaPgn, { 2, L_FIX} }, // sep.dyaPgn dya short
369 {NS_sprm::v6::sprmSDxaPgn, { 2, L_FIX} }, // sep.dxaPgn dya short
370 {NS_sprm::v6::sprmSFPgnRestart, { 1, L_FIX} }, // sep.fPgnRestart 0 or 1 byte
371 {NS_sprm::v6::sprmSFEndnote, { 1, L_FIX} }, // sep.fEndnote 0 or 1 byte
372 {NS_sprm::v6::sprmSLnc, { 1, L_FIX} }, // sep.lnc lnc byte
373 {NS_sprm::v6::sprmSGprfIhdt, { 1, L_FIX} }, // sep.grpfIhdt grpfihdt
374 {NS_sprm::v6::sprmSNLnnMod, { 2, L_FIX} }, // sep.nLnnMod non-neg int. word
375 {NS_sprm::v6::sprmSDxaLnn, { 2, L_FIX} }, // sep.dxaLnn dxa word
376 {NS_sprm::v6::sprmSDyaHdrTop, { 2, L_FIX} }, // sep.dyaHdrTop dya word
377 {NS_sprm::v6::sprmSDyaHdrBottom, { 2, L_FIX} }, // sep.dyaHdrBottom dya word
378 {NS_sprm::v6::sprmSLBetween, { 1, L_FIX} }, // sep.fLBetween 0 or 1 byte
379 {NS_sprm::v6::sprmSVjc, { 1, L_FIX} }, // sep.vjc vjc byte
380 {NS_sprm::v6::sprmSLnnMin, { 2, L_FIX} }, // sep.lnnMin lnn word
381 {NS_sprm::v6::sprmSPgnStart, { 2, L_FIX} }, // sep.pgnStart pgn word
382 {NS_sprm::v6::sprmSBOrientation, { 1, L_FIX} }, // sep.dmOrientPage dm byte
384 {NS_sprm::v6::sprmSXaPage, { 2, L_FIX} }, // sep.xaPage xa word
385 {NS_sprm::v6::sprmSYaPage, { 2, L_FIX} }, // sep.yaPage ya word
386 {NS_sprm::v6::sprmSDxaLeft, { 2, L_FIX} }, // sep.dxaLeft dxa word
387 {NS_sprm::v6::sprmSDxaRight, { 2, L_FIX} }, // sep.dxaRight dxa word
388 {NS_sprm::v6::sprmSDyaTop, { 2, L_FIX} }, // sep.dyaTop dya word
389 {NS_sprm::v6::sprmSDyaBottom, { 2, L_FIX} }, // sep.dyaBottom dya word
390 {NS_sprm::v6::sprmSDzaGutter, { 2, L_FIX} }, // sep.dzaGutter dza word
391 {NS_sprm::v6::sprmSDMPaperReq, { 2, L_FIX} }, // sep.dmPaperReq dm word
392 {179, { 0, L_VAR} }, // rtl property ?
393 {181, { 0, L_VAR} }, // rtl property ?
394 {NS_sprm::v6::sprmTJc, { 2, L_FIX} }, // tap.jc jc (low order byte is significant)
395 {NS_sprm::v6::sprmTDxaLeft, { 2, L_FIX} }, // tap.rgdxaCenter dxa word
396 {NS_sprm::v6::sprmTDxaGapHalf, { 2, L_FIX} }, // tap.dxaGapHalf, tap.rgdxaCenter
397 {NS_sprm::v6::sprmTFCantSplit, { 1, L_FIX} }, // tap.fCantSplit 1 or 0 byte
398 {NS_sprm::v6::sprmTTableHeader, { 1, L_FIX} }, // tap.fTableHeader 1 or 0 byte
399 {NS_sprm::v6::sprmTTableBorders, {12, L_FIX} }, // tap.rgbrcTable complex 12 bytes
400 {NS_sprm::v6::sprmTDefTable10, { 0, L_VAR2} }, // tap.rgdxaCenter, tap.rgtc complex
401 {NS_sprm::v6::sprmTDyaRowHeight, { 2, L_FIX} }, // tap.dyaRowHeight dya word
402 {NS_sprm::v6::sprmTDefTable, { 0, L_VAR2} }, // tap.rgtc complex
403 {NS_sprm::v6::sprmTDefTableShd, { 1, L_VAR} }, // tap.rgshd complex
404 {NS_sprm::v6::sprmTTlp, { 4, L_FIX} }, // tap.tlp TLP 4 bytes
405 {NS_sprm::v6::sprmTSetBrc, { 5, L_FIX} }, // tap.rgtc[].rgbrc complex 5 bytes
406 {NS_sprm::v6::sprmTInsert, { 4, L_FIX} }, // tap.rgdxaCenter,tap.rgtc complex
407 {NS_sprm::v6::sprmTDelete, { 2, L_FIX} }, // tap.rgdxaCenter, tap.rgtc complex
408 {NS_sprm::v6::sprmTDxaCol, { 4, L_FIX} }, // tap.rgdxaCenter complex
409 {NS_sprm::v6::sprmTMerge, { 2, L_FIX} }, // tap.fFirstMerged, tap.fMerged complex
410 {NS_sprm::v6::sprmTSplit, { 2, L_FIX} }, // tap.fFirstMerged, tap.fMerged complex
411 {NS_sprm::v6::sprmTSetBrc10, { 5, L_FIX} }, // tap.rgtc[].rgbrc complex 5 bytes
412 {NS_sprm::v6::sprmTSetShd, { 4, L_FIX} }, // tap.rgshd complex 4 bytes
413 {207, { 0, L_VAR} } // rtl property ?
414 };
415
416 if (rFib.m_wIdent >= 0xa697 && rFib.m_wIdent <= 0xa699)
417 {
418 //see Read_AmbiguousSPRM for this oddity
419 static wwSprmSearcher aSprmSrch(aSprms, SAL_N_ELEMENTS(aSprms), true);
420 return &aSprmSrch;
421 }
422
423 static wwSprmSearcher aSprmSrch(aSprms, SAL_N_ELEMENTS(aSprms));
424 return &aSprmSrch;
425};
426
428{
429 for (sal_uInt16 nId = 111; nId <= 113; ++nId)
430 {
431 SprmInfo& amb1 = map_[nId];
432 amb1.nLen = 2;
434 }
435}
436
437template <class Sprm> static constexpr SprmInfoRow InfoRow()
438{
439 return { Sprm::val, { Sprm::len, Sprm::varlen ? wwSprmParser::L_VAR : wwSprmParser::L_FIX } };
440}
441
443{
444 //double lock me
445 //WW8+ Sprms
446 static const SprmInfoRow aSprms[] =
447 {
448 { 0, { 0, L_FIX} }, // "Default-sprm"/ is skipped
449 InfoRow<NS_sprm::PIstd>(), // pap.istd;istd (style code);short;
450 InfoRow<NS_sprm::PIstdPermute>(), // pap.istd;permutation vector
451 InfoRow<NS_sprm::PIncLvl>(), // pap.istd, pap.lvl;difference
452 // between istd of base PAP and istd of PAP to be
453 // produced
454 InfoRow<NS_sprm::PJc80>(), // pap.jc;jc (justification);byte;
455 {NS_sprm::LN_PFSideBySide, { 1, L_FIX} }, // "sprmPFSideBySide" pap.fSideBySide;0 or 1;byte;
456 InfoRow<NS_sprm::PFKeep>(), // pap.fKeep;0 or 1;byte;
457 InfoRow<NS_sprm::PFKeepFollow>(), // pap.fKeepFollow;0 or 1;byte;
458 InfoRow<NS_sprm::PFPageBreakBefore>(), // pap.fPageBreakBefore;
459 // 0 or 1
460 {NS_sprm::LN_PBrcl, { 1, L_FIX} }, // "sprmPBrcl" pap.brcl;brcl;byte;
461 {NS_sprm::LN_PBrcp, { 1, L_FIX} }, // "sprmPBrcp" pap.brcp;brcp;byte;
462 InfoRow<NS_sprm::PIlvl>(), // pap.ilvl;ilvl;byte;
463 InfoRow<NS_sprm::PIlfo>(), // pap.ilfo;ilfo (list index) ;short;
464 InfoRow<NS_sprm::PFNoLineNumb>(), // pap.fNoLnn;0 or 1;byte;
465 InfoRow<NS_sprm::PChgTabsPapx>(), // pap.itbdMac, pap.rgdxaTab,
466 // pap.rgtbd;complex
467 InfoRow<NS_sprm::PDxaRight80>(), // pap.dxaRight;dxa;word;
468 InfoRow<NS_sprm::PDxaLeft80>(), // pap.dxaLeft;dxa;word;
469 InfoRow<NS_sprm::PNest80>(), // pap.dxaLeft;dxa
470 InfoRow<NS_sprm::PDxaLeft180>(), // pap.dxaLeft1;dxa;word;
471 InfoRow<NS_sprm::PDyaLine>(), // pap.lspd;an LSPD, a long word
472 // structure consisting of a short of dyaLine
473 // followed by a short of fMultLinespace
474 InfoRow<NS_sprm::PDyaBefore>(), // pap.dyaBefore;dya;word;
475 InfoRow<NS_sprm::PDyaAfter>(), // pap.dyaAfter;dya;word;
476 InfoRow<NS_sprm::PChgTabs>(), // pap.itbdMac, pap.rgdxaTab,
477 // pap.rgtbd;complex
478 InfoRow<NS_sprm::PFInTable>(), // pap.fInTable;0 or 1;byte;
479 InfoRow<NS_sprm::PFTtp>(), // pap.fTtp;0 or 1;byte;
480 InfoRow<NS_sprm::PDxaAbs>(), // pap.dxaAbs;dxa;word;
481 InfoRow<NS_sprm::PDyaAbs>(), // pap.dyaAbs;dya;word;
482 InfoRow<NS_sprm::PDxaWidth>(), // pap.dxaWidth;dxa;word;
483 InfoRow<NS_sprm::PPc>(), // pap.pcHorz, pap.pcVert;complex
484 {NS_sprm::LN_PBrcTop10, { 2, L_FIX} }, // "sprmPBrcTop10" pap.brcTop;BRC10;word;
485 {NS_sprm::LN_PBrcLeft10, { 2, L_FIX} }, // "sprmPBrcLeft10" pap.brcLeft;BRC10;word;
486 {NS_sprm::LN_PBrcBottom10, { 2, L_FIX} }, // "sprmPBrcBottom10" pap.brcBottom;BRC10;word;
487 {NS_sprm::LN_PBrcRight10, { 2, L_FIX} }, // "sprmPBrcRight10" pap.brcRight;BRC10;word;
488 {NS_sprm::LN_PBrcBetween10, { 2, L_FIX} }, // "sprmPBrcBetween10" pap.brcBetween;BRC10;word;
489 {NS_sprm::LN_PBrcBar10, { 2, L_FIX} }, // "sprmPBrcBar10" pap.brcBar;BRC10;word;
490 {NS_sprm::LN_PDxaFromText10, { 2, L_FIX} }, // "sprmPDxaFromText10" pap.dxaFromText;dxa;word;
491 InfoRow<NS_sprm::PWr>(), // pap.wr;wr
492 InfoRow<NS_sprm::PBrcTop80>(), // pap.brcTop;BRC;long;
493 InfoRow<NS_sprm::PBrcLeft80>(), // pap.brcLeft;BRC;long;
494 InfoRow<NS_sprm::PBrcBottom80>(), // pap.brcBottom;BRC;long;
495 InfoRow<NS_sprm::PBrcRight80>(), // pap.brcRight;BRC;long;
496 InfoRow<NS_sprm::PBrcBetween80>(), // pap.brcBetween;BRC;long;
497 InfoRow<NS_sprm::PBrcBar80>(), // pap.brcBar;BRC;long;
498 InfoRow<NS_sprm::PFNoAutoHyph>(), // pap.fNoAutoHyph;0 or 1;byte;
499 InfoRow<NS_sprm::PWHeightAbs>(), // pap.wHeightAbs;w;word;
500 InfoRow<NS_sprm::PDcs>(), // pap.dcs;DCS;short;
501 InfoRow<NS_sprm::PShd80>(), // pap.shd;SHD;word;
502 InfoRow<NS_sprm::PDyaFromText>(), // pap.dyaFromText;dya;word;
503 InfoRow<NS_sprm::PDxaFromText>(), // pap.dxaFromText;dxa;word;
504 InfoRow<NS_sprm::PFLocked>(), // pap.fLocked;0 or 1;byte;
505 InfoRow<NS_sprm::PFWidowControl>(), // pap.fWidowControl;0 or 1
506 {NS_sprm::LN_PRuler, { 0, L_VAR} }, // "sprmPRuler" ;;variable length;
507 InfoRow<NS_sprm::PFKinsoku>(), // pap.fKinsoku;0 or 1;byte;
508 InfoRow<NS_sprm::PFWordWrap>(), // pap.fWordWrap;0 or 1;byte;
509 InfoRow<NS_sprm::PFOverflowPunct>(), // pap.fOverflowPunct;0 or 1
510 InfoRow<NS_sprm::PFTopLinePunct>(), // pap.fTopLinePunct;0 or 1
511 InfoRow<NS_sprm::PFAutoSpaceDE>(), // pap.fAutoSpaceDE;0 or 1
512 InfoRow<NS_sprm::PFAutoSpaceDN>(), // pap.fAutoSpaceDN;0 or 1
513 InfoRow<NS_sprm::PWAlignFont>(), // pap.wAlignFont;iFa
514 InfoRow<NS_sprm::PFrameTextFlow>(), // pap.fVertical pap.fBackward
515 // pap.fRotateFont;complex
516 {NS_sprm::LN_PISnapBaseLine, { 1, L_FIX} }, // "sprmPISnapBaseLine" obsolete: not applicable in
517 // Word97 and later versions;
518 {NS_sprm::LN_PAnld, { 0, L_VAR} }, // "sprmPAnld" pap.anld;;variable length;
519 {NS_sprm::LN_PPropRMark, { 0, L_VAR} }, // "sprmPPropRMark" pap.fPropRMark;complex
520 InfoRow<NS_sprm::POutLvl>(), // pap.lvl;has no effect if pap.istd
521 // is < 1 or is > 9
522 InfoRow<NS_sprm::PFBiDi>(), // ;;byte;
523 InfoRow<NS_sprm::PFNumRMIns>(), // pap.fNumRMIns;1 or 0;bit;
524 {NS_sprm::LN_PCrLf, { 1, L_FIX} }, // "sprmPCrLf" ;;byte;
525 InfoRow<NS_sprm::PNumRM>(), // pap.numrm;;variable length;
526 {NS_sprm::LN_PHugePapx, { 4, L_FIX} }, // "sprmPHugePapx" fc in the data stream to locate
527 // the huge grpprl
528 InfoRow<NS_sprm::PHugePapx>(), // fc in the data stream to locate
529 // the huge grpprl
530 InfoRow<NS_sprm::PFUsePgsuSettings>(), // pap.fUsePgsuSettings;
531 // 1 or 0
532 InfoRow<NS_sprm::PFAdjustRight>(), // pap.fAdjustRight;1 or 0;byte;
533 InfoRow<NS_sprm::CFRMarkDel>(), // chp.fRMarkDel;1 or 0;bit;
534 InfoRow<NS_sprm::CFRMarkIns>(), // chp.fRMark;1 or 0;bit;
535 InfoRow<NS_sprm::CFFldVanish>(), // chp.fFieldVanish;1 or 0;bit;
536 InfoRow<NS_sprm::CPicLocation>(), // chp.fcPic and chp.fSpec;
537 InfoRow<NS_sprm::CIbstRMark>(), // chp.ibstRMark;index into
538 // sttbRMark
539 InfoRow<NS_sprm::CDttmRMark>(), // chp.dttmRMark;DTTM;long;
540 InfoRow<NS_sprm::CFData>(), // chp.fData;1 or 0;bit;
541 InfoRow<NS_sprm::CIdslRMark>(), // chp.idslRMReason;an index to a
542 // table of strings defined in Word 6.0
543 // executables;short;
544 {NS_sprm::LN_CChs, { 1, L_FIX} }, // "sprmCChs" chp.fChsDiff and chp.chse;
545 InfoRow<NS_sprm::CSymbol>(), // chp.fSpec, chp.xchSym and
546 // chp.ftcSym
547 InfoRow<NS_sprm::CFOle2>(), // chp.fOle2;1 or 0;bit;
548 {NS_sprm::LN_CIdCharType, { 0, L_FIX} }, // "sprmCIdCharType" obsolete: not applicable in
549 // Word97 and later versions;
550 InfoRow<NS_sprm::CHighlight>(), // chp.fHighlight,
551 // chp.icoHighlight;ico (fHighlight is set to 1 iff
552 // ico is not 0)
553 {NS_sprm::LN_CObjLocation, { 4, L_FIX} }, // "sprmCObjLocation" chp.fcObj;FC;long;
554 {NS_sprm::LN_CFFtcAsciSymb, { 0, L_FIX} }, // "sprmCFFtcAsciSymb" ;;;
555 InfoRow<NS_sprm::CIstd>(), // chp.istd;istd, see stylesheet def
556 InfoRow<NS_sprm::CIstdPermute>(), // chp.istd;permutation vector
557 {NS_sprm::LN_CDefault, { 0, L_VAR} }, // "sprmCDefault" whole CHP;none;variable length;
558 InfoRow<NS_sprm::CPlain>(), // whole CHP;none;0;
559 InfoRow<NS_sprm::CKcd>(), // ;;;
560 InfoRow<NS_sprm::CFBold>(), // chp.fBold;0,1, 128, or 129
561 InfoRow<NS_sprm::CFItalic>(), // chp.fItalic;0,1, 128, or 129
562 InfoRow<NS_sprm::CFStrike>(), // chp.fStrike;0,1, 128, or 129
563 InfoRow<NS_sprm::CFOutline>(), // chp.fOutline;0,1, 128, or 129
564 InfoRow<NS_sprm::CFShadow>(), // chp.fShadow;0,1, 128, or 129
565 InfoRow<NS_sprm::CFSmallCaps>(), // chp.fSmallCaps;0,1, 128, or 129
566 InfoRow<NS_sprm::CFCaps>(), // chp.fCaps;0,1, 128, or 129
567 InfoRow<NS_sprm::CFVanish>(), // chp.fVanish;0,1, 128, or 129
568 {NS_sprm::LN_CFtcDefault, { 2, L_FIX} }, // "sprmCFtcDefault" ;ftc, only used internally
569 InfoRow<NS_sprm::CKul>(), // chp.kul;kul;byte;
570 {NS_sprm::LN_CSizePos, { 3, L_FIX} }, // "sprmCSizePos" chp.hps, chp.hpsPos;3 bytes;
571 InfoRow<NS_sprm::CDxaSpace>(), // chp.dxaSpace;dxa;word;
572 {NS_sprm::LN_CLid, { 2, L_FIX} }, // "sprmCLid" ;only used internally never stored
573 InfoRow<NS_sprm::CIco>(), // chp.ico;ico;byte;
574 InfoRow<NS_sprm::CHps>(), // chp.hps;hps
575 {NS_sprm::LN_CHpsInc, { 1, L_FIX} }, // "sprmCHpsInc" chp.hps;
576 InfoRow<NS_sprm::CHpsPos>(), // chp.hpsPos;hps;short; (doc wrong)
577 {NS_sprm::LN_CHpsPosAdj, { 1, L_FIX} }, // "sprmCHpsPosAdj" chp.hpsPos;hps
578 InfoRow<NS_sprm::CMajority>(), // chp.fBold, chp.fItalic,
579 // chp.fSmallCaps, chp.fVanish, chp.fStrike,
580 // chp.fCaps, chp.rgftc, chp.hps, chp.hpsPos,
581 // chp.kul, chp.dxaSpace, chp.ico,
582 // chp.rglid;complex;variable length, length byte
583 // plus size of following grpprl;
584 InfoRow<NS_sprm::CIss>(), // chp.iss;iss;byte;
585 {NS_sprm::LN_CHpsNew50, { 0, L_VAR} }, // "sprmCHpsNew50" chp.hps;hps;variable width
586 {NS_sprm::LN_CHpsInc1, { 0, L_VAR} }, // "sprmCHpsInc1" chp.hps;complex
587 InfoRow<NS_sprm::CHpsKern>(), // chp.hpsKern;hps;short;
588 {NS_sprm::LN_CMajority50, { 2, L_FIX} }, // "sprmCMajority50" chp.fBold, chp.fItalic,
589 // chp.fSmallCaps, chp.fVanish, chp.fStrike,
590 // chp.fCaps, chp.ftc, chp.hps, chp.hpsPos, chp.kul,
591 // chp.dxaSpace, chp.ico,;complex
592 {NS_sprm::LN_CHpsMul, { 2, L_FIX} }, // "sprmCHpsMul" chp.hps;percentage to grow hps
593 InfoRow<NS_sprm::CHresi>(), // chp.ysri;ysri;short;
594 InfoRow<NS_sprm::CRgFtc0>(), // chp.rgftc[0];ftc for ASCII text
595 InfoRow<NS_sprm::CRgFtc1>(), // chp.rgftc[1];ftc for Far East text
596 InfoRow<NS_sprm::CRgFtc2>(), // chp.rgftc[2];ftc for non-FE text
597 InfoRow<NS_sprm::CCharScale>(),
598 InfoRow<NS_sprm::CFDStrike>(), // chp.fDStrike;;byte;
599 InfoRow<NS_sprm::CFImprint>(), // chp.fImprint;1 or 0;bit;
600 InfoRow<NS_sprm::CFSpec>(), // chp.fSpec ;1 or 0;bit;
601 InfoRow<NS_sprm::CFObj>(), // chp.fObj;1 or 0;bit;
602 InfoRow<NS_sprm::CPropRMark90>(), // chp.fPropRMark,
603 // chp.ibstPropRMark, chp.dttmPropRMark;Complex
604 InfoRow<NS_sprm::CFEmboss>(), // chp.fEmboss;1 or 0;bit;
605 InfoRow<NS_sprm::CSfxText>(), // chp.sfxtText;text animation;byte;
606 InfoRow<NS_sprm::CFBiDi>(), // ;;;
607 {NS_sprm::LN_CFDiacColor, { 1, L_FIX} }, // "sprmCFDiacColor" ;;;
608 InfoRow<NS_sprm::CFBoldBi>(), // ;;;
609 InfoRow<NS_sprm::CFItalicBi>(), // ;;;
610 InfoRow<NS_sprm::CFtcBi>(),
611 InfoRow<NS_sprm::CLidBi>(), // ;;;
612 InfoRow<NS_sprm::CIcoBi>(), // ;;;
613 InfoRow<NS_sprm::CHpsBi>(), // ;;;
614 InfoRow<NS_sprm::CDispFldRMark>(), // chp.fDispFieldRMark,
615 // chp.ibstDispFieldRMark, chp.dttmDispFieldRMark ;
616 InfoRow<NS_sprm::CIbstRMarkDel>(), // chp.ibstRMarkDel;index into
617 // sttbRMark;short;
618 InfoRow<NS_sprm::CDttmRMarkDel>(), // chp.dttmRMarkDel;DTTM;long;
619 InfoRow<NS_sprm::CBrc80>(), // chp.brc;BRC;long;
620 InfoRow<NS_sprm::CShd80>(), // chp.shd;SHD;short;
621 InfoRow<NS_sprm::CIdslRMarkDel>(), // chp.idslRMReasonDel;an index
622 // to a table of strings defined in Word 6.0
623 // executables;short;
624 InfoRow<NS_sprm::CFUsePgsuSettings>(),
625 // chp.fUsePgsuSettings;1 or 0
626 {NS_sprm::LN_CCpg, { 2, L_FIX} }, // "sprmCCpg" ;;word;
627 InfoRow<NS_sprm::CRgLid0_80>(), // chp.rglid[0];LID: for non-FE text
628 InfoRow<NS_sprm::CRgLid1_80>(), // chp.rglid[1];LID: for Far East text
629 InfoRow<NS_sprm::CIdctHint>(), // chp.idctHint;IDCT:
630 {NS_sprm::LN_PicBrcl, { 1, L_FIX} }, // "sprmPicBrcl" pic.brcl;brcl (see PIC definition)
631 {NS_sprm::LN_PicScale, { 0, L_VAR} }, // "sprmPicScale" pic.mx, pic.my, pic.dxaCropleft,
632 // pic.dyaCropTop pic.dxaCropRight,
633 // pic.dyaCropBottom;Complex
634 InfoRow<NS_sprm::PicBrcTop80>(), // pic.brcTop;BRC;long;
635 InfoRow<NS_sprm::PicBrcLeft80>(), // pic.brcLeft;BRC;long;
636 InfoRow<NS_sprm::PicBrcBottom80>(), // pic.brcBottom;BRC;long;
637 InfoRow<NS_sprm::PicBrcRight80>(), // pic.brcRight;BRC;long;
638 InfoRow<NS_sprm::ScnsPgn>(), // sep.cnsPgn;cns;byte;
639 InfoRow<NS_sprm::SiHeadingPgn>(), // sep.iHeadingPgn;heading number
640 // level;byte;
641 {NS_sprm::LN_SOlstAnm, { 0, L_VAR} }, // "sprmSOlstAnm" sep.olstAnm;OLST;variable length;
642 InfoRow<NS_sprm::SDxaColWidth>(), // sep.rgdxaColWidthSpacing;
643 InfoRow<NS_sprm::SDxaColSpacing>(), // sep.rgdxaColWidthSpacing;
644 // complex
645 InfoRow<NS_sprm::SFEvenlySpaced>(), // sep.fEvenlySpaced;1 or 0
646 InfoRow<NS_sprm::SFProtected>(), // sep.fUnlocked;1 or 0;byte;
647 InfoRow<NS_sprm::SDmBinFirst>(), // sep.dmBinFirst;;word;
648 InfoRow<NS_sprm::SDmBinOther>(), // sep.dmBinOther;;word;
649 InfoRow<NS_sprm::SBkc>(), // sep.bkc;bkc;byte;
650 InfoRow<NS_sprm::SFTitlePage>(), // sep.fTitlePage;0 or 1;byte;
651 InfoRow<NS_sprm::SCcolumns>(), // sep.ccolM1;# of cols - 1;word;
652 InfoRow<NS_sprm::SDxaColumns>(), // sep.dxaColumns;dxa;word;
653 {NS_sprm::LN_SFAutoPgn, { 1, L_FIX} }, // "sprmSFAutoPgn" sep.fAutoPgn;obsolete;byte;
654 InfoRow<NS_sprm::SNfcPgn>(), // sep.nfcPgn;nfc;byte;
655 {NS_sprm::LN_SDyaPgn, { 2, L_FIX} }, // "sprmSDyaPgn" sep.dyaPgn;dya;short;
656 {NS_sprm::LN_SDxaPgn, { 2, L_FIX} }, // "sprmSDxaPgn" sep.dxaPgn;dya;short;
657 InfoRow<NS_sprm::SFPgnRestart>(), // sep.fPgnRestart;0 or 1;byte;
658 InfoRow<NS_sprm::SFEndnote>(), // sep.fEndnote;0 or 1;byte;
659 InfoRow<NS_sprm::SLnc>(), // sep.lnc;lnc;byte;
660 {NS_sprm::LN_SGprfIhdt, { 1, L_FIX} }, // "sprmSGprfIhdt" sep.grpfIhdt;grpfihdt
661 InfoRow<NS_sprm::SNLnnMod>(), // sep.nLnnMod;non-neg int.;word;
662 InfoRow<NS_sprm::SDxaLnn>(), // sep.dxaLnn;dxa;word;
663 InfoRow<NS_sprm::SDyaHdrTop>(), // sep.dyaHdrTop;dya;word;
664 InfoRow<NS_sprm::SDyaHdrBottom>(), // sep.dyaHdrBottom;dya;word;
665 InfoRow<NS_sprm::SLBetween>(), // sep.fLBetween;0 or 1;byte;
666 InfoRow<NS_sprm::SVjc>(), // sep.vjc;vjc;byte;
667 InfoRow<NS_sprm::SLnnMin>(), // sep.lnnMin;lnn;word;
668 InfoRow<NS_sprm::SPgnStart97>(), // sep.pgnStart;pgn;word;
669 InfoRow<NS_sprm::SBOrientation>(), // sep.dmOrientPage;dm;byte;
670 {NS_sprm::LN_SBCustomize, { 1, L_FIX} }, // "sprmSBCustomize" ;;;
671 InfoRow<NS_sprm::SXaPage>(), // sep.xaPage;xa;word;
672 InfoRow<NS_sprm::SYaPage>(), // sep.yaPage;ya;word;
673 InfoRow<NS_sprm::SDxaLeft>(), // sep.dxaLeft;dxa;word;
674 InfoRow<NS_sprm::SDxaRight>(), // sep.dxaRight;dxa;word;
675 InfoRow<NS_sprm::SDyaTop>(), // sep.dyaTop;dya;word;
676 InfoRow<NS_sprm::SDyaBottom>(), // sep.dyaBottom;dya;word;
677 InfoRow<NS_sprm::SDzaGutter>(), // sep.dzaGutter;dza;word;
678 InfoRow<NS_sprm::SDmPaperReq>(), // sep.dmPaperReq;dm;word;
679 {NS_sprm::LN_SPropRMark, { 0, L_VAR} }, // "sprmSPropRMark" sep.fPropRMark,
680 // sep.ibstPropRMark, sep.dttmPropRMark ;complex
681 InfoRow<NS_sprm::SFBiDi>(), // ;;;
682 {NS_sprm::LN_SFFacingCol, { 1, L_FIX} }, // "sprmSFFacingCol" ;;;
683 InfoRow<NS_sprm::SFRTLGutter>(), //, set to one if gutter is on
684 // right
685 InfoRow<NS_sprm::SBrcTop80>(), // sep.brcTop;BRC;long;
686 InfoRow<NS_sprm::SBrcLeft80>(), // sep.brcLeft;BRC;long;
687 InfoRow<NS_sprm::SBrcBottom80>(), // sep.brcBottom;BRC;long;
688 InfoRow<NS_sprm::SBrcRight80>(), // sep.brcRight;BRC;long;
689 InfoRow<NS_sprm::SPgbProp>(), // sep.pgbProp;;word;
690 InfoRow<NS_sprm::SDxtCharSpace>(), // sep.dxtCharSpace;dxt;long;
691 InfoRow<NS_sprm::SDyaLinePitch>(),
692 // sep.dyaLinePitch;dya; WRONG:long; RIGHT:short; !
693 InfoRow<NS_sprm::SClm>(), // ;;;
694 InfoRow<NS_sprm::STextFlow>(), // sep.wTextFlow;complex
695 InfoRow<NS_sprm::TJc90>(), // tap.jc;jc;word (low order byte is
696 // significant);
697 InfoRow<NS_sprm::TDxaLeft>(), // tap.rgdxaCenter
698 InfoRow<NS_sprm::TDxaGapHalf>(), // tap.dxaGapHalf,
699 // tap.rgdxaCenter
700 InfoRow<NS_sprm::TFCantSplit90>(), // tap.fCantSplit90;1 or 0;byte;
701 InfoRow<NS_sprm::TTableHeader>(), // tap.fTableHeader;1 or 0;byte;
702 InfoRow<NS_sprm::TFCantSplit>(), // tap.fCantSplit;1 or 0;byte;
703 InfoRow<NS_sprm::TTableBorders80>(), // tap.rgbrcTable;complex
704 {NS_sprm::LN_TDefTable10, { 0, L_VAR2} }, // "sprmTDefTable10" tap.rgdxaCenter,
705 // tap.rgtc;complex
706 InfoRow<NS_sprm::TDyaRowHeight>(), // tap.dyaRowHeight;dya;word;
707 {NS_sprm::LN_TDefTable, { 0, L_VAR2} }, // "sprmTDefTable" tap.rgtc;complex
708 InfoRow<NS_sprm::TDefTableShd80>(), // tap.rgshd;complex
709 InfoRow<NS_sprm::TTlp>(), // tap.tlp;TLP;4 bytes;
710 InfoRow<NS_sprm::TFBiDi>(), // ;;;
711 {NS_sprm::LN_THTMLProps, { 1, L_FIX} }, // "sprmTHTMLProps" ;;;
712 InfoRow<NS_sprm::TSetBrc80>(), // tap.rgtc[].rgbrc;complex
713 InfoRow<NS_sprm::TInsert>(), // tap.rgdxaCenter, tap.rgtc;complex
714 InfoRow<NS_sprm::TDelete>(), // tap.rgdxaCenter, tap.rgtc;complex
715 InfoRow<NS_sprm::TDxaCol>(), // tap.rgdxaCenter;complex
716 InfoRow<NS_sprm::TMerge>(), // tap.fFirstMerged, tap.fMerged;
717 InfoRow<NS_sprm::TSplit>(), // tap.fFirstMerged, tap.fMerged;
718 {NS_sprm::LN_TSetBrc10, { 0, L_VAR} }, // "sprmTSetBrc10" tap.rgtc[].rgbrc;complex
719 {NS_sprm::LN_TSetShd80, { 0, L_VAR} }, // "sprmTSetShd80" tap.rgshd;complex
720 {NS_sprm::LN_TSetShdOdd80, { 0, L_VAR} }, // "sprmTSetShdOdd80" tap.rgshd;complex
721 InfoRow<NS_sprm::TTextFlow>(), // tap.rgtc[].fVerticaltap,
722 // rgtc[].fBackwardtap, rgtc[].fRotateFont;0 or 10
723 // or 10 or 1;word;
724 {NS_sprm::LN_TDiagLine, { 1, L_FIX} }, // "sprmTDiagLine" ;;;
725 InfoRow<NS_sprm::TVertMerge>(), // tap.rgtc[].vertMerge
726 InfoRow<NS_sprm::TVertAlign>(), // tap.rgtc[].vertAlign
727 InfoRow<NS_sprm::CFELayout>(),
728 InfoRow<NS_sprm::PItap>(), // undocumented
729 InfoRow<NS_sprm::TTableWidth>(), // undocumented
730 InfoRow<NS_sprm::TDefTableShd>(),
731 InfoRow<NS_sprm::TTableBorders>(),
732 InfoRow<NS_sprm::TBrcTopCv>(), // undocumented
733 InfoRow<NS_sprm::TBrcLeftCv>(), // undocumented
734 InfoRow<NS_sprm::TBrcBottomCv>(), // undocumented
735 InfoRow<NS_sprm::TBrcRightCv>(), // undocumented
736 InfoRow<NS_sprm::TCellPadding>(), // undocumented
737 InfoRow<NS_sprm::TCellPaddingDefault>(), // undocumented
738 {0xD238, { 0, L_VAR} }, // undocumented sep
739 InfoRow<NS_sprm::PBrcTop>(),
740 InfoRow<NS_sprm::PBrcLeft>(),
741 InfoRow<NS_sprm::PBrcBottom>(),
742 InfoRow<NS_sprm::PBrcRight>(),
743 InfoRow<NS_sprm::PBrcBetween>(),
744 InfoRow<NS_sprm::TWidthIndent>(), // undocumented
745 InfoRow<NS_sprm::CRgLid0>(), // chp.rglid[0];LID: for non-FE text
746 InfoRow<NS_sprm::CRgLid1>(), // chp.rglid[1];LID: for Far East text
747 {0x6463, { 4, L_FIX} }, // undocumented
748 InfoRow<NS_sprm::PJc>(), // undoc, must be asian version of "sprmPJc"
749 InfoRow<NS_sprm::PDxaRight>(), // undoc, must be asian version of "sprmPDxaRight"
750 InfoRow<NS_sprm::PDxaLeft>(), // undoc, must be asian version of "sprmPDxaLeft"
751 InfoRow<NS_sprm::PDxaLeft1>(), // undoc, must be asian version of "sprmPDxaLeft1"
752 InfoRow<NS_sprm::TFAutofit>(), // undocumented
753 InfoRow<NS_sprm::TPc>(), // undocumented
754 InfoRow<NS_sprm::SRsid>(), // undocumented, sep, perhaps related to textgrids ?
755 InfoRow<NS_sprm::SFpc>(), // undocumented, sep
756 InfoRow<NS_sprm::PFInnerTableCell>(), // undocumented, subtable "sprmPFInTable" equiv ?
757 InfoRow<NS_sprm::PFInnerTtp>(), // undocumented, subtable "sprmPFTtp" equiv ?
758 InfoRow<NS_sprm::TDxaAbs>(), // undocumented
759 InfoRow<NS_sprm::TDyaAbs>(), // undocumented
760 InfoRow<NS_sprm::TDxaFromText>(), // undocumented
761 InfoRow<NS_sprm::CRsidProp>(), // undocumented
762 InfoRow<NS_sprm::CRsidText>(), // undocumented
763 InfoRow<NS_sprm::CCv>(), // text colour
764 InfoRow<NS_sprm::PShd>(), // undocumented, para back colour
765 InfoRow<NS_sprm::PRsid>(), // undocumented
766 InfoRow<NS_sprm::PTableProps>(), // undocumented
767 InfoRow<NS_sprm::TWidthBefore>(), // undocumented
768 InfoRow<NS_sprm::TSetShdTable>(), // undocumented, something to do with colour.
769 InfoRow<NS_sprm::TDefTableShdRaw>(), // undocumented, something to do with colour.
770 InfoRow<NS_sprm::CShd>(), // text backcolour
771 InfoRow<NS_sprm::SRncFtn>(), // undocumented, sep
772 InfoRow<NS_sprm::PFDyaBeforeAuto>(), // undocumented, para autobefore
773 InfoRow<NS_sprm::PFDyaAfterAuto>(), // undocumented, para autoafter
774 // "sprmPFContextualSpacing", don't add space between para of the same style
775 InfoRow<NS_sprm::PFContextualSpacing>(),
776 };
777
778 static wwSprmSearcher aSprmSrch(aSprms, SAL_N_ELEMENTS(aSprms));
779 return &aSprmSrch;
780};
781
782wwSprmParser::wwSprmParser(const WW8Fib& rFib) : meVersion(rFib.GetFIBVersion())
783{
784 OSL_ENSURE((meVersion >= ww::eWW1 && meVersion <= ww::eWW8),
785 "Impossible value for version");
786
788
789 if (meVersion <= ww::eWW2)
791 else if (meVersion < ww::eWW8)
793 else
795}
796
798{
799 const SprmInfo* pFound = mpKnownSprms->search(nId);
800 if (pFound != nullptr)
801 {
802 return *pFound;
803 }
804
805 OSL_ENSURE(ww::IsEightPlus(meVersion),
806 "Unknown ww7- sprm, dangerous, report to development");
807
808 //All the unknown ww7 sprms appear to be variable (which makes sense)
809 SprmInfo aSrch = { 0, L_VAR };
810 if (ww::IsEightPlus(meVersion)) //We can recover perfectly in this case
811 {
812 aSrch.nVari = L_FIX;
813 switch (nId >> 13)
814 {
815 case 0:
816 case 1:
817 aSrch.nLen = 1;
818 break;
819 case 2:
820 aSrch.nLen = 2;
821 break;
822 case 3:
823 aSrch.nLen = 4;
824 break;
825 case 4:
826 case 5:
827 aSrch.nLen = 2;
828 break;
829 case 6:
830 aSrch.nLen = 0;
831 aSrch.nVari = L_VAR;
832 break;
833 case 7:
834 default:
835 aSrch.nLen = 3;
836 break;
837 }
838 }
839 return aSrch;
840}
841
842//-end
843
845{
846 sal_uInt8 n = *p;
847 p += 1;
848 return n;
849}
850
851static sal_uInt16 Get_UShort( sal_uInt8 *& p )
852{
853 const sal_uInt16 n = SVBT16ToUInt16( *reinterpret_cast<SVBT16*>(p) );
854 p += 2;
855 return n;
856}
857
858static sal_Int16 Get_Short( sal_uInt8 *& p )
859{
860 return Get_UShort(p);
861}
862
863static sal_uInt32 Get_ULong( sal_uInt8 *& p )
864{
865 sal_uInt32 n = SVBT32ToUInt32( *reinterpret_cast<SVBT32*>(p) );
866 p += 4;
867 return n;
868}
869
870static sal_Int32 Get_Long( sal_uInt8 *& p )
871{
872 return Get_ULong(p);
873}
874
875WW8SprmIter::WW8SprmIter(const sal_uInt8* pSprms_, sal_Int32 nLen_,
876 const wwSprmParser &rParser)
877 : mrSprmParser(rParser), m_pSprms( pSprms_), m_nRemLen( nLen_)
878{
880}
881
882void WW8SprmIter::SetSprms(const sal_uInt8* pSprms_, sal_Int32 nLen_)
883{
884 m_pSprms = pSprms_;
885 m_nRemLen = nLen_;
887}
888
890{
891 if (m_nRemLen > 0 )
892 {
893 sal_uInt16 nSize = m_nCurrentSize;
894 if (nSize > m_nRemLen)
895 nSize = m_nRemLen;
896 m_pSprms += nSize;
897 m_nRemLen -= nSize;
899 }
900}
901
903{
904 bool bValid = (m_pSprms && m_nRemLen >= mrSprmParser.MinSprmLen());
905
906 if (bValid)
907 {
911 bValid = m_nCurrentSize <= m_nRemLen;
912 SAL_WARN_IF(!bValid, "sw.ww8", "sprm longer than remaining bytes, doc or parser is wrong");
913 }
914
915 if (!bValid)
916 {
917 m_nCurrentId = 0;
918 m_pCurrentParams = nullptr;
919 m_nCurrentSize = 0;
920 m_nRemLen = 0;
921 }
922}
923
924SprmResult WW8SprmIter::FindSprm(sal_uInt16 nId, bool bFindFirst, const sal_uInt8* pNextByteMatch)
925{
926 SprmResult aRet;
927
928 while (GetSprms())
929 {
930 if (GetCurrentId() == nId)
931 {
932 sal_Int32 nFixedLen = mrSprmParser.DistanceToData(nId);
933 sal_Int32 nL = mrSprmParser.GetSprmSize(nId, GetSprms(), GetRemLen());
934 SprmResult aSprmResult(GetCurrentParams(), nL - nFixedLen);
935 // typically pNextByteMatch is nullptr and we just return the first match
936 // very occasionally we want one with a specific following byte
937 if ( !pNextByteMatch || (aSprmResult.nRemainingData >= 1 && *aSprmResult.pSprm == *pNextByteMatch) )
938 {
939 if ( bFindFirst )
940 return aSprmResult;
941 aRet = aSprmResult;
942 }
943 }
944 advance();
945 }
946
947 return aRet;
948}
949
950// temporary test
951// WW8PLCFx_PCDAttrs cling to WW8PLCF_Pcd and therefore do not have their own iterators.
952// All methods relating to iterators are therefore dummies.
954 WW8PLCFx_PCD* pPLCFx_PCD, const WW8ScannerBase* pBase)
955 : WW8PLCFx(rFib, true), m_pPcdI(pPLCFx_PCD->GetPLCFIter()),
956 m_pPcd(pPLCFx_PCD), mrGrpprls(pBase->m_aPieceGrpprls)
957{
958}
959
961{
962 return 0;
963}
964
966{
967}
968
970{
971 return true;
972}
973
975{
976}
977
979{
980 return m_pPcd ? m_pPcd->Where() : WW8_CP_MAX;
981}
982
984{
985 void* pData;
986
987 p->bRealLineEnd = false;
988 if ( !m_pPcdI || !m_pPcdI->Get(p->nStartPos, p->nEndPos, pData) )
989 {
990 // PLCF fully processed
991 p->nStartPos = p->nEndPos = WW8_CP_MAX;
992 p->pMemPos = nullptr;
993 p->nSprmsLen = 0;
994 return;
995 }
996
997 const sal_uInt16 nPrm = SVBT16ToUInt16( static_cast<WW8_PCD*>(pData)->prm );
998 if ( nPrm & 1 )
999 {
1000 // PRM Variant 2
1001 const sal_uInt16 nSprmIdx = nPrm >> 1;
1002
1003 if( nSprmIdx >= mrGrpprls.size() )
1004 {
1005 // Invalid Index
1006 p->nStartPos = p->nEndPos = WW8_CP_MAX;
1007 p->pMemPos = nullptr;
1008 p->nSprmsLen = 0;
1009 return;
1010 }
1011 const sal_uInt8* pSprms = mrGrpprls[ nSprmIdx ].get();
1012
1013 p->nSprmsLen = SVBT16ToUInt16( pSprms ); // Length
1014 pSprms += 2;
1015 p->pMemPos = pSprms; // Position
1016 }
1017 else
1018 {
1019 // SPRM is stored directly into members var
1020 /*
1021 These are the attr that are in the piece-table instead of in the text!
1022 */
1023
1025 {
1026 m_aShortSprm[0] = static_cast<sal_uInt8>( ( nPrm & 0xfe) >> 1 );
1027 m_aShortSprm[1] = static_cast<sal_uInt8>( nPrm >> 8 );
1028 p->nSprmsLen = nPrm ? 2 : 0; // length
1029
1030 // store Position of internal mini storage in Data Pointer
1031 p->pMemPos = m_aShortSprm;
1032 }
1033 else
1034 {
1035 p->pMemPos = nullptr;
1036 p->nSprmsLen = 0;
1037 sal_uInt8 nSprmListIdx = static_cast<sal_uInt8>((nPrm & 0xfe) >> 1);
1038 if( nSprmListIdx )
1039 {
1040 // process Sprm Id Matching as explained in MS Documentation
1041
1042 // ''Property Modifier(variant 1) (PRM)''
1043 // see file: s62f39.htm
1044
1045 // Since Sprm is 7 bits, rgsprmPrm can hold 0x80 entries.
1046 static const sal_uInt16 aSprmId[0x80] =
1047 {
1048 // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1049 0x0000,0x0000,0x0000,0x0000,
1050 // sprmPIncLvl, sprmPJc, sprmPFSideBySide, sprmPFKeep
1051 0x2402,0x2403,NS_sprm::LN_PFSideBySide,0x2405,
1052 // sprmPFKeepFollow, sprmPFPageBreakBefore, sprmPBrcl,
1053 // sprmPBrcp
1055 // sprmPIlvl, sprmNoop, sprmPFNoLineNumb, sprmNoop
1056 0x260A,0x0000,0x240C,0x0000,
1057 // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1058 0x0000,0x0000,0x0000,0x0000,
1059 // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1060 0x0000,0x0000,0x0000,0x0000,
1061 // sprmPFInTable, sprmPFTtp, sprmNoop, sprmNoop
1062 0x2416,0x2417,0x0000,0x0000,
1063 // sprmNoop, sprmPPc, sprmNoop, sprmNoop
1064 0x0000,0x261B,0x0000,0x0000,
1065 // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1066 0x0000,0x0000,0x0000,0x0000,
1067 // sprmNoop, sprmPWr, sprmNoop, sprmNoop
1068 0x0000,0x2423,0x0000,0x0000,
1069 // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1070 0x0000,0x0000,0x0000,0x0000,
1071 // sprmPFNoAutoHyph, sprmNoop, sprmNoop, sprmNoop
1072 0x242A,0x0000,0x0000,0x0000,
1073 // sprmNoop, sprmNoop, sprmPFLocked, sprmPFWidowControl
1074 0x0000,0x0000,0x2430,0x2431,
1075 // sprmNoop, sprmPFKinsoku, sprmPFWordWrap,
1076 // sprmPFOverflowPunct
1077 0x0000,0x2433,0x2434,0x2435,
1078 // sprmPFTopLinePunct, sprmPFAutoSpaceDE,
1079 // sprmPFAutoSpaceDN, sprmNoop
1080 0x2436,0x2437,0x2438,0x0000,
1081 // sprmNoop, sprmPISnapBaseLine, sprmNoop, sprmNoop
1082 0x0000,NS_sprm::LN_PISnapBaseLine,0x000,0x0000,
1083 // sprmNoop, sprmCFStrikeRM, sprmCFRMark, sprmCFFieldVanish
1084 0x0000,0x0800,0x0801,0x0802,
1085 // sprmNoop, sprmNoop, sprmNoop, sprmCFData
1086 0x0000,0x0000,0x0000,0x0806,
1087 // sprmNoop, sprmNoop, sprmNoop, sprmCFOle2
1088 0x0000,0x0000,0x0000,0x080A,
1089 // sprmNoop, sprmCHighlight, sprmCFEmboss, sprmCSfxText
1090 0x0000,0x2A0C,0x0858,0x2859,
1091 // sprmNoop, sprmNoop, sprmNoop, sprmCPlain
1092 0x0000,0x0000,0x0000,0x2A33,
1093 // sprmNoop, sprmCFBold, sprmCFItalic, sprmCFStrike
1094 0x0000,0x0835,0x0836,0x0837,
1095 // sprmCFOutline, sprmCFShadow, sprmCFSmallCaps, sprmCFCaps,
1096 0x0838,0x0839,0x083a,0x083b,
1097 // sprmCFVanish, sprmNoop, sprmCKul, sprmNoop,
1098 0x083C,0x0000,0x2A3E,0x0000,
1099 // sprmNoop, sprmNoop, sprmCIco, sprmNoop,
1100 0x0000,0x0000,0x2A42,0x0000,
1101 // sprmCHpsInc, sprmNoop, sprmCHpsPosAdj, sprmNoop,
1103 // sprmCIss, sprmNoop, sprmNoop, sprmNoop,
1104 0x2A48,0x0000,0x0000,0x0000,
1105 // sprmNoop, sprmNoop, sprmNoop, sprmNoop,
1106 0x0000,0x0000,0x0000,0x0000,
1107 // sprmNoop, sprmNoop, sprmNoop, sprmCFDStrike,
1108 0x0000,0x0000,0x0000,0x2A53,
1109 // sprmCFImprint, sprmCFSpec, sprmCFObj, sprmPicBrcl,
1110 0x0854,0x0855,0x0856,NS_sprm::LN_PicBrcl,
1111 // sprmPOutLvl, sprmPFBiDi, sprmNoop, sprmNoop,
1112 0x2640,0x2441,0x0000,0x0000,
1113 // sprmNoop, sprmNoop, sprmPPnbrRMarkNot
1114 0x0000,0x0000,0x0000,0x0000
1115 };
1116
1117 // find real Sprm Id:
1118 const sal_uInt16 nSprmId = aSprmId[ nSprmListIdx ];
1119
1120 if( nSprmId )
1121 {
1122 // move Sprm Id and Sprm Param to internal mini storage:
1123 m_aShortSprm[0] = static_cast<sal_uInt8>( nSprmId & 0x00ff) ;
1124 m_aShortSprm[1] = static_cast<sal_uInt8>( ( nSprmId & 0xff00) >> 8 );
1125 m_aShortSprm[2] = static_cast<sal_uInt8>( nPrm >> 8 );
1126
1127 // store Sprm Length in member:
1128 p->nSprmsLen = nPrm ? 3 : 0;
1129
1130 // store Position of internal mini storage in Data Pointer
1131 p->pMemPos = m_aShortSprm;
1132 }
1133 }
1134 }
1135 }
1136}
1137
1139 WW8_CP nStartCp, bool bVer67P)
1140 : WW8PLCFx(rFib, false), m_nClipStart(-1)
1141{
1142 // construct own iterator
1143 m_pPcdI.reset( new WW8PLCFpcd_Iter(*pPLCFpcd, nStartCp) );
1144 m_bVer67= bVer67P;
1145}
1146
1148{
1149}
1150
1151sal_uInt32 WW8PLCFx_PCD::GetIMax() const
1152{
1153 return m_pPcdI ? m_pPcdI->GetIMax() : 0;
1154}
1155
1156sal_uInt32 WW8PLCFx_PCD::GetIdx() const
1157{
1158 return m_pPcdI ? m_pPcdI->GetIdx() : 0;
1159}
1160
1161void WW8PLCFx_PCD::SetIdx(sal_uInt32 nIdx)
1162{
1163 if (m_pPcdI)
1164 m_pPcdI->SetIdx( nIdx );
1165}
1166
1168{
1169 return m_pPcdI && m_pPcdI->SeekPos( nCpPos );
1170}
1171
1173{
1174 return m_pPcdI ? m_pPcdI->Where() : WW8_CP_MAX;
1175}
1176
1177tools::Long WW8PLCFx_PCD::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
1178{
1179 void* pData;
1180 rLen = 0;
1181
1182 if ( !m_pPcdI || !m_pPcdI->Get(rStart, rEnd, pData) )
1183 {
1184 rStart = rEnd = WW8_CP_MAX;
1185 return -1;
1186 }
1187 return m_pPcdI->GetIdx();
1188}
1189
1191{
1192 OSL_ENSURE(m_pPcdI , "missing pPcdI");
1193 if (m_pPcdI)
1194 m_pPcdI->advance();
1195}
1196
1198{
1199 WW8_CP nCpStart, nCpEnd;
1200 void* pData;
1201
1202 if ( !m_pPcdI->Get(nCpStart, nCpEnd, pData) )
1203 {
1204 OSL_ENSURE( false, "CurrentPieceStartCp2Fc() with false Cp found (1)" );
1205 return WW8_FC_MAX;
1206 }
1207
1208 OSL_ENSURE( nCp >= nCpStart && nCp < nCpEnd,
1209 "AktPieceCp2Fc() with false Cp found (2)" );
1210
1211 if( nCp < nCpStart )
1212 nCp = nCpStart;
1213 if( nCp >= nCpEnd )
1214 nCp = nCpEnd - 1;
1215
1216 bool bIsUnicode = false;
1217 WW8_FC nFC = SVBT32ToUInt32( static_cast<WW8_PCD*>(pData)->fc );
1218 if( !m_bVer67 )
1219 nFC = WW8PLCFx_PCD::TransformPieceAddress( nFC, bIsUnicode );
1220
1221 WW8_CP nDistance;
1222 bool bFail = o3tl::checked_sub(nCp, nCpStart, nDistance);
1223 if (bFail)
1224 {
1225 SAL_WARN("sw.ww8", "broken offset, ignoring");
1226 return WW8_FC_MAX;
1227 }
1228
1229 if (bIsUnicode)
1230 {
1231 bFail = o3tl::checked_multiply<WW8_CP>(nDistance, 2, nDistance);
1232 if (bFail)
1233 {
1234 SAL_WARN("sw.ww8", "broken offset, ignoring");
1235 return WW8_FC_MAX;
1236 }
1237 }
1238
1239 WW8_FC nRet;
1240 bFail = o3tl::checked_add(nFC, nDistance, nRet);
1241 if (bFail)
1242 {
1243 SAL_WARN("sw.ww8", "broken offset, ignoring");
1244 return WW8_FC_MAX;
1245 }
1246
1247 return nRet;
1248}
1249
1251 const WW8ScannerBase *pSBase )
1252{
1253 //No point going anywhere with this
1254 if ((rStartPos == WW8_CP_MAX) && (rEndPos == WW8_CP_MAX))
1255 return;
1256
1257 rStartPos = pSBase->WW8Fc2Cp( rStartPos );
1258 rEndPos = pSBase->WW8Fc2Cp( rEndPos );
1259}
1260
1262{
1263 WW8_CP nCpStart, nCpEnd;
1264 void* pData;
1265 if ( !m_pPcdI->Get( nCpStart, nCpEnd, pData ) )
1266 {
1267 OSL_ENSURE( false, "CurrentPieceStartFc2Cp() - error" );
1268 return WW8_CP_MAX;
1269 }
1270 bool bIsUnicode = false;
1271 sal_Int32 nFcStart = SVBT32ToUInt32( static_cast<WW8_PCD*>(pData)->fc );
1272 if( !m_bVer67 )
1273 nFcStart = WW8PLCFx_PCD::TransformPieceAddress( nFcStart, bIsUnicode );
1274
1275 sal_Int32 nUnicodeFactor = bIsUnicode ? 2 : 1;
1276
1277 if( nStartPos < nFcStart )
1278 nStartPos = nFcStart;
1279
1280 WW8_CP nCpLen;
1281 bool bFail = o3tl::checked_sub(nCpEnd, nCpStart, nCpLen);
1282 if (bFail)
1283 {
1284 SAL_WARN("sw.ww8", "broken offset, ignoring");
1285 return WW8_CP_MAX;
1286 }
1287
1288 WW8_CP nCpLenBytes;
1289 bFail = o3tl::checked_multiply(nCpLen, nUnicodeFactor, nCpLenBytes);
1290 if (bFail)
1291 {
1292 SAL_WARN("sw.ww8", "broken offset, ignoring");
1293 return WW8_CP_MAX;
1294 }
1295
1296 WW8_FC nFcLen;
1297 bFail = o3tl::checked_add(nFcStart, nCpLenBytes, nFcLen);
1298 if (bFail)
1299 {
1300 SAL_WARN("sw.ww8", "broken offset, ignoring");
1301 return WW8_CP_MAX;
1302 }
1303
1304 WW8_FC nFcEnd;
1305 bFail = o3tl::checked_add(nFcStart, nFcLen, nFcEnd);
1306 if (bFail)
1307 {
1308 SAL_WARN("sw.ww8", "broken offset, ignoring");
1309 return WW8_CP_MAX;
1310 }
1311
1312
1313 if (nStartPos >= nFcEnd)
1314 nStartPos = nFcEnd - (1 * nUnicodeFactor);
1315
1316 WW8_FC nFcDiff = (nStartPos - nFcStart) / nUnicodeFactor;
1317
1318 WW8_FC nCpRet;
1319 bFail = o3tl::checked_add(nCpStart, nFcDiff, nCpRet);
1320 if (bFail)
1321 {
1322 SAL_WARN("sw.ww8", "broken offset, ignoring");
1323 return WW8_CP_MAX;
1324 }
1325
1326 return nCpRet;
1327}
1328
1329// Helper routines for all
1330
1331// Convert BRC from WW6 to WW8 format
1333{
1334 sal_uInt8 _dptLineWidth = brcVer6.dxpLineWidth(),
1335 _brcType = brcVer6.brcType();
1336
1337 if (_dptLineWidth > 5) // this signifies dashed(6) or dotted(7) line
1338 {
1339 _brcType = _dptLineWidth;
1340 _dptLineWidth = 1;
1341 }
1342 _dptLineWidth *= 6; // convert units from 0.75pt to 1/8pt
1343
1344 *this = WW8_BRC(_dptLineWidth, _brcType, brcVer6.ico(), brcVer6.dxpSpace(),
1345 brcVer6.fShadow(), false);
1346}
1347
1348// Convert BRC from WW8 to WW9 format
1350{
1351 if (brcVer8.isNil()) {
1352 UInt32ToSVBT32(0, aBits1);
1353 UInt32ToSVBT32(0xffffffff, aBits2);
1354 }
1355 else
1356 {
1357 sal_uInt32 _cv = brcVer8.ico() == 0 ? 0xff000000 // "auto" colour
1359 *this = WW8_BRCVer9(_cv, brcVer8.dptLineWidth(), brcVer8.brcType(),
1360 brcVer8.dptSpace(), brcVer8.fShadow(), brcVer8.fFrame());
1361 }
1362}
1363
1364short WW8_BRC::DetermineBorderProperties(short *pSpace) const
1365{
1366 WW8_BRCVer9 brcVer9(*this);
1367 return brcVer9.DetermineBorderProperties(pSpace);
1368}
1369
1371{
1372 /*
1373 Word does not factor the width of the border into the width/height
1374 stored in the information for graphic/table/object widths, so we need
1375 to figure out this extra width here and utilize the returned size in
1376 our calculations
1377 */
1378 short nMSTotalWidth;
1379
1380 //Specification in 8ths of a point, 1 Point = 20 Twips, so by 2.5
1381 nMSTotalWidth = static_cast<short>(dptLineWidth()) * 20 / 8;
1382
1383 //Figure out the real size of the border according to word
1384 switch (brcType())
1385 {
1386 //Note that codes over 25 are undocumented, and I can't create
1387 //these 4 here in the wild.
1388 case 2:
1389 case 4:
1390 case 5:
1391 case 22:
1392 OSL_FAIL("Can't create these from the menus, please report");
1393 break;
1394 default:
1395 case 23: //Only 3pt in the menus, but honours the size setting.
1396 break;
1397 case 10:
1398 /*
1399 triple line is five times the width of an ordinary line,
1400 except that the smallest 1/4 point size appears to have
1401 exactly the same total border width as a 3/4 point size
1402 ordinary line, i.e. three times the nominal line width. The
1403 second smallest 1/2 point size appears to have exactly the
1404 total border width as a 2 1/4 border, i.e 4.5 times the size.
1405 */
1406 if (nMSTotalWidth == 5)
1407 nMSTotalWidth*=3;
1408 else if (nMSTotalWidth == 10)
1409 nMSTotalWidth = nMSTotalWidth*9/2;
1410 else
1411 nMSTotalWidth*=5;
1412 break;
1413 case 20:
1414 /*
1415 wave, the dimensions appear to be created by the drawing of
1416 the wave, so we have only two possibilities in the menus, 3/4
1417 point is equal to solid 3 point. This calculation seems to
1418 match well to results.
1419 */
1420 nMSTotalWidth +=45;
1421 break;
1422 case 21:
1423 /*
1424 double wave, the dimensions appear to be created by the
1425 drawing of the wave, so we have only one possibilities in the
1426 menus, that of 3/4 point is equal to solid 3 point. This
1427 calculation seems to match well to results.
1428 */
1429 nMSTotalWidth += 45*2;
1430 break;
1431 }
1432
1433 if (pSpace)
1434 *pSpace = static_cast<short>(dptSpace()) * 20; // convert from points to twips
1435 return nMSTotalWidth;
1436}
1437
1438/*
1439 * WW8Cp2Fc is a good method, a CP always maps to a FC
1440 * WW8Fc2Cp on the other hand is more dubious, a random FC
1441 * may not map to a valid CP. Try and avoid WW8Fc2Cp where
1442 * possible
1443 */
1445{
1446 WW8_CP nFallBackCpEnd = WW8_CP_MAX;
1447 if( nFcPos == WW8_FC_MAX )
1448 return nFallBackCpEnd;
1449
1450 bool bIsUnicode;
1451 if (m_pWw8Fib->m_nVersion >= 8)
1452 bIsUnicode = false;
1453 else
1454 bIsUnicode = m_pWw8Fib->m_fExtChar;
1455
1456 if( m_pPieceIter ) // Complex File ?
1457 {
1458 sal_uInt32 nOldPos = m_pPieceIter->GetIdx();
1459
1460 for (m_pPieceIter->SetIdx(0);
1461 m_pPieceIter->GetIdx() < m_pPieceIter->GetIMax(); m_pPieceIter->advance())
1462 {
1463 WW8_CP nCpStart, nCpEnd;
1464 void* pData;
1465 if( !m_pPieceIter->Get( nCpStart, nCpEnd, pData ) )
1466 { // outside PLCFfpcd ?
1467 OSL_ENSURE( false, "PLCFpcd-WW8Fc2Cp() went wrong" );
1468 break;
1469 }
1470 sal_Int32 nFcStart = SVBT32ToUInt32( static_cast<WW8_PCD*>(pData)->fc );
1471 if (m_pWw8Fib->m_nVersion >= 8)
1472 {
1473 nFcStart = WW8PLCFx_PCD::TransformPieceAddress( nFcStart,
1474 bIsUnicode );
1475 }
1476 else
1477 {
1478 bIsUnicode = m_pWw8Fib->m_fExtChar;
1479 }
1480
1481 sal_Int32 nLen;
1482 if (o3tl::checked_sub(nCpEnd, nCpStart, nLen))
1483 {
1484 SAL_WARN("sw.ww8", "broken offset, ignoring");
1485 return WW8_CP_MAX;
1486 }
1487 if (bIsUnicode)
1488 {
1489 if (o3tl::checked_multiply<WW8_CP>(nLen, 2, nLen))
1490 {
1491 SAL_WARN("sw.ww8", "broken offset, ignoring");
1492 return WW8_CP_MAX;
1493 }
1494 }
1495
1496 /*
1497 If this cp is inside this piece, or it's the last piece and we are
1498 on the very last cp of that piece
1499 */
1500 if (nFcPos >= nFcStart)
1501 {
1502 // found
1503 WW8_FC nFcDiff;
1504 if (o3tl::checked_sub(nFcPos, nFcStart, nFcDiff))
1505 {
1506 SAL_WARN("sw.ww8", "broken offset, ignoring");
1507 return WW8_CP_MAX;
1508 }
1509 if (bIsUnicode)
1510 nFcDiff /= 2;
1511 WW8_CP nTempCp;
1512 if (o3tl::checked_add(nCpStart, nFcDiff, nTempCp))
1513 {
1514 SAL_WARN("sw.ww8", "broken offset, ignoring");
1515 return WW8_CP_MAX;
1516 }
1517 WW8_FC nFcEnd;
1518 if (o3tl::checked_add(nFcStart, nLen, nFcEnd))
1519 {
1520 SAL_WARN("sw.ww8", "broken offset, ignoring");
1521 return WW8_CP_MAX;
1522 }
1523 if (nFcPos < nFcEnd)
1524 {
1525 m_pPieceIter->SetIdx( nOldPos );
1526 return nTempCp;
1527 }
1528 else if (nFcPos == nFcEnd)
1529 {
1530 //Keep this cp as its on a piece boundary because we might
1531 //need it if tests fail
1532 nFallBackCpEnd = nTempCp;
1533 }
1534 }
1535 }
1536 // not found
1537 m_pPieceIter->SetIdx( nOldPos ); // not found
1538 /*
1539 If it was not found, then this is because it has fallen between two
1540 stools, i.e. either it is the last cp/fc of the last piece, or it is
1541 the last cp/fc of a disjoint piece.
1542 */
1543 return nFallBackCpEnd;
1544 }
1545
1546 WW8_FC nFcDiff;
1547 if (o3tl::checked_sub(nFcPos, m_pWw8Fib->m_fcMin, nFcDiff))
1548 {
1549 SAL_WARN("sw.ww8", "broken offset, ignoring");
1550 return WW8_CP_MAX;
1551 }
1552
1553 // No complex file
1554 if (!bIsUnicode)
1555 nFallBackCpEnd = nFcDiff;
1556 else
1557 nFallBackCpEnd = (nFcDiff + 1) / 2;
1558
1559 return nFallBackCpEnd;
1560}
1561
1562// the fib of WinWord2 has a last entry of cpnBtePap of 2 byte sized type PN at
1563// offset 324
1564const int nSmallestPossibleFib = 326;
1565
1566WW8_FC WW8ScannerBase::WW8Cp2Fc(WW8_CP nCpPos, bool* pIsUnicode,
1567 WW8_CP* pNextPieceCp, bool* pTestFlag) const
1568{
1569 if( pTestFlag )
1570 *pTestFlag = true;
1571 if( WW8_CP_MAX == nCpPos )
1572 return WW8_CP_MAX;
1573
1574 bool bIsUnicode;
1575 if( !pIsUnicode )
1576 pIsUnicode = &bIsUnicode;
1577
1578 if (m_pWw8Fib->m_nVersion >= 8)
1579 *pIsUnicode = false;
1580 else
1581 *pIsUnicode = m_pWw8Fib->m_fExtChar;
1582
1583 WW8_FC nRet;
1584
1585 if( m_pPieceIter )
1586 {
1587 // Complex File
1588 if( pNextPieceCp )
1589 *pNextPieceCp = WW8_CP_MAX;
1590
1591 if( !m_pPieceIter->SeekPos( nCpPos ) )
1592 {
1593 if( pTestFlag )
1594 *pTestFlag = false;
1595 else {
1596 OSL_ENSURE( false, "Handed over wrong CP to WW8Cp2Fc()" );
1597 }
1598 return WW8_FC_MAX;
1599 }
1600 WW8_CP nCpStart, nCpEnd;
1601 void* pData;
1602 if( !m_pPieceIter->Get( nCpStart, nCpEnd, pData ) )
1603 {
1604 if( pTestFlag )
1605 *pTestFlag = false;
1606 else {
1607 OSL_ENSURE( false, "PLCFfpcd-Get went wrong" );
1608 }
1609 return WW8_FC_MAX;
1610 }
1611 if( pNextPieceCp )
1612 *pNextPieceCp = nCpEnd;
1613
1614 nRet = SVBT32ToUInt32( static_cast<WW8_PCD*>(pData)->fc );
1615 if (m_pWw8Fib->m_nVersion >= 8)
1616 nRet = WW8PLCFx_PCD::TransformPieceAddress( nRet, *pIsUnicode );
1617 else
1618 *pIsUnicode = m_pWw8Fib->m_fExtChar;
1619
1620 WW8_CP nCpLen;
1621 bool bFail = o3tl::checked_sub(nCpPos, nCpStart, nCpLen);
1622 if (bFail)
1623 {
1624 SAL_WARN("sw.ww8", "broken offset, ignoring");
1625 return WW8_CP_MAX;
1626 }
1627
1628 if (*pIsUnicode)
1629 {
1630 bFail = o3tl::checked_multiply<WW8_CP>(nCpLen, 2, nCpLen);
1631 if (bFail)
1632 {
1633 SAL_WARN("sw.ww8", "broken offset, ignoring");
1634 return WW8_CP_MAX;
1635 }
1636 }
1637
1638 bFail = o3tl::checked_add(nRet, nCpLen, nRet);
1639 if (bFail)
1640 {
1641 SAL_WARN("sw.ww8", "broken offset, ignoring");
1642 return WW8_CP_MAX;
1643 }
1644
1645 return nRet;
1646 }
1647
1648 if (*pIsUnicode)
1649 {
1650 const bool bFail = o3tl::checked_multiply<WW8_CP>(nCpPos, 2, nCpPos);
1651 if (bFail)
1652 {
1653 SAL_WARN("sw.ww8", "broken offset, ignoring");
1654 return WW8_CP_MAX;
1655 }
1656 }
1657
1658 // No complex file
1659 const bool bFail = o3tl::checked_add(m_pWw8Fib->m_fcMin, nCpPos, nRet);
1660 if (bFail)
1661 {
1662 SAL_WARN("sw.ww8", "broken offset, ignoring");
1663 return WW8_CP_MAX;
1664 }
1665
1666 // the text and the fib share the same stream, if the text is inside the fib
1667 // then it's definitely a bad offset. The smallest FIB supported is that of
1668 // WW2 which is 326 bytes in size
1669 if (nRet < nSmallestPossibleFib)
1670 {
1671 SAL_WARN("sw.ww8", "broken offset, ignoring");
1672 return WW8_CP_MAX;
1673 }
1674
1675 return nRet;
1676}
1677
1678std::unique_ptr<WW8PLCFpcd> WW8ScannerBase::OpenPieceTable( SvStream* pStr, const WW8Fib* pWwF )
1679{
1680 if ( ((8 > m_pWw8Fib->m_nVersion) && !pWwF->m_fComplex) || !pWwF->m_lcbClx )
1681 return nullptr;
1682
1683 if (pWwF->m_lcbClx < 0)
1684 return nullptr;
1685
1686 WW8_FC nClxPos = pWwF->m_fcClx;
1687
1688 if (!checkSeek(*pStr, nClxPos))
1689 return nullptr;
1690
1691 sal_Int32 nClxLen = pWwF->m_lcbClx;
1692 sal_Int32 nLeft = nClxLen;
1693
1694 while (true)
1695 {
1696 sal_uInt8 clxt(2);
1697 pStr->ReadUChar( clxt );
1698 nLeft--;
1699 if( 2 == clxt) // PLCFfpcd ?
1700 break; // PLCFfpcd found
1701 sal_uInt16 nLen(0);
1702 pStr->ReadUInt16( nLen );
1703 nLeft -= 2 + nLen;
1704 if( nLeft < 0 )
1705 return nullptr; // gone wrong
1706 if( 1 == clxt ) // clxtGrpprl ?
1707 {
1708 if (m_aPieceGrpprls.size() == SHRT_MAX)
1709 return nullptr;
1710 if (nLen > pStr->remainingSize())
1711 return nullptr;
1712 std::unique_ptr<sal_uInt8[]> p(new sal_uInt8[nLen+2]); // allocate
1713 ShortToSVBT16(nLen, p.get()); // add length
1714 if (!checkRead(*pStr, p.get()+2, nLen)) // read grpprl
1715 {
1716 return nullptr;
1717 }
1718 m_aPieceGrpprls.push_back(std::move(p)); // add to array
1719 }
1720 else
1721 {
1722 nLen = std::min<sal_uInt64>(nLen, pStr->remainingSize());
1723 pStr->Seek(pStr->Tell() + nLen); // non-Grpprl left
1724 }
1725 }
1726
1727 // read Piece Table PLCF
1728 sal_Int32 nPLCFfLen(0);
1729 if (pWwF->GetFIBVersion() <= ww::eWW2)
1730 {
1731 sal_Int16 nWordTwoLen(0);
1732 pStr->ReadInt16( nWordTwoLen );
1733 nPLCFfLen = nWordTwoLen;
1734 }
1735 else
1736 pStr->ReadInt32( nPLCFfLen );
1737 OSL_ENSURE( 65536 > nPLCFfLen, "PLCFfpcd above 64 k" );
1738 return std::make_unique<WW8PLCFpcd>( pStr, pStr->Tell(), nPLCFfLen, 8 );
1739}
1740
1742 SvStream* pDataSt, WW8Fib* pWwFib )
1743 : m_pWw8Fib(pWwFib)
1744{
1745 m_pPiecePLCF = OpenPieceTable( pTableSt, m_pWw8Fib ); // Complex
1746 if( m_pPiecePLCF )
1747 {
1749 m_pPLCFx_PCD.reset( new WW8PLCFx_PCD(*pWwFib, m_pPiecePLCF.get(), 0,
1751 m_pPLCFx_PCDAttrs.reset(new WW8PLCFx_PCDAttrs(*pWwFib,
1752 m_pPLCFx_PCD.get(), this));
1753 }
1754 else
1755 {
1756 m_pPieceIter = nullptr;
1757 m_pPLCFx_PCD = nullptr;
1758 m_pPLCFx_PCDAttrs = nullptr;
1759 }
1760
1761 // pChpPLCF and pPapPLCF may NOT be created before pPLCFx_PCD !!
1762 m_pChpPLCF.reset(new WW8PLCFx_Cp_FKP( pSt, pTableSt, pDataSt, *this, CHP )); // CHPX
1763 m_pPapPLCF.reset(new WW8PLCFx_Cp_FKP( pSt, pTableSt, pDataSt, *this, PAP )); // PAPX
1764
1765 m_pSepPLCF.reset(new WW8PLCFx_SEPX( pSt, pTableSt, *pWwFib, 0 )); // SEPX
1766
1767 // Footnotes
1768 m_pFootnotePLCF.reset(new WW8PLCFx_SubDoc( pTableSt, *pWwFib, 0,
1769 pWwFib->m_fcPlcffndRef, pWwFib->m_lcbPlcffndRef, pWwFib->m_fcPlcffndText,
1770 pWwFib->m_lcbPlcffndText, 2 ));
1771 // Endnotes
1772 m_pEdnPLCF.reset(new WW8PLCFx_SubDoc( pTableSt, *pWwFib, 0,
1773 pWwFib->m_fcPlcfendRef, pWwFib->m_lcbPlcfendRef, pWwFib->m_fcPlcfendText,
1774 pWwFib->m_lcbPlcfendText, 2 ));
1775 // Comments
1776 m_pAndPLCF.reset(new WW8PLCFx_SubDoc( pTableSt, *pWwFib, 0,
1777 pWwFib->m_fcPlcfandRef, pWwFib->m_lcbPlcfandRef, pWwFib->m_fcPlcfandText,
1778 pWwFib->m_lcbPlcfandText, IsSevenMinus(pWwFib->GetFIBVersion()) ? 20 : 30));
1779
1780 // Fields Main Text
1781 m_pFieldPLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_MAINTEXT));
1782 // Fields Header / Footer
1783 m_pFieldHdFtPLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_HDFT));
1784 // Fields Footnote
1785 m_pFieldFootnotePLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_FTN));
1786 // Fields Endnote
1787 m_pFieldEdnPLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_EDN));
1788 // Fields Comments
1789 m_pFieldAndPLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_AND));
1790 // Fields in Textboxes in Main Text
1791 m_pFieldTxbxPLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_TXBX));
1792 // Fields in Textboxes in Header / Footer
1793 m_pFieldTxbxHdFtPLCF.reset(new WW8PLCFx_FLD(pTableSt,*pWwFib,MAN_TXBX_HDFT));
1794
1795 // Note: 6 stands for "6 OR 7", 7 stands for "ONLY 7"
1796 switch( m_pWw8Fib->m_nVersion )
1797 {
1798 case 6:
1799 case 7:
1800 if( pWwFib->m_fcPlcfdoaMom && pWwFib->m_lcbPlcfdoaMom )
1801 {
1802 m_pMainFdoa.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcfdoaMom,
1803 pWwFib->m_lcbPlcfdoaMom, 6 ));
1804 }
1805 if( pWwFib->m_fcPlcfdoaHdr && pWwFib->m_lcbPlcfdoaHdr )
1806 {
1807 m_pHdFtFdoa.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcfdoaHdr,
1808 pWwFib->m_lcbPlcfdoaHdr, 6 ));
1809 }
1810 break;
1811 case 8:
1812 if( pWwFib->m_fcPlcfspaMom && pWwFib->m_lcbPlcfspaMom )
1813 {
1814 m_pMainFdoa.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcfspaMom,
1815 pWwFib->m_lcbPlcfspaMom, 26 ));
1816 }
1817 if( pWwFib->m_fcPlcfspaHdr && pWwFib->m_lcbPlcfspaHdr )
1818 {
1819 m_pHdFtFdoa.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcfspaHdr,
1820 pWwFib->m_lcbPlcfspaHdr, 26 ));
1821 }
1822 // PLCF for TextBox break-descriptors in the main text
1823 if( pWwFib->m_fcPlcftxbxBkd && pWwFib->m_lcbPlcftxbxBkd )
1824 {
1825 m_pMainTxbxBkd.reset(new WW8PLCFspecial( pTableSt,
1826 pWwFib->m_fcPlcftxbxBkd, pWwFib->m_lcbPlcftxbxBkd, 0));
1827 }
1828 // PLCF for TextBox break-descriptors in Header/Footer range
1829 if( pWwFib->m_fcPlcfHdrtxbxBkd && pWwFib->m_lcbPlcfHdrtxbxBkd )
1830 {
1831 m_pHdFtTxbxBkd.reset(new WW8PLCFspecial( pTableSt,
1832 pWwFib->m_fcPlcfHdrtxbxBkd, pWwFib->m_lcbPlcfHdrtxbxBkd, 0));
1833 }
1834 // Sub table cp positions
1835 if (pWwFib->m_fcPlcfTch && pWwFib->m_lcbPlcfTch)
1836 {
1837 m_pMagicTables.reset(new WW8PLCFspecial( pTableSt,
1838 pWwFib->m_fcPlcfTch, pWwFib->m_lcbPlcfTch, 4));
1839 }
1840 // Sub document cp positions
1841 if (pWwFib->m_fcPlcfwkb && pWwFib->m_lcbPlcfwkb)
1842 {
1843 m_pSubdocs.reset(new WW8PLCFspecial( pTableSt,
1844 pWwFib->m_fcPlcfwkb, pWwFib->m_lcbPlcfwkb, 12));
1845 }
1846 // Extended ATRD
1847 if (pWwFib->m_fcAtrdExtra && pWwFib->m_lcbAtrdExtra)
1848 {
1849 sal_uInt64 const nOldPos = pTableSt->Tell();
1850 if (checkSeek(*pTableSt, pWwFib->m_fcAtrdExtra) && (pTableSt->remainingSize() >= pWwFib->m_lcbAtrdExtra))
1851 {
1852 m_pExtendedAtrds.reset( new sal_uInt8[pWwFib->m_lcbAtrdExtra] );
1853 pWwFib->m_lcbAtrdExtra = pTableSt->ReadBytes(m_pExtendedAtrds.get(), pWwFib->m_lcbAtrdExtra);
1854 }
1855 else
1856 pWwFib->m_lcbAtrdExtra = 0;
1857 pTableSt->Seek(nOldPos);
1858 }
1859
1860 break;
1861 default:
1862 OSL_ENSURE( false, "nVersion not implemented!" );
1863 break;
1864 }
1865
1866 // PLCF for TextBox stories in main text
1867 sal_uInt32 nLenTxBxS = (8 > m_pWw8Fib->m_nVersion) ? 0 : 22;
1868 if( pWwFib->m_fcPlcftxbxText && pWwFib->m_lcbPlcftxbxText )
1869 {
1870 m_pMainTxbx.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcftxbxText,
1871 pWwFib->m_lcbPlcftxbxText, nLenTxBxS ));
1872 }
1873
1874 // PLCF for TextBox stories in Header/Footer range
1875 if( pWwFib->m_fcPlcfHdrtxbxText && pWwFib->m_lcbPlcfHdrtxbxText )
1876 {
1877 m_pHdFtTxbx.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcfHdrtxbxText,
1878 pWwFib->m_lcbPlcfHdrtxbxText, nLenTxBxS ));
1879 }
1880
1881 m_pBook.reset(new WW8PLCFx_Book(pTableSt, *pWwFib));
1882 m_pAtnBook.reset(new WW8PLCFx_AtnBook(pTableSt, *pWwFib));
1883 m_pFactoidBook.reset(new WW8PLCFx_FactoidBook(pTableSt, *pWwFib));
1884}
1885
1887{
1888 m_aPieceGrpprls.clear();
1889 m_pPLCFx_PCDAttrs.reset();
1890 m_pPLCFx_PCD.reset();
1891 m_pPieceIter.reset();
1892 m_pPiecePLCF.reset();
1893 m_pFactoidBook.reset();
1894 m_pAtnBook.reset();
1895 m_pBook.reset();
1896 m_pFieldEdnPLCF.reset();
1897 m_pFieldFootnotePLCF.reset();
1898 m_pFieldAndPLCF.reset();
1899 m_pFieldHdFtPLCF.reset();
1900 m_pFieldPLCF.reset();
1901 m_pFieldTxbxPLCF.reset();
1902 m_pFieldTxbxHdFtPLCF.reset();
1903 m_pEdnPLCF.reset();
1904 m_pFootnotePLCF.reset();
1905 m_pAndPLCF.reset();
1906 m_pSepPLCF.reset();
1907 m_pPapPLCF.reset();
1908 m_pChpPLCF.reset();
1909 m_pMainFdoa.reset();
1910 m_pHdFtFdoa.reset();
1911 m_pMainTxbx.reset();
1912 m_pMainTxbxBkd.reset();
1913 m_pHdFtTxbx.reset();
1914 m_pHdFtTxbxBkd.reset();
1915 m_pMagicTables.reset();
1916 m_pSubdocs.reset();
1917}
1918
1919// Fields
1920
1921static bool WW8SkipField(WW8PLCFspecial& rPLCF)
1922{
1923 void* pData;
1924 WW8_CP nP;
1925
1926 if (!rPLCF.Get(nP, pData)) // End of PLCFspecial?
1927 return false;
1928
1929 rPLCF.advance();
1930
1931 if((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) != 0x13 ) // No beginning?
1932 return true; // Do not terminate on error
1933
1934 if( !rPLCF.Get( nP, pData ) )
1935 return false;
1936
1937 while((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x13 )
1938 {
1939 // still new (nested) beginnings ?
1940 WW8SkipField( rPLCF ); // nested Field in description
1941 if( !rPLCF.Get( nP, pData ) )
1942 return false;
1943 }
1944
1945 if((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x14 )
1946 {
1947
1948 // Field Separator ?
1949 rPLCF.advance();
1950
1951 if( !rPLCF.Get( nP, pData ) )
1952 return false;
1953
1954 while ((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x13)
1955 {
1956 // still new (nested) beginnings?
1957 WW8SkipField( rPLCF ); // nested Field in Results
1958 if( !rPLCF.Get( nP, pData ) )
1959 return false;
1960 }
1961 }
1962 rPLCF.advance();
1963
1964 return true;
1965}
1966
1968{
1969 void* pData;
1970 sal_uInt32 nOldIdx = rPLCF.GetIdx();
1971
1972 rF.nLen = rF.nId = rF.nOpt = 0;
1973 rF.bCodeNest = rF.bResNest = false;
1974
1975 if (!rPLCF.Get(rF.nSCode, pData) || rF.nSCode < 0) // end of PLCFspecial?
1976 goto Err;
1977
1978 rPLCF.advance();
1979
1980 if (!pData || (static_cast<sal_uInt8*>(pData)[0] & 0x1f) != 0x13) // No beginning?
1981 goto Err;
1982
1983 rF.nId = static_cast<sal_uInt8*>(pData)[1];
1984
1985 if( !rPLCF.Get( rF.nLCode, pData ) )
1986 goto Err;
1987
1988 if (rF.nLCode < rF.nSCode)
1989 goto Err;
1990
1991 rF.nSRes = rF.nLCode; // Default
1992 rF.nSCode++; // without markers
1993 rF.nLCode -= rF.nSCode; // Pos -> length
1994
1995 while((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x13 )
1996 {
1997 // still new (nested) beginnings ?
1998 WW8SkipField( rPLCF ); // nested Field in description
1999 rF.bCodeNest = true;
2000 if (!rPLCF.Get(rF.nSRes, pData) || rF.nSRes < 0)
2001 goto Err;
2002 }
2003
2004 if ((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x14 ) // Field Separator?
2005 {
2006 rPLCF.advance();
2007
2008 if (!rPLCF.Get(rF.nLRes, pData) || rF.nLRes < 0)
2009 goto Err;
2010
2011 while((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x13 )
2012 {
2013 // still new (nested) beginnings ?
2014 WW8SkipField( rPLCF ); // nested Field in results
2015 rF.bResNest = true;
2016 if (!rPLCF.Get(rF.nLRes, pData) || rF.nLRes < 0)
2017 goto Err;
2018 }
2019 WW8_CP nTmp;
2020 if (o3tl::checked_sub<WW8_CP>(rF.nLRes, rF.nSCode, nTmp))
2021 {
2022 rF.nLen = 0;
2023 goto Err;
2024 }
2025 if (o3tl::checked_add<WW8_CP>(nTmp, 2, rF.nLen)) // nLRes is still the final position
2026 {
2027 rF.nLen = 0;
2028 goto Err;
2029 }
2030 rF.nLRes -= rF.nSRes; // now: nLRes = length
2031 if (o3tl::checked_add<WW8_CP>(rF.nSRes, 1, rF.nSRes)) // Endpos including Markers
2032 {
2033 rF.nLen = 0;
2034 goto Err;
2035 }
2036 rF.nLRes--;
2037 }else{
2038 rF.nLRes = 0; // no result found
2039 WW8_CP nTmp;
2040 if (o3tl::checked_sub<WW8_CP>(rF.nSRes, rF.nSCode, nTmp))
2041 {
2042 rF.nLen = 0;
2043 goto Err;
2044 }
2045 if (o3tl::checked_add<WW8_CP>(nTmp, 2, rF.nLen)) // total length
2046 {
2047 rF.nLen = 0;
2048 goto Err;
2049 }
2050 }
2051
2052 if (rF.nLen < 0)
2053 {
2054 rF.nLen = 0;
2055 goto Err;
2056 }
2057
2058 rPLCF.advance();
2059 if((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x15 )
2060 {
2061 // Field end ?
2062 // INDEX-Field has set Bit7?
2063 rF.nOpt = static_cast<sal_uInt8*>(pData)[1]; // yes -> copy flags
2064 }else{
2065 rF.nId = 0; // no -> Field invalid
2066 }
2067
2068 rPLCF.SetIdx( nOldIdx );
2069 return true;
2070Err:
2071 rPLCF.SetIdx( nOldIdx );
2072 return false;
2073}
2074
2075OUString read_uInt8_BeltAndBracesString(SvStream& rStrm, rtl_TextEncoding eEnc)
2076{
2077 const OUString aRet = read_uInt8_lenPrefixed_uInt8s_ToOUString(rStrm, eEnc);
2078 rStrm.SeekRel(sizeof(sal_uInt8)); // skip null-byte at end
2079 return aRet;
2080}
2081
2083{
2084 const OUString aRet = read_uInt16_PascalString(rStrm);
2085 rStrm.SeekRel(sizeof(sal_Unicode)); // skip null-byte at end
2086 return aRet;
2087}
2088
2089sal_Int32 WW8ScannerBase::WW8ReadString( SvStream& rStrm, OUString& rStr,
2090 WW8_CP nCurrentStartCp, tools::Long nTotalLen, rtl_TextEncoding eEnc ) const
2091{
2092 // Read in plain text, which can extend over several pieces
2093 rStr.clear();
2094
2095 if (nCurrentStartCp < 0 || nTotalLen < 0)
2096 return 0;
2097
2098 WW8_CP nBehindTextCp = nCurrentStartCp + nTotalLen;
2099 WW8_CP nNextPieceCp = nBehindTextCp; // Initialization, important for Ver6
2100 tools::Long nTotalRead = 0;
2101 do
2102 {
2103 bool bIsUnicode(false), bPosOk(false);
2104 WW8_FC fcAct = WW8Cp2Fc(nCurrentStartCp,&bIsUnicode,&nNextPieceCp,&bPosOk);
2105
2106 // Probably aimed beyond file end, doesn't matter!
2107 if( !bPosOk )
2108 break;
2109
2110 bool bValid = checkSeek(rStrm, fcAct);
2111 if (!bValid)
2112 break;
2113
2114 WW8_CP nEnd = (nNextPieceCp < nBehindTextCp) ? nNextPieceCp
2115 : nBehindTextCp;
2116 WW8_CP nLen;
2117 const bool bFail = o3tl::checked_sub(nEnd, nCurrentStartCp, nLen);
2118 if (bFail)
2119 break;
2120
2121 if( 0 >= nLen )
2122 break;
2123
2124 rStr += bIsUnicode
2126 : read_uInt8s_ToOUString(rStrm, nLen, eEnc);
2127
2128 nTotalRead += nLen;
2129 nCurrentStartCp += nLen;
2130 if ( nTotalRead != rStr.getLength() )
2131 break;
2132 }
2133 while( nTotalRead < nTotalLen );
2134
2135 return rStr.getLength();
2136}
2137
2139 sal_uInt32 nPLCF, sal_uInt32 nStruct)
2140 : m_nIdx(0), m_nStru(nStruct)
2141{
2142 const sal_uInt32 nValidMin=4;
2143
2144 sal_uInt64 const nOldPos = pSt->Tell();
2145
2146 bool bValid = checkSeek(*pSt, nFilePos);
2147 std::size_t nRemainingSize = pSt->remainingSize();
2148 if( nRemainingSize < nValidMin || nPLCF < nValidMin )
2149 bValid = false;
2150 nPLCF = bValid ? std::min(nRemainingSize, static_cast<std::size_t>(nPLCF)) : nValidMin;
2151
2152 // Pointer to Pos- and Struct-array
2153 m_pPLCF_PosArray.reset( new sal_Int32[ ( nPLCF + 3 ) / 4 ] );
2154 m_pPLCF_PosArray[0] = 0;
2155
2156 nPLCF = bValid ? pSt->ReadBytes(m_pPLCF_PosArray.get(), nPLCF) : nValidMin;
2157
2158 nPLCF = std::max(nPLCF, nValidMin);
2159
2160 m_nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
2161#ifdef OSL_BIGENDIAN
2162 for( m_nIdx = 0; m_nIdx <= m_nIMax; m_nIdx++ )
2163 m_pPLCF_PosArray[m_nIdx] = OSL_SWAPDWORD( m_pPLCF_PosArray[m_nIdx] );
2164 m_nIdx = 0;
2165#endif // OSL_BIGENDIAN
2166 if( nStruct ) // Pointer to content array
2167 m_pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&m_pPLCF_PosArray[m_nIMax + 1]);
2168 else
2169 m_pPLCF_Contents = nullptr; // no content
2170
2171 pSt->Seek(nOldPos);
2172}
2173
2174// WW8PLCFspecial::SeekPos() sets WW8PLCFspecial to position nPos, while also the entry is used
2175// that begins before nPos and ends after nPos.
2176// Suitable for normal attributes. However, the beginning of the attribute is not corrected onto
2177// the position nPos.
2179{
2180 if( nP < m_pPLCF_PosArray[0] )
2181 {
2182 m_nIdx = 0;
2183 return false; // Not found: nP less than smallest entry
2184 }
2185
2186 // Search from beginning?
2187 if ((m_nIdx < 1) || (nP < m_pPLCF_PosArray[m_nIdx - 1]))
2188 m_nIdx = 1;
2189
2190 tools::Long nI = m_nIdx;
2191 tools::Long nEnd = m_nIMax;
2192
2193 for(int n = (1==m_nIdx ? 1 : 2); n; --n )
2194 {
2195 for( ; nI <=nEnd; ++nI)
2196 { // search with an index that is incremented by 1
2197 if( nP < m_pPLCF_PosArray[nI] )
2198 { // found position
2199 m_nIdx = nI - 1; // nI - 1 is the correct index
2200 return true; // done
2201 }
2202 }
2203 nI = 1;
2204 nEnd = m_nIdx-1;
2205 }
2206 m_nIdx = m_nIMax; // not found, greater than all entries
2207 return false;
2208}
2209
2210// WW8PLCFspecial::SeekPosExact() like SeekPos(), but it is ensured that no attribute is cut,
2211// i.e. the next given attribute begins at or after nPos.
2212// Is used for fields and bookmarks.
2214{
2215 if( nP < m_pPLCF_PosArray[0] )
2216 {
2217 m_nIdx = 0;
2218 return false; // Not found: nP less than smallest entry
2219 }
2220 // Search from beginning?
2221 if( nP <=m_pPLCF_PosArray[m_nIdx] )
2222 m_nIdx = 0;
2223
2224 tools::Long nI = m_nIdx ? m_nIdx-1 : 0;
2225 tools::Long nEnd = m_nIMax;
2226
2227 for(int n = (0==m_nIdx ? 1 : 2); n; --n )
2228 {
2229 for( ; nI < nEnd; ++nI)
2230 {
2231 if( nP <=m_pPLCF_PosArray[nI] )
2232 { // found position
2233 m_nIdx = nI; // nI is the correct index
2234 return true; // done
2235 }
2236 }
2237 nI = 0;
2238 nEnd = m_nIdx;
2239 }
2240 m_nIdx = m_nIMax; // Not found, greater than all entries
2241 return false;
2242}
2243
2244bool WW8PLCFspecial::Get(WW8_CP& rPos, void*& rpValue) const
2245{
2246 return GetData( m_nIdx, rPos, rpValue );
2247}
2248
2249bool WW8PLCFspecial::GetData(tools::Long nInIdx, WW8_CP& rPos, void*& rpValue) const
2250{
2251 if ( nInIdx >= m_nIMax )
2252 {
2253 rPos = WW8_CP_MAX;
2254 return false;
2255 }
2256 rPos = m_pPLCF_PosArray[nInIdx];
2257 rpValue = m_pPLCF_Contents ? static_cast<void*>(&m_pPLCF_Contents[nInIdx * m_nStru]) : nullptr;
2258 return true;
2259}
2260
2261// WW8PLCF e.g. for SEPX
2262// Ctor for *others* than Fkps
2263// With nStartPos < 0, the first element of PLCFs will be taken
2264WW8PLCF::WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
2265 WW8_CP nStartPos) : m_nIdx(0), m_nStru(nStruct)
2266{
2267 if (nPLCF < 0)
2268 {
2269 SAL_WARN("sw.ww8", "broken WW8PLCF, ignoring");
2270 nPLCF = 0;
2271 }
2272 else
2273 m_nIMax = (nPLCF - 4) / (4 + nStruct);
2274
2275 ReadPLCF(rSt, nFilePos, nPLCF);
2276
2277 if( nStartPos >= 0 )
2278 SeekPos( nStartPos );
2279}
2280
2281// Ctor *only* for Fkps
2282// The last 2 parameters are needed for PLCF.Chpx and PLCF.Papx.
2283// If ncpN != 0, then an incomplete PLCF will be completed. This is always required for WW6 with
2284// lack of resources and for WordPad (W95).
2285// With nStartPos < 0, the first element of the PLCFs is taken.
2286WW8PLCF::WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
2287 WW8_CP nStartPos, sal_Int32 nPN, sal_Int32 ncpN): m_nIdx(0),
2288 m_nStru(nStruct)
2289{
2290 if (nPLCF < 0)
2291 {
2292 SAL_WARN("sw.ww8", "broken WW8PLCF, ignoring");
2294 }
2295 else
2296 m_nIMax = (nPLCF - 4) / (4 + nStruct);
2297
2298 if( m_nIMax >= ncpN )
2299 ReadPLCF(rSt, nFilePos, nPLCF);
2300 else
2301 GeneratePLCF(rSt, nPN, ncpN);
2302
2303 if( nStartPos >= 0 )
2304 SeekPos( nStartPos );
2305}
2306
2307void WW8PLCF::ReadPLCF(SvStream& rSt, WW8_FC nFilePos, sal_uInt32 nPLCF)
2308{
2309 sal_uInt64 const nOldPos = rSt.Tell();
2310 bool bValid = nPLCF != 0 && checkSeek(rSt, nFilePos)
2311 && (rSt.remainingSize() >= nPLCF);
2312
2313 if (bValid)
2314 {
2315 // Pointer to Pos-array
2316 const size_t nEntries = (nPLCF + 3) / 4;
2317 m_pPLCF_PosArray.reset(new WW8_CP[nEntries]);
2318 bValid = checkRead(rSt, m_pPLCF_PosArray.get(), nPLCF);
2319 size_t nBytesAllocated = nEntries * sizeof(WW8_CP);
2320 if (bValid && nPLCF != nBytesAllocated)
2321 {
2322 sal_uInt8* pStartBlock = reinterpret_cast<sal_uInt8*>(m_pPLCF_PosArray.get());
2323 memset(pStartBlock + nPLCF, 0, nBytesAllocated - nPLCF);
2324 }
2325 }
2326
2327 if (bValid)
2328 {
2329#ifdef OSL_BIGENDIAN
2330 for( m_nIdx = 0; m_nIdx <= m_nIMax; m_nIdx++ )
2331 m_pPLCF_PosArray[m_nIdx] = OSL_SWAPDWORD( m_pPLCF_PosArray[m_nIdx] );
2332 m_nIdx = 0;
2333#endif // OSL_BIGENDIAN
2334 // Pointer to content array
2335 m_pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&m_pPLCF_PosArray[m_nIMax + 1]);
2336
2338 }
2339
2340 OSL_ENSURE(bValid, "Document has corrupt PLCF, ignoring it");
2341
2342 if (!bValid)
2344
2345 rSt.Seek(nOldPos);
2346}
2347
2349{
2350 m_nIMax = 0;
2351 m_pPLCF_PosArray.reset( new WW8_CP[2] );
2353 m_pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&m_pPLCF_PosArray[m_nIMax + 1]);
2354}
2355
2356namespace
2357{
2358 sal_Int32 TruncToSortedRange(const sal_Int32* pPLCF_PosArray, sal_Int32 nIMax)
2359 {
2360 //Docs state that: ... all Plcs ... are sorted in ascending order.
2361 //So ensure that here for broken documents.
2362 for (auto nI = 0; nI < nIMax; ++nI)
2363 {
2364 if (pPLCF_PosArray[nI] > pPLCF_PosArray[nI+1])
2365 {
2366 SAL_WARN("sw.ww8", "Document has unsorted PLCF, truncated to sorted portion");
2367 nIMax = nI;
2368 break;
2369 }
2370 }
2371 return nIMax;
2372 }
2373}
2374
2376{
2378}
2379
2381{
2383}
2384
2385void WW8PLCF::GeneratePLCF(SvStream& rSt, sal_Int32 nPN, sal_Int32 ncpN)
2386{
2387 OSL_ENSURE( m_nIMax < ncpN, "Pcl.Fkp: Why is PLCF too big?" );
2388
2389 bool failure = false;
2390 m_nIMax = ncpN;
2391
2392 if ((m_nIMax < 1) || (m_nIMax > (WW8_CP_MAX - 4) / (4 + m_nStru)) || nPN < 0)
2393 failure = true;
2394
2395 if (!failure)
2396 {
2397 // Check arguments to ShortToSVBT16 in loop below will all be valid:
2398 sal_Int32 nResult;
2399 failure = o3tl::checked_add(nPN, ncpN, nResult) || nResult > SAL_MAX_UINT16;
2400 }
2401
2402 if (!failure)
2403 {
2404 size_t nSiz = (4 + m_nStru) * m_nIMax + 4;
2405 size_t nElems = ( nSiz + 3 ) / 4;
2406 m_pPLCF_PosArray.reset( new WW8_CP[ nElems ] ); // Pointer to Pos-array
2407
2408 for (sal_Int32 i = 0; i < ncpN && !failure; ++i)
2409 {
2410 failure = true;
2411 // construct FC entries
2412 // first FC entry of each Fkp
2413 if (!checkSeek(rSt, (nPN + i) << 9))
2414 break;
2415
2416 WW8_CP nFc(0);
2417 rSt.ReadInt32( nFc );
2418 m_pPLCF_PosArray[i] = nFc;
2419
2420 failure = bool(rSt.GetError());
2421 }
2422 }
2423
2424 if (!failure)
2425 {
2426 do
2427 {
2428 failure = true;
2429
2430 std::size_t nLastFkpPos = nPN + m_nIMax - 1;
2431 nLastFkpPos = nLastFkpPos << 9;
2432 // number of FC entries of last Fkp
2433 if (!checkSeek(rSt, nLastFkpPos + 511))
2434 break;
2435
2436 sal_uInt8 nb(0);
2437 rSt.ReadUChar( nb );
2438 // last FC entry of last Fkp
2439 if (!checkSeek(rSt, nLastFkpPos + nb * 4))
2440 break;
2441
2442 WW8_CP nFc(0);
2443 rSt.ReadInt32( nFc );
2444 m_pPLCF_PosArray[m_nIMax] = nFc; // end of the last Fkp
2445
2446 failure = bool(rSt.GetError());
2447 } while(false);
2448 }
2449
2450 if (!failure)
2451 {
2452 // Pointer to content array
2453 m_pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&m_pPLCF_PosArray[m_nIMax + 1]);
2455
2456 for (sal_Int32 i = 0; i < ncpN; ++i) // construct PNs
2457 {
2458 ShortToSVBT16(o3tl::narrowing<sal_uInt16>(nPN + i), p);
2459 p += m_nStru;
2460 }
2461 }
2462
2463 SAL_WARN_IF(failure, "sw.ww8", "Document has corrupt PLCF, ignoring it");
2464
2465 if (failure)
2467}
2468
2470{
2471 WW8_CP nP = nPos;
2472
2473 if( nP < m_pPLCF_PosArray[0] )
2474 {
2475 m_nIdx = 0;
2476 // not found: nPos less than smallest entry
2477 return false;
2478 }
2479
2480 // Search from beginning?
2481 if ((m_nIdx < 1) || (nP < m_pPLCF_PosArray[m_nIdx - 1]))
2482 m_nIdx = 1;
2483
2484 sal_Int32 nI = m_nIdx;
2485 sal_Int32 nEnd = m_nIMax;
2486
2487 for(int n = (1==m_nIdx ? 1 : 2); n; --n )
2488 {
2489 for( ; nI <=nEnd; ++nI) // search with an index that is incremented by 1
2490 {
2491 if( nP < m_pPLCF_PosArray[nI] ) // found position
2492 {
2493 m_nIdx = nI - 1; // nI - 1 is the correct index
2494 return true; // done
2495 }
2496 }
2497 nI = 1;
2498 nEnd = m_nIdx-1;
2499 }
2500
2501 m_nIdx = m_nIMax; // not found, greater than all entries
2502 return false;
2503}
2504
2505bool WW8PLCF::Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const
2506{
2507 if ( m_nIdx >= m_nIMax )
2508 {
2509 rStart = rEnd = WW8_CP_MAX;
2510 return false;
2511 }
2512 rStart = m_pPLCF_PosArray[ m_nIdx ];
2513 rEnd = m_pPLCF_PosArray[ m_nIdx + 1 ];
2514 rpValue = static_cast<void*>(&m_pPLCF_Contents[m_nIdx * m_nStru]);
2515 return true;
2516}
2517
2519{
2520 if ( m_nIdx >= m_nIMax )
2521 return WW8_CP_MAX;
2522
2523 return m_pPLCF_PosArray[m_nIdx];
2524}
2525
2526WW8PLCFpcd::WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos,
2527 sal_uInt32 nPLCF, sal_uInt32 nStruct)
2528 : m_nStru( nStruct )
2529{
2530 const sal_uInt32 nValidMin=4;
2531
2532 sal_uInt64 const nOldPos = pSt->Tell();
2533
2534 bool bValid = checkSeek(*pSt, nFilePos);
2535 std::size_t nRemainingSize = pSt->remainingSize();
2536 if( nRemainingSize < nValidMin || nPLCF < nValidMin )
2537 bValid = false;
2538 nPLCF = bValid ? std::min(nRemainingSize, static_cast<std::size_t>(nPLCF)) : nValidMin;
2539
2540 m_pPLCF_PosArray.reset( new WW8_CP[ ( nPLCF + 3 ) / 4 ] ); // Pointer to Pos-array
2541 m_pPLCF_PosArray[0] = 0;
2542
2543 nPLCF = bValid ? pSt->ReadBytes(m_pPLCF_PosArray.get(), nPLCF) : nValidMin;
2544 nPLCF = std::max(nPLCF, nValidMin);
2545
2546 m_nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
2547#ifdef OSL_BIGENDIAN
2548 for( tools::Long nI = 0; nI <= m_nIMax; nI++ )
2549 m_pPLCF_PosArray[nI] = OSL_SWAPDWORD( m_pPLCF_PosArray[nI] );
2550#endif // OSL_BIGENDIAN
2551
2552 // Pointer to content array
2553 m_pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&m_pPLCF_PosArray[m_nIMax + 1]);
2555
2556 pSt->Seek( nOldPos );
2557}
2558
2559// If nStartPos < 0, the first element of PLCFs will be taken
2561 :m_rPLCF( rPLCFpcd ), m_nIdx( 0 )
2562{
2563 if( nStartPos >= 0 )
2564 SeekPos( nStartPos );
2565}
2566
2568{
2569 tools::Long nP = nPos;
2570
2571 if( nP < m_rPLCF.m_pPLCF_PosArray[0] )
2572 {
2573 m_nIdx = 0;
2574 return false; // not found: nPos less than smallest entry
2575 }
2576 // Search from beginning?
2577 if ((m_nIdx < 1) || (nP < m_rPLCF.m_pPLCF_PosArray[m_nIdx - 1]))
2578 m_nIdx = 1;
2579
2580 tools::Long nI = m_nIdx;
2582
2583 for(int n = (1==m_nIdx ? 1 : 2); n; --n )
2584 {
2585 for( ; nI <=nEnd; ++nI)
2586 { // search with an index that is incremented by 1
2587 if( nP < m_rPLCF.m_pPLCF_PosArray[nI] )
2588 { // found position
2589 m_nIdx = nI - 1; // nI - 1 is the correct index
2590 return true; // done
2591 }
2592 }
2593 nI = 1;
2594 nEnd = m_nIdx-1;
2595 }
2596 m_nIdx = m_rPLCF.m_nIMax; // not found, greater than all entries
2597 return false;
2598}
2599
2600bool WW8PLCFpcd_Iter::Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const
2601{
2602 if( m_nIdx >= m_rPLCF.m_nIMax )
2603 {
2604 rStart = rEnd = WW8_CP_MAX;
2605 return false;
2606 }
2608 rEnd = m_rPLCF.m_pPLCF_PosArray[m_nIdx + 1];
2609 rpValue = static_cast<void*>(&m_rPLCF.m_pPLCF_Contents[m_nIdx * m_rPLCF.m_nStru]);
2610 return true;
2611}
2612
2613sal_Int32 WW8PLCFpcd_Iter::Where() const
2614{
2615 if ( m_nIdx >= m_rPLCF.m_nIMax )
2616 return SAL_MAX_INT32;
2617
2619}
2620
2621bool WW8PLCFx_Fc_FKP::WW8Fkp::Entry::operator<
2622 (const WW8PLCFx_Fc_FKP::WW8Fkp::Entry& rSecond) const
2623{
2624 return (mnFC < rSecond.mnFC);
2625}
2626
2627static bool IsReplaceAllSprm(sal_uInt16 nSpId)
2628{
2629 return (NS_sprm::LN_PHugePapx == nSpId || 0x6646 == nSpId);
2630}
2631
2632static bool IsExpandableSprm(sal_uInt16 nSpId)
2633{
2634 return 0x646B == nSpId;
2635}
2636
2638 std::size_t nDataOffset, sal_uInt16 nLen)
2639{
2640 bool bValidPos = (nDataOffset < sizeof(maRawData));
2641
2642 OSL_ENSURE(bValidPos, "sprm sequence offset is out of range, ignoring");
2643
2644 if (!bValidPos)
2645 {
2646 rEntry.mnLen = 0;
2647 return;
2648 }
2649
2650 const sal_uInt16 nAvailableData = sizeof(maRawData)-nDataOffset;
2651 OSL_ENSURE(nLen <= nAvailableData, "sprm sequence len is out of range, clipping");
2652 rEntry.mnLen = std::min(nLen, nAvailableData);
2653 rEntry.mpData = maRawData + nDataOffset;
2654}
2655
2657 SvStream* pDataSt, tools::Long _nFilePos, tools::Long nItemSiz, ePLCFT ePl,
2658 WW8_FC nStartFc)
2659 : m_nItemSize(nItemSiz), m_nFilePos(_nFilePos), mnIdx(0), m_ePLCF(ePl)
2660 , mnMustRemainCached(0), maSprmParser(rFib)
2661{
2662 memset(maRawData, 0, 512);
2663
2664 const ww::WordVersion eVersion = rFib.GetFIBVersion();
2665
2666 sal_uInt64 const nOldPos = pSt->Tell();
2667
2668 bool bCouldSeek = checkSeek(*pSt, m_nFilePos);
2669 bool bCouldRead = bCouldSeek && checkRead(*pSt, maRawData, 512);
2670
2671 mnIMax = bCouldRead ? maRawData[511] : 0;
2672
2673 sal_uInt8 *pStart = maRawData;
2674 // Offset-Location in maRawData
2675 const size_t nRawDataStart = (mnIMax + 1) * 4;
2676
2677 for (mnIdx = 0; mnIdx < mnIMax; ++mnIdx)
2678 {
2679 const size_t nRawDataOffset = nRawDataStart + mnIdx * m_nItemSize;
2680
2681 //clip to available data, corrupt fkp
2682 if (nRawDataOffset >= 511)
2683 {
2684 mnIMax = mnIdx;
2685 break;
2686 }
2687
2688 unsigned int nOfs = maRawData[nRawDataOffset] * 2;
2689 // nOfs in [0..0xff*2=510]
2690
2691 Entry aEntry(Get_Long(pStart));
2692
2693 if (nOfs)
2694 {
2695 switch (m_ePLCF)
2696 {
2697 case CHP:
2698 {
2699 aEntry.mnLen = maRawData[nOfs];
2700
2701 //len byte
2702 std::size_t nDataOffset = nOfs + 1;
2703
2704 FillEntry(aEntry, nDataOffset, aEntry.mnLen);
2705
2706 if (aEntry.mnLen && eVersion <= ww::eWW2)
2707 {
2708 Word2CHPX aChpx = ReadWord2Chpx(*pSt, m_nFilePos + nOfs + 1, static_cast< sal_uInt8 >(aEntry.mnLen));
2709 std::vector<sal_uInt8> aSprms = ChpxToSprms(aChpx);
2710 aEntry.mnLen = static_cast< sal_uInt16 >(aSprms.size());
2711 if (aEntry.mnLen)
2712 {
2713 aEntry.mpData = new sal_uInt8[aEntry.mnLen];
2714 memcpy(aEntry.mpData, aSprms.data(), aEntry.mnLen);
2715 aEntry.mbMustDelete = true;
2716 }
2717 }
2718 break;
2719 }
2720 case PAP:
2721 {
2722 sal_uInt8 nDelta = 0;
2723
2724 aEntry.mnLen = maRawData[nOfs];
2725 if (IsEightPlus(eVersion) && !aEntry.mnLen)
2726 {
2727 aEntry.mnLen = maRawData[nOfs+1];
2728 nDelta++;
2729 }
2730 aEntry.mnLen *= 2;
2731
2732 //stylecode, std/istd
2733 if (eVersion <= ww::eWW2)
2734 {
2735 if (aEntry.mnLen >= 1)
2736 {
2737 aEntry.mnIStd = *(maRawData+nOfs+1+nDelta);
2738 aEntry.mnLen--; //style code
2739 if (aEntry.mnLen >= 6)
2740 {
2741 aEntry.mnLen-=6; //PHE
2742 //skip stc, len byte + 6 byte PHE
2743 unsigned int nOffset = nOfs + 8;
2744 if (nOffset >= 511) //Bad offset
2745 aEntry.mnLen=0;
2746 if (aEntry.mnLen) //start is ok
2747 {
2748 if (nOffset + aEntry.mnLen > 512) //Bad end, clip
2749 aEntry.mnLen = 512 - nOffset;
2750 aEntry.mpData = maRawData + nOffset;
2751 }
2752 }
2753 else
2754 aEntry.mnLen=0; //Too short
2755 }
2756 }
2757 else
2758 {
2759 if (aEntry.mnLen >= 2)
2760 {
2761 //len byte + optional extra len byte
2762 std::size_t nDataOffset = nOfs + 1 + nDelta;
2763 aEntry.mnIStd = nDataOffset <= sizeof(maRawData)-sizeof(aEntry.mnIStd) ?
2764 SVBT16ToUInt16(maRawData+nDataOffset) : 0;
2765 aEntry.mnLen-=2; //istd
2766 if (aEntry.mnLen)
2767 {
2768 //additional istd
2769 nDataOffset += sizeof(aEntry.mnIStd);
2770
2771 FillEntry(aEntry, nDataOffset, aEntry.mnLen);
2772 }
2773 }
2774 else
2775 aEntry.mnLen=0; //Too short, ignore
2776 }
2777
2778 const sal_uInt16 nSpId = aEntry.mnLen
2779 ? maSprmParser.GetSprmId(aEntry.mpData) : 0;
2780
2781 /*
2782 If we replace then we throw away the old data, if we
2783 are expanding, then we tack the old data onto the end
2784 of the new data
2785 */
2786 const bool bExpand = IsExpandableSprm(nSpId);
2787 const sal_uInt8* pStartData
2788 = aEntry.mpData == nullptr ? nullptr : aEntry.mpData + 2;
2789 const sal_uInt8* pLastValidDataPos = maRawData + 512 - sizeof(sal_uInt32);
2790 if (pStartData != nullptr && pStartData > pLastValidDataPos)
2791 pStartData = nullptr;
2792 if ((IsReplaceAllSprm(nSpId) || bExpand) && pStartData)
2793 {
2794 sal_uInt32 nCurr = pDataSt->Tell();
2795 sal_uInt32 nPos = SVBT32ToUInt32(pStartData);
2796 sal_uInt16 nLen(0);
2797
2798 bool bOk = checkSeek(*pDataSt, nPos);
2799 if (bOk)
2800 {
2801 pDataSt->ReadUInt16( nLen );
2802 bOk = nLen <= pDataSt->remainingSize();
2803 }
2804
2805 if (bOk)
2806 {
2807 const sal_uInt16 nOrigLen = bExpand ? aEntry.mnLen : 0;
2808 sal_uInt8 *pOrigData = bExpand ? aEntry.mpData : nullptr;
2809
2810 aEntry.mnLen = nLen;
2811 aEntry.mpData =
2812 new sal_uInt8[aEntry.mnLen + nOrigLen];
2813 aEntry.mbMustDelete = true;
2814 aEntry.mnLen =
2815 pDataSt->ReadBytes(aEntry.mpData, aEntry.mnLen);
2816
2817 pDataSt->Seek( nCurr );
2818
2819 if (pOrigData)
2820 {
2821 memcpy(aEntry.mpData + aEntry.mnLen,
2822 pOrigData, nOrigLen);
2823 aEntry.mnLen = aEntry.mnLen + nOrigLen;
2824 }
2825 }
2826 }
2827 }
2828 break;
2829 default:
2830 OSL_FAIL("sweet god, what have you done!");
2831 break;
2832 }
2833 }
2834
2835 maEntries.push_back(aEntry);
2836
2837#ifdef DEBUGSPRMREADER
2838 {
2839 sal_Int32 nLen;
2840 sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen );
2841 WW8SprmIter aIter(pSprms, nLen, maSprmParser);
2842 while (aIter.GetSprms())
2843 {
2844 fprintf(stderr, "id is %x\n", aIter.GetCurrentId());
2845 aIter.advance();
2846 }
2847 }
2848#endif
2849 }
2850
2851 //one more FC than grrpl entries
2852 maEntries.emplace_back(Get_Long(pStart));
2853
2854 //we expect them sorted, but it appears possible for them to arrive unsorted
2855 std::stable_sort(maEntries.begin(), maEntries.end());
2856
2857 mnIdx = 0;
2858
2859 if (nStartFc >= 0)
2860 SeekPos(nStartFc);
2861
2862 pSt->Seek(nOldPos);
2863}
2864
2866 : mnFC(rEntry.mnFC), mnLen(rEntry.mnLen), mnIStd(rEntry.mnIStd),
2867 mbMustDelete(rEntry.mbMustDelete)
2868{
2869 if (mbMustDelete)
2870 {
2871 mpData = new sal_uInt8[mnLen];
2872 memcpy(mpData, rEntry.mpData, mnLen);
2873 }
2874 else
2875 mpData = rEntry.mpData;
2876}
2877
2880{
2881 if (this == &rEntry)
2882 return *this;
2883
2884 if (mbMustDelete)
2885 delete[] mpData;
2886
2887 mnFC = rEntry.mnFC;
2888 mnLen = rEntry.mnLen;
2889 mnIStd = rEntry.mnIStd;
2890 mbMustDelete = rEntry.mbMustDelete;
2891
2892 if (rEntry.mbMustDelete)
2893 {
2894 mpData = new sal_uInt8[mnLen];
2895 memcpy(mpData, rEntry.mpData, mnLen);
2896 }
2897 else
2898 mpData = rEntry.mpData;
2899
2900 return *this;
2901}
2902
2904{
2905 if (mbMustDelete)
2906 delete[] mpData;
2907}
2908
2910{
2911 SetIdx(0);
2912 if (nFc >= 0)
2913 SeekPos(nFc);
2914}
2915
2917{
2918 if (nFc < maEntries[0].mnFC)
2919 {
2920 mnIdx = 0;
2921 return false; // not found: nPos less than smallest entry
2922 }
2923
2924 // Search from beginning?
2925 if ((mnIdx < 1) || (nFc < maEntries[mnIdx - 1].mnFC))
2926 mnIdx = 1;
2927
2928 sal_uInt8 nI = mnIdx;
2929 sal_uInt8 nEnd = mnIMax;
2930
2931 for(sal_uInt8 n = (1==mnIdx ? 1 : 2); n; --n )
2932 {
2933 for( ; nI <=nEnd; ++nI)
2934 { // search with an index that is incremented by 1
2935 if (nFc < maEntries[nI].mnFC)
2936 { // found position
2937 mnIdx = nI - 1; // nI - 1 is the correct index
2938 return true; // done
2939 }
2940 }
2941 nI = 1;
2942 nEnd = mnIdx-1;
2943 }
2944 mnIdx = mnIMax; // not found, greater than all entries
2945 return false;
2946}
2947
2948sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::Get(WW8_FC& rStart, WW8_FC& rEnd, sal_Int32& rLen)
2949 const
2950{
2951 rLen = 0;
2952
2953 if (mnIdx >= mnIMax)
2954 {
2955 rStart = WW8_FC_MAX;
2956 return nullptr;
2957 }
2958
2959 rStart = maEntries[mnIdx].mnFC;
2960 rEnd = maEntries[mnIdx + 1].mnFC;
2961
2962 sal_uInt8* pSprms = GetLenAndIStdAndSprms( rLen );
2963 return pSprms;
2964}
2965
2967{
2968 if (nI < mnIMax)
2969 {
2970 mnIdx = nI;
2971 }
2972}
2973
2975{
2976 rLen = maEntries[mnIdx].mnLen;
2977 return maEntries[mnIdx].mpData;
2978}
2979
2980SprmResult WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm( sal_uInt16 nId, bool bFindFirst )
2981{
2982 if (mnIdx >= mnIMax)
2983 return SprmResult();
2984
2985 sal_Int32 nLen;
2986 sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen );
2987
2988 WW8SprmIter aIter(pSprms, nLen, maSprmParser);
2989 return aIter.FindSprm(nId, bFindFirst);
2990}
2991
2993 std::vector<SprmResult> &rResult)
2994{
2995 if (mnIdx >= mnIMax)
2996 return;
2997
2998 sal_Int32 nLen;
2999 sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen );
3000
3001 WW8SprmIter aIter(pSprms, nLen, maSprmParser);
3002
3003 while(aIter.GetSprms())
3004 {
3005 if (aIter.GetCurrentId() == nId)
3006 {
3007 sal_Int32 nFixedLen = maSprmParser.DistanceToData(nId);
3008 sal_Int32 nL = maSprmParser.GetSprmSize(nId, aIter.GetSprms(), aIter.GetRemLen());
3009 rResult.emplace_back(aIter.GetCurrentParams(), nL - nFixedLen);
3010 }
3011 aIter.advance();
3012 };
3013}
3014
3016{
3017 return mrFib.GetFIBVersion();
3018}
3019
3021{
3022 OSL_ENSURE( false, "Called wrong GetSprms" );
3023 p->nStartPos = p->nEndPos = WW8_CP_MAX;
3024 p->pMemPos = nullptr;
3025 p->nSprmsLen = 0;
3026 p->bRealLineEnd = false;
3027}
3028
3029tools::Long WW8PLCFx::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
3030{
3031 OSL_ENSURE( false, "Called wrong GetNoSprms" );
3032 rStart = rEnd = WW8_CP_MAX;
3033 rLen = 0;
3034 return 0;
3035}
3036
3037// ...Idx2: Default: ignore
3038sal_uInt32 WW8PLCFx::GetIdx2() const
3039{
3040 return 0;
3041}
3042
3043void WW8PLCFx::SetIdx2(sal_uInt32)
3044{
3045}
3046
3047namespace {
3048
3049class SamePos
3050{
3051private:
3052 tools::Long mnPo;
3053public:
3054 explicit SamePos(tools::Long nPo) : mnPo(nPo) {}
3055 bool operator()(const std::unique_ptr<WW8PLCFx_Fc_FKP::WW8Fkp>& pFkp)
3056 {return mnPo == pFkp->GetFilePos();}
3057};
3058
3059}
3060
3062{
3063 WW8_CP nPLCFStart, nPLCFEnd;
3064 void* pPage;
3065
3066 static const int WW8FkpSizeTabVer2[ PLCF_END ] =
3067 {
3068 1, 1, 0 /*, 0, 0, 0*/
3069 };
3070 static const int WW8FkpSizeTabVer6[ PLCF_END ] =
3071 {
3072 1, 7, 0 /*, 0, 0, 0*/
3073 };
3074 static const int WW8FkpSizeTabVer8[ PLCF_END ] =
3075 {
3076 1, 13, 0 /*, 0, 0, 0*/
3077 };
3078 const int* pFkpSizeTab;
3079
3080 switch (GetFIBVersion())
3081 {
3082 case ww::eWW1:
3083 case ww::eWW2:
3084 pFkpSizeTab = WW8FkpSizeTabVer2;
3085 break;
3086 case ww::eWW6:
3087 case ww::eWW7:
3088 pFkpSizeTab = WW8FkpSizeTabVer6;
3089 break;
3090 case ww::eWW8:
3091 pFkpSizeTab = WW8FkpSizeTabVer8;
3092 break;
3093 default:
3094 // program error!
3095 OSL_ENSURE( false, "nVersion not implemented!" );
3096 return false;
3097 }
3098
3099 if (!m_pPLCF->Get( nPLCFStart, nPLCFEnd, pPage ))
3100 {
3101 m_pFkp = nullptr;
3102 return false; // PLCF completely processed
3103 }
3104 m_pPLCF->advance();
3105 tools::Long nPo = SVBT16ToUInt16( static_cast<sal_uInt8 *>(pPage) );
3106 nPo <<= 9; // shift as LONG
3107
3108 tools::Long nCurrentFkpFilePos = m_pFkp ? m_pFkp->GetFilePos() : -1;
3109 if (nCurrentFkpFilePos == nPo)
3111 else
3112 {
3113 auto aIter =
3114 std::find_if(maFkpCache.begin(), maFkpCache.end(), SamePos(nPo));
3115 if (aIter != maFkpCache.end())
3116 {
3117 m_pFkp = aIter->get();
3119 }
3120 else
3121 {
3122 m_pFkp = new WW8Fkp(GetFIB(), m_pFKPStrm, m_pDataStrm, nPo,
3123 pFkpSizeTab[ m_ePLCF ], m_ePLCF, GetStartFc());
3124 maFkpCache.push_back(std::unique_ptr<WW8Fkp>(m_pFkp));
3125
3126 if (maFkpCache.size() > eMaxCache)
3127 {
3128 WW8Fkp* pCachedFkp = maFkpCache.front().get();
3129 if (!pCachedFkp->IsMustRemainCache())
3130 {
3131 maFkpCache.pop_front();
3132 }
3133 }
3134 }
3135 }
3136
3137 SetStartFc( -1 ); // only the first time
3138 return true;
3139}
3140
3142 SvStream* pDataSt, const WW8Fib& rFib, ePLCFT ePl, WW8_FC nStartFcL)
3143 : WW8PLCFx(rFib, true), m_pFKPStrm(pSt), m_pDataStrm(pDataSt)
3144 , m_pFkp(nullptr), m_ePLCF(ePl)
3145{
3146 SetStartFc(nStartFcL);
3147 tools::Long nLenStruct = (8 > rFib.m_nVersion) ? 2 : 4;
3148 if (ePl == CHP)
3149 {
3150 m_pPLCF.reset(new WW8PLCF(*pTableSt, rFib.m_fcPlcfbteChpx, rFib.m_lcbPlcfbteChpx,
3151 nLenStruct, GetStartFc(), rFib.m_pnChpFirst, rFib.m_cpnBteChp));
3152 }
3153 else
3154 {
3155 m_pPLCF.reset(new WW8PLCF(*pTableSt, rFib.m_fcPlcfbtePapx, rFib.m_lcbPlcfbtePapx,
3156 nLenStruct, GetStartFc(), rFib.m_pnPapFirst, rFib.m_cpnBtePap));
3157 }
3158}
3159
3161{
3162 maFkpCache.clear();
3163 m_pPLCF.reset();
3164 m_pPCDAttrs.reset();
3165}
3166
3167sal_uInt32 WW8PLCFx_Fc_FKP::GetIdx() const
3168{
3169 sal_uInt32 u = m_pPLCF->GetIdx() << 8;
3170 if (m_pFkp)
3171 u |= m_pFkp->GetIdx();
3172 return u;
3173}
3174
3175void WW8PLCFx_Fc_FKP::SetIdx(sal_uInt32 nIdx)
3176{
3177 if( !( nIdx & 0xffffff00L ) )
3178 {
3179 m_pPLCF->SetIdx( nIdx >> 8 );
3180 m_pFkp = nullptr;
3181 }
3182 else
3183 { // there was a Fkp
3184 // Set PLCF one position back to retrieve the address of the Fkp
3185 m_pPLCF->SetIdx( ( nIdx >> 8 ) - 1 );
3186 if (NewFkp()) // read Fkp again
3187 {
3188 sal_uInt8 nFkpIdx = static_cast<sal_uInt8>(nIdx & 0xff);
3189 m_pFkp->SetIdx(nFkpIdx); // set Fkp-Pos again
3190 }
3191 }
3192}
3193
3195{
3196 // StartPos for next Where()
3197 SetStartFc( nFcPos );
3198
3199 // find StartPos for next pPLCF->Get()
3200 bool bRet = m_pPLCF->SeekPos(nFcPos);
3201
3202 // make FKP invalid?
3203 WW8_CP nPLCFStart, nPLCFEnd;
3204 void* pPage;
3205 if( m_pFkp && m_pPLCF->Get( nPLCFStart, nPLCFEnd, pPage ) )
3206 {
3207 tools::Long nPo = SVBT16ToUInt16( static_cast<sal_uInt8 *>(pPage) );
3208 nPo <<= 9; // shift as LONG
3209 if (nPo != m_pFkp->GetFilePos())
3210 m_pFkp = nullptr;
3211 else
3212 m_pFkp->SeekPos( nFcPos );
3213 }
3214 return bRet;
3215}
3216
3218{
3219 if( !m_pFkp && !NewFkp() )
3220 return WW8_FC_MAX;
3221 WW8_FC nP = m_pFkp ? m_pFkp->Where() : WW8_FC_MAX;
3222 if( nP != WW8_FC_MAX )
3223 return nP;
3224
3225 m_pFkp = nullptr; // FKP finished -> get new
3226 return Where(); // easiest way: do it recursively
3227}
3228
3230{
3231 rLen = 0; // Default
3232 rStart = rEnd = WW8_FC_MAX;
3233
3234 if( !m_pFkp ) // Fkp not there ?
3235 {
3236 if( !NewFkp() )
3237 return nullptr;
3238 }
3239
3240 sal_uInt8* pPos = m_pFkp ? m_pFkp->Get( rStart, rEnd, rLen ) : nullptr;
3241 if( rStart == WW8_FC_MAX ) //Not found
3242 return nullptr;
3243 return pPos;
3244}
3245
3247{
3248 if( !m_pFkp && !NewFkp() )
3249 return;
3250
3251 if (!m_pFkp)
3252 return;
3253
3254 m_pFkp->advance();
3255 if( m_pFkp->Where() == WW8_FC_MAX )
3256 (void)NewFkp();
3257}
3258
3260{
3261 return m_pFkp ? m_pFkp->GetIstd() : 0xFFFF;
3262}
3263
3265{
3266 rDesc.pMemPos = nullptr;
3267 rDesc.nSprmsLen = 0;
3268 if( m_pPCDAttrs )
3269 {
3270 if( !m_pFkp )
3271 {
3272 OSL_FAIL("+Problem: GetPCDSprms: NewFkp necessary (not possible!)" );
3273 if( !NewFkp() )
3274 return;
3275 }
3276 m_pPCDAttrs->GetSprms(&rDesc);
3277 }
3278}
3279
3280SprmResult WW8PLCFx_Fc_FKP::HasSprm(sal_uInt16 nId, bool bFindFirst)
3281{
3282 // const would be nicer, but for that, NewFkp() would need to be replaced or eliminated
3283 if( !m_pFkp )
3284 {
3285 OSL_FAIL( "+Motz: HasSprm: NewFkp needed ( no const possible )" );
3286 // happens in BugDoc 31722
3287 if( !NewFkp() )
3288 return SprmResult();
3289 }
3290
3291 if (!m_pFkp)
3292 return SprmResult();
3293
3294 SprmResult aRes = m_pFkp->HasSprm(nId, bFindFirst);
3295
3296 if (!aRes.pSprm)
3297 {
3298 WW8PLCFxDesc aDesc;
3299 GetPCDSprms( aDesc );
3300
3301 if (aDesc.pMemPos)
3302 {
3303 WW8SprmIter aIter(aDesc.pMemPos, aDesc.nSprmsLen,
3305 aRes = aIter.FindSprm(nId, bFindFirst);
3306 }
3307 }
3308
3309 return aRes;
3310}
3311
3312void WW8PLCFx_Fc_FKP::HasSprm(sal_uInt16 nId, std::vector<SprmResult> &rResult)
3313{
3314 // const would be nicer, but for that, NewFkp() would need to be replaced or eliminated
3315 if (!m_pFkp)
3316 {
3317 OSL_FAIL( "+Motz: HasSprm: NewFkp needed ( no const possible )" );
3318 // happens in BugDoc 31722
3319 if( !NewFkp() )
3320 return;
3321 }
3322
3323 if (!m_pFkp)
3324 return;
3325
3326 m_pFkp->HasSprm(nId, rResult);
3327
3328 WW8PLCFxDesc aDesc;
3329 GetPCDSprms( aDesc );
3330
3331 if (!aDesc.pMemPos)
3332 return;
3333
3334 const wwSprmParser &rSprmParser = m_pFkp->GetSprmParser();
3335 WW8SprmIter aIter(aDesc.pMemPos, aDesc.nSprmsLen, rSprmParser);
3336 while(aIter.GetSprms())
3337 {
3338 if (aIter.GetCurrentId() == nId)
3339 {
3340 sal_Int32 nFixedLen = rSprmParser.DistanceToData(nId);
3341 sal_Int32 nL = rSprmParser.GetSprmSize(nId, aIter.GetSprms(), aIter.GetRemLen());
3342 rResult.emplace_back(aIter.GetCurrentParams(), nL - nFixedLen);
3343 }
3344 aIter.advance();
3345 };
3346}
3347
3349 SvStream* pDataSt, const WW8ScannerBase& rBase, ePLCFT ePl )
3350 : WW8PLCFx_Fc_FKP(pSt, pTableSt, pDataSt, *rBase.m_pWw8Fib, ePl,
3351 rBase.WW8Cp2Fc(0)), m_rSBase(rBase), m_nAttrStart(-1), m_nAttrEnd(-1),
3352 m_bLineEnd(false),
3353 m_bComplex( (7 < rBase.m_pWw8Fib->m_nVersion) || rBase.m_pWw8Fib->m_fComplex )
3354{
3356
3358 m_pPcd.reset( new WW8PLCFx_PCD(GetFIB(), rBase.m_pPiecePLCF.get(), 0, IsSevenMinus(GetFIBVersion())) );
3359
3360 /*
3361 Make a copy of the piece attributes for so that the calls to HasSprm on a
3362 Fc_FKP will be able to take into account the current piece attributes,
3363 despite the fact that such attributes can only be found through a cp based
3364 mechanism.
3365 */
3366 if (m_pPcd)
3367 {
3369 *m_rSBase.m_pWw8Fib, m_pPcd.get(), &m_rSBase) : nullptr);
3370 }
3371
3373}
3374
3376{
3377}
3378
3380{
3381 m_nAttrStart = -1;
3382 m_nAttrEnd = -1;
3383 m_bLineEnd = false;
3384}
3385
3387{
3388 return m_pPcd ? m_pPcd->GetIdx() : 0;
3389}
3390
3392{
3393 if( m_pPcd ) // Complex
3394 {
3395 if( !m_pPcd->SeekPos( nCpPos ) ) // set piece
3396 return false;
3397 if (m_pPCDAttrs && !m_pPCDAttrs->GetIter()->SeekPos(nCpPos))
3398 return false;
3399 return WW8PLCFx_Fc_FKP::SeekPos(m_pPcd->CurrentPieceStartCp2Fc(nCpPos));
3400 }
3401 // NO piece table !!!
3402 return WW8PLCFx_Fc_FKP::SeekPos( m_rSBase.WW8Cp2Fc(nCpPos) );
3403}
3404
3406{
3408 if( m_pPcd )
3409 return m_pPcd->CurrentPieceStartFc2Cp( nFc ); // identify piece
3410 return m_rSBase.WW8Fc2Cp( nFc ); // NO piece table !!!
3411}
3412
3414{
3415 WW8_CP nOrigCp = p->nStartPos;
3416
3417 if (!GetDirty()) //Normal case
3418 {
3419 p->pMemPos = WW8PLCFx_Fc_FKP::GetSprmsAndPos(p->nStartPos, p->nEndPos,
3420 p->nSprmsLen);
3421 }
3422 else
3423 {
3424 /*
3425 For the odd case where we have a location in a fastsaved file which
3426 does not have an entry in the FKP, perhaps its para end is in the next
3427 piece, or perhaps the cp just doesn't exist at all in this document.
3428 AdvSprm doesn't know so it sets the PLCF as dirty and we figure out
3429 in this method what the situation is
3430
3431 It doesn't exist then the piece iterator will not be able to find it.
3432 Otherwise our cool fastsave algorithm can be brought to bear on the
3433 problem.
3434 */
3435 if( !m_pPieceIter )
3436 return;
3437 const sal_uInt32 nOldPos = m_pPieceIter->GetIdx();
3438 bool bOk = m_pPieceIter->SeekPos(nOrigCp);
3439 m_pPieceIter->SetIdx(nOldPos);
3440 if (!bOk)
3441 return;
3442 }
3443
3444 if( m_pPcd ) // piece table available
3445 {
3446 // Init ( no ++ called, yet )
3447 if( (m_nAttrStart > m_nAttrEnd) || (m_nAttrStart == -1) )
3448 {
3449 p->bRealLineEnd = (m_ePLCF == PAP);
3450
3451 if ( ((m_ePLCF == PAP ) || (m_ePLCF == CHP)) && (nOrigCp != WW8_CP_MAX) )
3452 {
3453 bool bIsUnicode=false;
3454 /*
3455 To find the end of a paragraph for a character in a
3456 complex format file.
3457
3458 It is necessary to know the piece that contains the
3459 character and the FC assigned to the character.
3460 */
3461
3462 //We set the piece iterator to the piece that contains the
3463 //character, now we have the correct piece for this character
3464 sal_uInt32 nOldPos = m_pPieceIter->GetIdx();
3465 p->nStartPos = nOrigCp;
3466 m_pPieceIter->SeekPos( p->nStartPos);
3467
3468 //This is the FC assigned to the character, but we already
3469 //have the result of the next stage, so we can skip this step
3470 //WW8_FC nStartFc = rSBase.WW8Cp2Fc(p->nStartPos, &bIsUnicode);
3471
3472 /*
3473 Using the FC of the character, first search the FKP that
3474 describes the character to find the smallest FC in the rgfc
3475 that is larger than the character FC.
3476 */
3477 //But the search has already been done, the next largest FC is
3478 //p->nEndPos.
3479 WW8_FC nOldEndPos = p->nEndPos;
3480
3481 /*
3482 If the FC found in the FKP is less than or equal to the limit
3483 FC of the piece, the end of the paragraph that contains the
3484 character is at the FKP FC minus 1.
3485 */
3486 WW8_CP nCpStart, nCpEnd;
3487 void* pData=nullptr;
3488 bool bOk = m_pPieceIter->Get(nCpStart, nCpEnd, pData);
3489
3490 if (!bOk)
3491 {
3492 m_pPieceIter->SetIdx(nOldPos);
3493 return;
3494 }
3495
3496 WW8_FC nLimitFC = SVBT32ToUInt32( static_cast<WW8_PCD*>(pData)->fc );
3497 WW8_FC nBeginLimitFC = nLimitFC;
3499 {
3500 nBeginLimitFC =
3502 bIsUnicode);
3503 }
3504
3505 WW8_CP nCpLen;
3506 bool bFail = o3tl::checked_sub(nCpEnd, nCpStart, nCpLen);
3507 if (bFail)
3508 {
3509 SAL_WARN("sw.ww8", "broken offset, ignoring");
3510 p->nStartPos = p->nEndPos = WW8_FC_MAX;
3511 m_pPieceIter->SetIdx(nOldPos);
3512 return;
3513 }
3514
3515 if (bIsUnicode)
3516 {
3517 bFail = o3tl::checked_multiply<WW8_CP>(nCpLen, 2, nCpLen);
3518 if (bFail)
3519 {
3520 SAL_WARN("sw.ww8", "broken offset, ignoring");
3521 p->nStartPos = p->nEndPos = WW8_FC_MAX;
3522 m_pPieceIter->SetIdx(nOldPos);
3523 return;
3524 }
3525 }
3526
3527 bFail = o3tl::checked_add(nBeginLimitFC, nCpLen, nLimitFC);
3528 if (bFail)
3529 {
3530 SAL_WARN("sw.ww8", "broken offset, ignoring");
3531 p->nStartPos = p->nEndPos = WW8_FC_MAX;
3532 m_pPieceIter->SetIdx(nOldPos);
3533 return;
3534 }
3535
3536 if (nOldEndPos <= nLimitFC)
3537 {
3538 bFail = o3tl::checked_sub(nLimitFC, nOldEndPos, nCpLen);
3539 if (bFail)
3540 {
3541 SAL_WARN("sw.ww8", "broken offset, ignoring");
3542 p->nStartPos = p->nEndPos = WW8_FC_MAX;
3543 m_pPieceIter->SetIdx(nOldPos);
3544 return;
3545 }
3546
3547 nCpLen /= (bIsUnicode ? 2 : 1);
3548
3549 bFail = o3tl::checked_sub(nCpEnd, nCpLen, p->nEndPos);
3550 if (bFail)
3551 {
3552 SAL_WARN("sw.ww8", "broken offset, ignoring");
3553 p->nStartPos = p->nEndPos = WW8_FC_MAX;
3554 m_pPieceIter->SetIdx(nOldPos);
3555 return;
3556 }
3557 }
3558 else
3559 {
3560 p->nEndPos = nCpEnd;
3561 if (m_ePLCF != CHP)
3562 {
3563 /*
3564 If the FKP FC that was found was greater than the FC
3565 of the end of the piece, scan piece by piece toward
3566 the end of the document until a piece is found that
3567 contains a paragraph end mark.
3568 */
3569
3570 /*
3571 It's possible to check if a piece contains a paragraph
3572 mark by using the FC of the beginning of the piece to
3573 search in the FKPs for the smallest FC in the FKP rgfc
3574 that is greater than the FC of the beginning of the
3575 piece. If the FC found is less than or equal to the
3576 limit FC of the piece, then the character that ends
3577 the paragraph is the character immediately before the
3578 FKP fc
3579 */
3580
3582
3585 {
3586 if( !m_pPieceIter->Get( nCpStart, nCpEnd, pData ) )
3587 {
3588 OSL_ENSURE( false, "piece iter broken!" );
3589 break;
3590 }
3591 bIsUnicode = false;
3592 sal_Int32 nFcStart=SVBT32ToUInt32(static_cast<WW8_PCD*>(pData)->fc);
3593
3595 {
3596 nFcStart =
3598 nFcStart,bIsUnicode );
3599 }
3600
3601 bFail = o3tl::checked_sub(nCpEnd, nCpStart, nCpLen);
3602 if (bFail)
3603 {
3604 SAL_WARN("sw.ww8", "broken offset, ignoring");
3605 p->nStartPos = p->nEndPos = WW8_FC_MAX;
3606 continue;
3607 }
3608
3609 if (bIsUnicode)
3610 {
3611 bFail = o3tl::checked_multiply<WW8_CP>(nCpLen, 2, nCpLen);
3612 if (bFail)
3613 {
3614 SAL_WARN("sw.ww8", "broken offset, ignoring");
3615 p->nStartPos = p->nEndPos = WW8_FC_MAX;
3616 continue;
3617 }
3618 }
3619
3620 bFail = o3tl::checked_add(nFcStart, nCpLen, nLimitFC);
3621 if (bFail)
3622 {
3623 SAL_WARN("sw.ww8", "broken offset, ignoring");
3624 p->nStartPos = p->nEndPos = WW8_FC_MAX;
3625 continue;
3626 }
3627
3628 //if it doesn't exist, skip it
3629 if (!SeekPos(nCpStart))
3630 continue;
3631
3632 WW8_FC nOne,nSmallest;
3633 p->pMemPos = WW8PLCFx_Fc_FKP::GetSprmsAndPos(nOne,
3634 nSmallest, p->nSprmsLen);
3635
3636 if (nSmallest <= nLimitFC)
3637 {
3638 WW8_CP nCpDiff;
3639 bFail = o3tl::checked_sub(nLimitFC, nSmallest, nCpDiff);
3640 if (bFail)
3641 {
3642 SAL_WARN("sw.ww8", "broken offset, ignoring");
3643 p->nStartPos = p->nEndPos = WW8_FC_MAX;
3644 continue;
3645 }
3646 if (bIsUnicode)
3647 nCpDiff /= 2;
3648
3649 WW8_CP nEndPos;
3650 bFail = o3tl::checked_sub(nCpEnd, nCpDiff, nEndPos);
3651 if (bFail)
3652 {
3653 SAL_WARN("sw.ww8", "broken offset, ignoring");
3654 p->nStartPos = p->nEndPos = WW8_FC_MAX;
3655 continue;
3656 }
3657
3658 OSL_ENSURE(nEndPos >= p->nStartPos, "EndPos before StartPos");
3659
3660 if (nEndPos >= p->nStartPos)
3661 p->nEndPos = nEndPos;
3662
3663 break;
3664 }
3665 }
3666 }
3667 }
3668 m_pPieceIter->SetIdx( nOldPos );
3669 }
3670 else
3671 WW8PLCFx_PCD::CurrentPieceFc2Cp( p->nStartPos, p->nEndPos,&m_rSBase );
3672 }
3673 else
3674 {
3675 p->nStartPos = m_nAttrStart;
3676 p->nEndPos = m_nAttrEnd;
3677 p->bRealLineEnd = m_bLineEnd;
3678 }
3679 }
3680 else // NO piece table !!!
3681 {
3682 p->nStartPos = m_rSBase.WW8Fc2Cp( p->nStartPos );
3683 p->nEndPos = m_rSBase.WW8Fc2Cp( p->nEndPos );
3684 p->bRealLineEnd = m_ePLCF == PAP;
3685 }
3686}
3687
3689{
3691 // !pPcd: emergency break
3692 if ( !m_bComplex || !m_pPcd )
3693 return;
3694
3695 if( GetPCDIdx() >= m_pPcd->GetIMax() ) // End of PLCF
3696 {
3698 return;
3699 }
3700
3701 sal_Int32 nFkpLen; // Fkp entry
3702 // get Fkp entry
3704
3706 m_bLineEnd = (m_ePLCF == PAP);
3707}
3708
3710 const WW8Fib& rFib, WW8_CP nStartCp)
3711 : WW8PLCFx(rFib, true), maSprmParser(rFib),
3712 m_pStrm(pSt), m_nArrMax(256), m_nSprmSiz(0)
3713{
3714 if (rFib.m_lcbPlcfsed)
3715 m_pPLCF.reset( new WW8PLCF(*pTableSt, rFib.m_fcPlcfsed, rFib.m_lcbPlcfsed,
3716 GetFIBVersion() <= ww::eWW2 ? 6 : 12, nStartCp) );
3717
3718 m_pSprms.reset( new sal_uInt8[m_nArrMax] ); // maximum length
3719}
3720
3722{
3723}
3724
3725sal_uInt32 WW8PLCFx_SEPX::GetIdx() const
3726{
3727 return m_pPLCF ? m_pPLCF->GetIdx() : 0;
3728}
3729
3730void WW8PLCFx_SEPX::SetIdx(sal_uInt32 nIdx)
3731{
3732 if( m_pPLCF ) m_pPLCF->SetIdx( nIdx );
3733}
3734
3736{
3737 return m_pPLCF && m_pPLCF->SeekPos( nCpPos );
3738}
3739
3741{
3742 return m_pPLCF ? m_pPLCF->Where() : 0;
3743}
3744
3746{
3747 if( !m_pPLCF ) return;
3748
3749 void* pData;
3750
3751 p->bRealLineEnd = false;
3752 if (!m_pPLCF->Get( p->nStartPos, p->nEndPos, pData ))
3753 {
3754 p->nStartPos = p->nEndPos = WW8_CP_MAX; // PLCF completely processed
3755 p->pMemPos = nullptr;
3756 p->nSprmsLen = 0;
3757 }
3758 else
3759 {
3760 sal_uInt32 nPo = SVBT32ToUInt32( static_cast<sal_uInt8*>(pData)+2 );
3761 if (nPo == 0xFFFFFFFF || !checkSeek(*m_pStrm, nPo))
3762 {
3763 p->nStartPos = p->nEndPos = WW8_CP_MAX; // Sepx empty
3764 p->pMemPos = nullptr;
3765 p->nSprmsLen = 0;
3766 }
3767 else
3768 {
3769 // read len
3770 if (GetFIBVersion() <= ww::eWW2) // eWW6 ?, docs say yes, but...
3771 {
3772 sal_uInt8 nSiz(0);
3773 m_pStrm->ReadUChar( nSiz );
3774 m_nSprmSiz = nSiz;
3775 }
3776 else
3777 {
3779 }
3780
3781 std::size_t nRemaining = m_pStrm->remainingSize();
3782 if (m_nSprmSiz > nRemaining)
3783 m_nSprmSiz = nRemaining;
3784
3785 if( m_nSprmSiz > m_nArrMax )
3786 { // does not fit
3787 m_nArrMax = m_nSprmSiz; // Get more memory
3788 m_pSprms.reset( new sal_uInt8[m_nArrMax] );
3789 }
3790 m_nSprmSiz = m_pStrm->ReadBytes(m_pSprms.get(), m_nSprmSiz); // read Sprms
3791
3792 p->nSprmsLen = m_nSprmSiz;
3793 p->pMemPos = m_pSprms.get(); // return Position
3794 }
3795 }
3796}
3797
3799{
3800 if (m_pPLCF)
3801 m_pPLCF->advance();
3802}
3803
3805{
3806 return HasSprm(nId, m_pSprms.get(), m_nSprmSiz);
3807}
3808
3809SprmResult WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, const sal_uInt8* pOtherSprms,
3810 tools::Long nOtherSprmSiz ) const
3811{
3812 SprmResult aRet;
3813 if (m_pPLCF)
3814 {
3815 WW8SprmIter aIter(pOtherSprms, nOtherSprmSiz, maSprmParser);
3816 aRet = aIter.FindSprm(nId, /*bFindFirst=*/true);
3817 }
3818 return aRet;
3819}
3820
3821bool WW8PLCFx_SEPX::Find4Sprms(sal_uInt16 nId1,sal_uInt16 nId2,sal_uInt16 nId3,sal_uInt16 nId4,
3822 SprmResult& r1, SprmResult& r2, SprmResult& r3, SprmResult& r4) const
3823{
3824 if( !m_pPLCF )
3825 return false;
3826
3827 bool bFound = false;
3828
3829 sal_uInt8* pSp = m_pSprms.get();
3830 size_t i = 0;
3831 while (i + maSprmParser.MinSprmLen() <= m_nSprmSiz)
3832 {
3833 // Sprm found?
3834 const sal_uInt16 nCurrentId = maSprmParser.GetSprmId(pSp);
3835 sal_Int32 nRemLen = m_nSprmSiz - i;
3836 const sal_Int32 x = maSprmParser.GetSprmSize(nCurrentId, pSp, nRemLen);
3837 bool bValid = x <= nRemLen;
3838 if (!bValid)
3839 {
3840 SAL_WARN("sw.ww8", "sprm longer than remaining bytes, doc or parser is wrong");
3841 break;
3842 }
3843 bool bOk = true;
3844 if( nCurrentId == nId1 )
3845 {
3846 sal_Int32 nFixedLen = maSprmParser.DistanceToData(nId1);
3847 r1 = SprmResult(pSp + nFixedLen, x - nFixedLen);
3848 }
3849 else if( nCurrentId == nId2 )
3850 {
3851 sal_Int32 nFixedLen = maSprmParser.DistanceToData(nId2);
3852 r2 = SprmResult(pSp + nFixedLen, x - nFixedLen);
3853 }
3854 else if( nCurrentId == nId3 )
3855 {
3856 sal_Int32 nFixedLen = maSprmParser.DistanceToData(nId3);
3857 r3 = SprmResult(pSp + nFixedLen, x - nFixedLen);
3858 }
3859 else if( nCurrentId == nId4 )
3860 {
3861 sal_Int32 nFixedLen = maSprmParser.DistanceToData(nId4);
3862 r4 = SprmResult(pSp + nFixedLen, x - nFixedLen);
3863 }
3864 else
3865 bOk = false;
3866 bFound |= bOk;
3867 // increment pointer so that it points to next SPRM
3868 i += x;
3869 pSp += x;
3870 }
3871 return bFound;
3872}
3873
3874SprmResult WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const
3875{
3876 SprmResult aRet;
3877 if (m_pPLCF)
3878 {
3880 aRet = aIter.FindSprm(nId, /*bFindFirst=*/true, &n2nd);
3881 }
3882 return aRet;
3883}
3884
3886 WW8_CP nStartCp, tools::Long nFcRef, tools::Long nLenRef, tools::Long nFcText, tools::Long nLenText,
3887 tools::Long nStruct)
3888 : WW8PLCFx(rFib, true)
3889{
3890 if( nLenRef && nLenText )
3891 {
3892 m_pRef.reset(new WW8PLCF(*pSt, nFcRef, nLenRef, nStruct, nStartCp));
3893 m_pText.reset(new WW8PLCF(*pSt, nFcText, nLenText, 0, nStartCp));
3894 }
3895}
3896
3898{
3899 m_pRef.reset();
3900 m_pText.reset();
3901}
3902
3903sal_uInt32 WW8PLCFx_SubDoc::GetIdx() const
3904{
3905 // Probably pText ... no need for it
3906 if( m_pRef )
3907 return ( m_pRef->GetIdx() << 16 | m_pText->GetIdx() );
3908 return 0;
3909}
3910
3911void WW8PLCFx_SubDoc::SetIdx(sal_uInt32 nIdx)
3912{
3913 if( m_pRef )
3914 {
3915 m_pRef->SetIdx( nIdx >> 16 );
3916 // Probably pText ... no need for it
3917 m_pText->SetIdx( nIdx & 0xFFFF );
3918 }
3919}
3920
3922{
3923 return m_pRef && m_pRef->SeekPos( nCpPos );
3924}
3925
3927{
3928 return m_pRef ? m_pRef->Where() : WW8_CP_MAX;
3929}
3930
3932{
3933 p->nStartPos = p->nEndPos = WW8_CP_MAX;
3934 p->pMemPos = nullptr;
3935 p->nSprmsLen = 0;
3936 p->bRealLineEnd = false;
3937
3938 if (!m_pRef)
3939 return;
3940
3941 sal_uInt32 nNr = m_pRef->GetIdx();
3942
3943 void *pData;
3944 WW8_CP nFoo;
3945 if (!m_pRef->Get(p->nStartPos, nFoo, pData))
3946 {
3947 p->nEndPos = p->nStartPos = WW8_CP_MAX;
3948 return;
3949 }
3950
3951 if (o3tl::checked_add<WW8_CP>(p->nStartPos, 1, p->nEndPos))
3952 {
3953 SAL_WARN("sw.ww8", "broken offset, ignoring");
3954 p->nEndPos = p->nStartPos = WW8_CP_MAX;
3955 return;
3956 }
3957
3958 if (!m_pText)
3959 return;
3960
3961 m_pText->SetIdx(nNr);
3962
3963 if (!m_pText->Get(p->nCp2OrIdx, p->nSprmsLen, pData))
3964 {
3965 p->nEndPos = p->nStartPos = WW8_CP_MAX;
3966 p->nSprmsLen = 0;
3967 return;
3968 }
3969
3970 if (p->nCp2OrIdx < 0 || p->nCp2OrIdx > p->nSprmsLen)
3971 {
3972 SAL_WARN("sw.ww8", "Document has invalid Cp or Idx, ignoring it");
3973 p->nEndPos = p->nStartPos = WW8_CP_MAX;
3974 p->nSprmsLen = 0;
3975 return;
3976 }
3977
3978 p->nSprmsLen -= p->nCp2OrIdx;
3979}
3980
3982{
3983 if (m_pRef && m_pText)
3984 {
3985 m_pRef->advance();
3986 m_pText->advance();
3987 }
3988}
3989
3990// fields
3991WW8PLCFx_FLD::WW8PLCFx_FLD( SvStream* pSt, const WW8Fib& rMyFib, short nType)
3992 : WW8PLCFx(rMyFib, true), m_rFib(rMyFib)
3993{
3994 WW8_FC nFc;
3995 sal_Int32 nLen;
3996
3997 switch( nType )
3998 {
3999 case MAN_HDFT:
4000 nFc = m_rFib.m_fcPlcffldHdr;
4001 nLen = m_rFib.m_lcbPlcffldHdr;
4002 break;
4003 case MAN_FTN:
4006 break;
4007 case MAN_EDN:
4008 nFc = m_rFib.m_fcPlcffldEdn;
4009 nLen = m_rFib.m_lcbPlcffldEdn;
4010 break;
4011 case MAN_AND:
4012 nFc = m_rFib.m_fcPlcffldAtn;
4013 nLen = m_rFib.m_lcbPlcffldAtn;
4014 break;
4015 case MAN_TXBX:
4016 nFc = m_rFib.m_fcPlcffldTxbx;
4017 nLen = m_rFib.m_lcbPlcffldTxbx;
4018 break;
4019 case MAN_TXBX_HDFT:
4022 break;
4023 default:
4024 nFc = m_rFib.m_fcPlcffldMom;
4025 nLen = m_rFib.m_lcbPlcffldMom;
4026 break;
4027 }
4028
4029 if( nLen )
4030 m_pPLCF.reset( new WW8PLCFspecial( pSt, nFc, nLen, 2 ) );
4031}
4032
4034{
4035}
4036
4037sal_uInt32 WW8PLCFx_FLD::GetIdx() const
4038{
4039 return m_pPLCF ? m_pPLCF->GetIdx() : 0;
4040}
4041
4042void WW8PLCFx_FLD::SetIdx(sal_uInt32 nIdx)
4043{
4044 if( m_pPLCF )
4045 m_pPLCF->SetIdx( nIdx );
4046}
4047
4049{
4050 return m_pPLCF && m_pPLCF->SeekPosExact( nCpPos );
4051}
4052
4054{
4055 return m_pPLCF ? m_pPLCF->Where() : WW8_CP_MAX;
4056}
4057
4059{
4060 void* pData;
4061 sal_Int32 nTest;
4062 return m_pPLCF && m_pPLCF->Get(nTest, pData) && ((static_cast<sal_uInt8*>(pData)[0] & 0x1f) == 0x13);
4063}
4064
4066{
4067 bool bRet = false;
4068
4069 if (m_pPLCF)
4070 {
4071 tools::Long n = m_pPLCF->GetIdx();
4072
4073 m_pPLCF->advance();
4074
4075 void* pData;
4076 sal_Int32 nTest;
4077 if ( m_pPLCF->Get(nTest, pData) && ((static_cast<sal_uInt8*>(pData)[0] & 0x1f) == 0x15) )
4078 {
4079 nCP = nTest;
4080 bRet = true;
4081 }
4082
4083 m_pPLCF->SetIdx(n);
4084 }
4085
4086 return bRet;
4087}
4088
4090{
4091 p->nStartPos = p->nEndPos = WW8_CP_MAX;
4092 p->pMemPos = nullptr;
4093 p->nSprmsLen = 0;
4094 p->bRealLineEnd = false;
4095
4096 if (!m_pPLCF)
4097 {
4098 p->nStartPos = WW8_CP_MAX; // there are no fields
4099 return;
4100 }
4101
4102 tools::Long n = m_pPLCF->GetIdx();
4103
4104 sal_Int32 nP;
4105 void *pData;
4106 if (!m_pPLCF->Get(nP, pData)) // end of PLCFspecial?
4107 {
4108 p->nStartPos = WW8_CP_MAX; // PLCF completely processed
4109 return;
4110 }
4111
4112 p->nStartPos = nP;
4113
4114 m_pPLCF->advance();
4115 if (!m_pPLCF->Get(nP, pData)) // end of PLCFspecial?
4116 {
4117 p->nStartPos = WW8_CP_MAX; // PLCF completely processed
4118 return;
4119 }
4120
4121 p->nEndPos = nP;
4122
4123 m_pPLCF->SetIdx(n);
4124
4125 p->nCp2OrIdx = m_pPLCF->GetIdx();
4126}
4127
4129{
4130 SAL_WARN_IF(!m_pPLCF, "sw.ww8", "Call without PLCFspecial field");
4131 if( !m_pPLCF )
4132 return;
4133 m_pPLCF->advance();
4134}
4135
4137{
4138 SAL_WARN_IF(!m_pPLCF, "sw.ww8", "Call without PLCFspecial field");
4139 if( !m_pPLCF )
4140 return false;
4141
4142 tools::Long n = m_pPLCF->GetIdx();
4143 m_pPLCF->SetIdx(nIdx);
4144
4145 bool bOk = WW8GetFieldPara(*m_pPLCF, rF);
4146
4147 m_pPLCF->SetIdx(n);
4148 return bOk;
4149}
4150
4151// WW8PLCF_Book
4152void WW8ReadSTTBF(bool bVer8, SvStream& rStrm, sal_uInt32 nStart, sal_Int32 nLen,
4153 sal_uInt16 nExtraLen, rtl_TextEncoding eCS, std::vector<OUString> &rArray,
4154 std::vector<ww::bytes>* pExtraArray, std::vector<OUString>* pValueArray)
4155{
4156 if (nLen==0) // Handle Empty STTBF
4157 return;
4158
4159 sal_uInt64 const nOldPos = rStrm.Tell();
4160 if (checkSeek(rStrm, nStart))
4161 {
4162 sal_uInt16 nLen2(0);
4163 rStrm.ReadUInt16( nLen2 ); // bVer67: total length of structure
4164 // bVer8 : count of strings
4165
4166 if( bVer8 )
4167 {
4168 sal_uInt16 nStrings(0);
4169 bool bUnicode = (0xFFFF == nLen2);
4170 if (bUnicode)
4171 rStrm.ReadUInt16( nStrings );
4172 else
4173 nStrings = nLen2;
4174
4175 rStrm.ReadUInt16( nExtraLen );
4176
4177 const size_t nMinStringLen = bUnicode ? sizeof(sal_uInt16) : sizeof(sal_uInt8);
4178 const size_t nMinRecordSize = nExtraLen + nMinStringLen;
4179 assert(nMinRecordSize != 0 && "impossible to be zero");
4180 const size_t nMaxPossibleStrings = rStrm.remainingSize() / nMinRecordSize;
4181 if (nStrings > nMaxPossibleStrings)
4182 {
4183 SAL_WARN("sw.ww8", "STTBF claims " << nStrings << " entries, but only " << nMaxPossibleStrings << " are possible");
4184 nStrings = nMaxPossibleStrings;
4185 }
4186
4187 if (nExtraLen && nStrings)
4188 {
4189 const size_t nMaxExtraLen = (rStrm.remainingSize() - (nStrings * nMinStringLen)) / nStrings;
4190 if (nExtraLen > nMaxExtraLen)
4191 {
4192 SAL_WARN("sw.ww8", "STTBF claims " << nMaxExtraLen << " extra len, but only " << nMaxExtraLen << " are possible");
4193 nExtraLen = nMaxExtraLen;
4194 }
4195 }
4196
4197 for (sal_uInt16 i=0; i < nStrings; ++i)
4198 {
4199 if (bUnicode)
4200 rArray.push_back(read_uInt16_PascalString(rStrm));
4201 else
4202 {
4204 rArray.push_back(OStringToOUString(aTmp, eCS));
4205 }
4206
4207 // Skip the extra data
4208 if (nExtraLen)
4209 {
4210 if (pExtraArray)
4211 {
4212 ww::bytes extraData(nExtraLen);
4213 rStrm.ReadBytes(extraData.data(), nExtraLen);
4214 pExtraArray->push_back(extraData);
4215 }
4216 else
4217 rStrm.SeekRel( nExtraLen );
4218 }
4219 }
4220 // read the value of the document variables, if requested.
4221 if (pValueArray)
4222 {
4223 for (sal_uInt16 i=0; i < nStrings; ++i)
4224 {
4225 if( bUnicode )
4226 pValueArray->push_back(read_uInt16_PascalString(rStrm));
4227 else
4228 {
4230 pValueArray->push_back(OStringToOUString(aTmp, eCS));
4231 }
4232 }
4233 }
4234 }
4235 else
4236 {
4237 if( nLen2 != nLen )
4238 {
4239 OSL_ENSURE(nLen2 == nLen,
4240 "Fib length and read length are different");
4241 if (nLen > SAL_MAX_UINT16)
4242 nLen = SAL_MAX_UINT16;
4243 else if (nLen < 2 )
4244 nLen = 2;
4245 nLen2 = o3tl::narrowing<sal_uInt16>(nLen);
4246 }
4247 sal_uLong nRead = 0;
4248 for( nLen2 -= 2; nRead < nLen2; )
4249 {
4250 sal_uInt8 nBChar(0);
4251 rStrm.ReadUChar( nBChar );
4252 ++nRead;
4253 if (nBChar)
4254 {
4255 OString aTmp = read_uInt8s_ToOString(rStrm, nBChar);
4256 nRead += aTmp.getLength();
4257 rArray.push_back(OStringToOUString(aTmp, eCS));
4258 }
4259 else
4260 rArray.emplace_back();
4261
4262 // Skip the extra data (for bVer67 versions this must come from
4263 // external knowledge)
4264 if (nExtraLen)
4265 {
4266 if (pExtraArray)
4267 {
4268 ww::bytes extraData(nExtraLen);
4269 rStrm.ReadBytes(extraData.data(), nExtraLen);
4270 pExtraArray->push_back(extraData);
4271 }
4272 else
4273 rStrm.SeekRel( nExtraLen );
4274 nRead+=nExtraLen;
4275 }
4276 }
4277 }
4278 }
4279 rStrm.Seek(nOldPos);
4280}
4281
4283 : WW8PLCFx(rFib, false), m_nIsEnd(0), m_nBookmarkId(1)
4284{
4285 if( !rFib.m_fcPlcfbkf || !rFib.m_lcbPlcfbkf || !rFib.m_fcPlcfbkl ||
4286 !rFib.m_lcbPlcfbkl || !rFib.m_fcSttbfbkmk || !rFib.m_lcbSttbfbkmk )
4287 {
4288 m_nIMax = 0;
4289 }
4290 else
4291 {
4292 m_pBook[0].reset( new WW8PLCFspecial(pTableSt,rFib.m_fcPlcfbkf,rFib.m_lcbPlcfbkf,4) );
4293
4294 m_pBook[1].reset( new WW8PLCFspecial(pTableSt,rFib.m_fcPlcfbkl,rFib.m_lcbPlcfbkl,0) );
4295
4296 rtl_TextEncoding eStructChrSet = WW8Fib::GetFIBCharset(rFib.m_chseTables, rFib.m_lid);
4297
4298 WW8ReadSTTBF( (7 < rFib.m_nVersion), *pTableSt, rFib.m_fcSttbfbkmk,
4299 rFib.m_lcbSttbfbkmk, 0, eStructChrSet, m_aBookNames );
4300
4301 m_nIMax = m_aBookNames.size();
4302
4303 if( m_pBook[0]->GetIMax() < m_nIMax ) // Count of Bookmarks
4304 m_nIMax = m_pBook[0]->GetIMax();
4305 if( m_pBook[1]->GetIMax() < m_nIMax )
4306 m_nIMax = m_pBook[1]->GetIMax();
4307 m_aStatus.resize(m_nIMax);
4308 }
4309}
4310
4312{
4313}
4314
4315sal_uInt32 WW8PLCFx_Book::GetIdx() const
4316{
4317 return m_nIMax ? m_pBook[0]->GetIdx() : 0;
4318}
4319
4320void WW8PLCFx_Book::SetIdx(sal_uInt32 nI)
4321{
4322 if( m_nIMax )
4323 m_pBook[0]->SetIdx( nI );
4324}
4325
4326sal_uInt32 WW8PLCFx_Book::GetIdx2() const
4327{
4328 return m_nIMax ? ( m_pBook[1]->GetIdx() | ( m_nIsEnd ? 0x80000000 : 0 ) ) : 0;
4329}
4330
4331void WW8PLCFx_Book::SetIdx2(sal_uInt32 nI)
4332{
4333 if( m_nIMax )
4334 {
4335 m_pBook[1]->SetIdx( nI & 0x7fffffff );
4336 m_nIsEnd = o3tl::narrowing<sal_uInt16>( ( nI >> 31 ) & 1 ); // 0 or 1
4337 }
4338}
4339
4341{
4342 if( !m_pBook[0] )
4343 return false;
4344
4345 bool bOk = m_pBook[0]->SeekPosExact( nCpPos );
4346 bOk &= m_pBook[1]->SeekPosExact( nCpPos );
4347 m_nIsEnd = 0;
4348
4349 return bOk;
4350}
4351
4353{
4354 return m_pBook[m_nIsEnd]->Where();
4355}
4356
4357tools::Long WW8PLCFx_Book::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
4358{
4359 void* pData;
4360 rEnd = WW8_CP_MAX;
4361 rLen = 0;
4362
4363 if (!m_pBook[0] || !m_pBook[1] || !m_nIMax || (m_pBook[m_nIsEnd]->GetIdx()) >= m_nIMax)
4364 {
4365 rStart = rEnd = WW8_CP_MAX;
4366 return -1;
4367 }
4368
4369 (void)m_pBook[m_nIsEnd]->Get( rStart, pData ); // query position
4370 return m_pBook[m_nIsEnd]->GetIdx();
4371}
4372
4373// The operator ++ has a pitfall: If 2 bookmarks adjoin each other,
4374// we should first go to the end of the first one
4375// and then to the beginning of the second one.
4376// But if 2 bookmarks with the length of 0 lie on top of each other,
4377// we *must* first find the start and end of each bookmark.
4378// The case of: ][
4379// [...]
4380// ][
4381// is not solved yet.
4382// Because I must jump back and forth in the start- and end-indices then.
4383// This would require one more index or bitfield to remember
4384// the already processed bookmarks.
4385
4387{
4388 if( !(m_pBook[0] && m_pBook[1] && m_nIMax) )
4389 return;
4390
4391 (*m_pBook[m_nIsEnd]).advance();
4392
4393 sal_uLong l0 = m_pBook[0]->Where();
4394 sal_uLong l1 = m_pBook[1]->Where();
4395 if( l0 < l1 )
4396 m_nIsEnd = 0;
4397 else if( l1 < l0 )
4398 m_nIsEnd = 1;
4399 else
4400 {
4401 const void * p = m_pBook[0]->GetData(m_pBook[0]->GetIdx());
4402 tools::Long nPairFor = (p == nullptr) ? 0 : SVBT16ToUInt16(*static_cast<SVBT16 const *>(p));
4403 if (nPairFor == m_pBook[1]->GetIdx())
4404 m_nIsEnd = 0;
4405 else
4406 m_nIsEnd = m_nIsEnd ? 0 : 1;
4407 }
4408}
4409
4411{
4412 if( m_nIsEnd )
4413 {
4414 OSL_ENSURE( false, "Incorrect call (1) of PLCF_Book::GetLen()" );
4415 return 0;
4416 }
4417 void * p;
4418 WW8_CP nStartPos;
4419 if( !m_pBook[0]->Get( nStartPos, p ) )
4420 {
4421 OSL_ENSURE( false, "Incorrect call (2) of PLCF_Book::GetLen()" );
4422 return 0;
4423 }
4424 const sal_uInt16 nEndIdx = SVBT16ToUInt16( *static_cast<SVBT16*>(p) );
4425 tools::Long nNum = m_pBook[1]->GetPos( nEndIdx );
4426 nNum -= nStartPos;
4427 return nNum;
4428}
4429
4430void WW8PLCFx_Book::SetStatus(sal_uInt16 nIndex, eBookStatus eStat)
4431{
4432 SAL_WARN_IF(nIndex >= m_nIMax, "sw.ww8",
4433 "bookmark index " << nIndex << " invalid");
4434 eBookStatus eStatus = m_aStatus.at(nIndex);
4435 m_aStatus[nIndex] = static_cast<eBookStatus>(eStatus | eStat);
4436}
4437
4439{
4440 if (m_aStatus.empty())
4441 return BOOK_NORMAL;
4442 tools::Long nEndIdx = GetHandle();
4443 return ( nEndIdx < m_nIMax ) ? m_aStatus[nEndIdx] : BOOK_NORMAL;
4444}
4445
4447{
4448 if( !m_pBook[0] || !m_pBook[1] )
4449 return LONG_MAX;
4450
4451 if( m_nIsEnd )
4452 return m_pBook[1]->GetIdx();
4453 else
4454 {
4455 if (const void* p = m_pBook[0]->GetData(m_pBook[0]->GetIdx()))
4456 return SVBT16ToUInt16( *static_cast<SVBT16 const *>(p) );
4457 else
4458 return LONG_MAX;
4459 }
4460}
4461
4462OUString WW8PLCFx_Book::GetBookmark(tools::Long nStart,tools::Long nEnd, sal_uInt16 &nIndex)
4463{
4464 bool bFound = false;
4465 sal_uInt16 i = 0;
4466 if (m_pBook[0] && m_pBook[1])
4467 {
4468 WW8_CP nStartCurrent, nEndCurrent;
4469 while (sal::static_int_cast<decltype(m_aBookNames)::size_type>(i) < m_aBookNames.size())
4470 {
4471 void* p;
4472 sal_uInt16 nEndIdx;
4473
4474 if( m_pBook[0]->GetData( i, nStartCurrent, p ) && p )
4475 nEndIdx = SVBT16ToUInt16( *static_cast<SVBT16*>(p) );
4476 else
4477 {
4478 OSL_ENSURE( false, "Bookmark-EndIdx not readable" );
4479 nEndIdx = i;
4480 }
4481
4482 nEndCurrent = m_pBook[1]->GetPos( nEndIdx );
4483
4484 if ((nStartCurrent >= nStart) && (nEndCurrent <= nEnd))
4485 {
4486 nIndex = i;
4487 bFound=true;
4488 break;
4489 }
4490 ++i;
4491 }
4492 }
4493 return bFound ? m_aBookNames[i] : OUString();
4494}
4495
4496OUString WW8PLCFx_Book::GetUniqueBookmarkName(const OUString &rSuggestedName)
4497{
4498 OUString aRet(rSuggestedName.isEmpty() ? OUString("Unnamed") : rSuggestedName);
4499 size_t i = 0;
4500 while (i < m_aBookNames.size())
4501 {
4502 if (aRet == m_aBookNames[i])
4503 {
4504 sal_Int32 len = aRet.getLength();
4505 sal_Int32 p = len - 1;
4506 while (p > 0 && aRet[p] >= '0' && aRet[p] <= '9')
4507 --p;
4508 aRet = aRet.subView(0, p+1) + OUString::number(m_nBookmarkId++);
4509 i = 0; // start search from beginning
4510 }
4511 else
4512 ++i;
4513 }
4514 return aRet;
4515}
4516
4517void WW8PLCFx_Book::MapName(OUString& rName)
4518{
4519 if( !m_pBook[0] || !m_pBook[1] )
4520 return;
4521
4522 size_t i = 0;
4523 while (i < m_aBookNames.size())
4524 {
4525 if (rName.equalsIgnoreAsciiCase(m_aBookNames[i]))
4526 {
4527 rName = m_aBookNames[i];
4528 break;
4529 }
4530 ++i;
4531 }
4532}
4533
4534const OUString* WW8PLCFx_Book::GetName() const
4535{
4536 const OUString *pRet = nullptr;
4537 if (!m_nIsEnd && (m_pBook[0]->GetIdx() < m_nIMax))
4538 pRet = &(m_aBookNames[m_pBook[0]->GetIdx()]);
4539 return pRet;
4540}
4541
4543 : WW8PLCFx(rFib, /*bSprm=*/false),
4544 m_bIsEnd(false)
4545{
4546 if (!rFib.m_fcPlcfAtnbkf || !rFib.m_lcbPlcfAtnbkf || !rFib.m_fcPlcfAtnbkl || !rFib.m_lcbPlcfAtnbkl)
4547 {
4548 m_nIMax = 0;
4549 }
4550 else
4551 {
4552 m_pBook[0].reset( new WW8PLCFspecial(pTableSt, rFib.m_fcPlcfAtnbkf, rFib.m_lcbPlcfAtnbkf, 4) );
4553 m_pBook[1].reset( new WW8PLCFspecial(pTableSt, rFib.m_fcPlcfAtnbkl, rFib.m_lcbPlcfAtnbkl, 0) );
4554
4555 m_nIMax = m_pBook[0]->GetIMax();
4556 if (m_pBook[1]->GetIMax() < m_nIMax)
4557 m_nIMax = m_pBook[1]->GetIMax();
4558 }
4559}
4560
4562{
4563}
4564
4566{
4567 return m_nIMax ? m_pBook[0]->GetIdx() : 0;
4568}
4569
4570void WW8PLCFx_AtnBook::SetIdx(sal_uInt32 nI)
4571{
4572 if( m_nIMax )
4573 m_pBook[0]->SetIdx( nI );
4574}
4575
4577{
4578 if (m_nIMax)
4579 return m_pBook[1]->GetIdx() | ( m_bIsEnd ? 0x80000000 : 0 );
4580 else
4581 return 0;
4582}
4583
4584void WW8PLCFx_AtnBook::SetIdx2(sal_uInt32 nI)
4585{
4586 if( m_nIMax )
4587 {
4588 m_pBook[1]->SetIdx( nI & 0x7fffffff );
4589 m_bIsEnd = static_cast<bool>(( nI >> 31 ) & 1);
4590 }
4591}
4592
4594{
4595 if (!m_pBook[0])
4596 return false;
4597
4598 bool bOk = m_pBook[0]->SeekPosExact(nCpPos);
4599 bOk &= m_pBook[1]->SeekPosExact(nCpPos);
4600 m_bIsEnd = false;
4601
4602 return bOk;
4603}
4604
4606{
4607 return m_pBook[static_cast<int>(m_bIsEnd)]->Where();
4608}
4609
4610tools::Long WW8PLCFx_AtnBook::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
4611{
4612 void* pData;
4613 rEnd = WW8_CP_MAX;
4614 rLen = 0;
4615
4616 if (!m_pBook[0] || !m_pBook[1] || !m_nIMax || (m_pBook[static_cast<int>(m_bIsEnd)]->GetIdx()) >= m_nIMax)
4617 {
4618 rStart = rEnd = WW8_CP_MAX;
4619 return -1;
4620 }
4621
4622 (void)m_pBook[static_cast<int>(m_bIsEnd)]->Get(rStart, pData);
4623 return m_pBook[static_cast<int>(m_bIsEnd)]->GetIdx();
4624}
4625
4627{
4628 if( !(m_pBook[0] && m_pBook[1] && m_nIMax) )
4629 return;
4630
4631 (*m_pBook[static_cast<int>(m_bIsEnd)]).advance();
4632
4633 sal_uLong l0 = m_pBook[0]->Where();
4634 sal_uLong l1 = m_pBook[1]->Where();
4635 if( l0 < l1 )
4636 m_bIsEnd = false;
4637 else if( l1 < l0 )
4638 m_bIsEnd = true;
4639 else
4640 {
4641 const void * p = m_pBook[0]->GetData(m_pBook[0]->GetIdx());
4642 tools::Long nPairFor = (p == nullptr) ? 0 : SVBT16ToUInt16(*static_cast<SVBT16 const *>(p));
4643 if (nPairFor == m_pBook[1]->GetIdx())
4644 m_bIsEnd = false;
4645 else
4646 m_bIsEnd = !m_bIsEnd;
4647 }
4648}
4649
4651{
4652 if (!m_pBook[0] || !m_pBook[1])
4653 return LONG_MAX;
4654
4655 if (m_bIsEnd)
4656 return m_pBook[1]->GetIdx();
4657 else
4658 {
4659 if (const void* p = m_pBook[0]->GetData(m_pBook[0]->GetIdx()))
4660 return SVBT16ToUInt16(*static_cast<const SVBT16*>(p));
4661 else
4662 return LONG_MAX;
4663 }
4664}
4665
4667{
4668 return m_bIsEnd;
4669}
4670
4672 : WW8PLCFx(rFib, /*bSprm=*/false),
4673 m_bIsEnd(false)
4674{
4676 {
4677 m_nIMax = 0;
4678 }
4679 else
4680 {
4681 m_pBook[0].reset(new WW8PLCFspecial(pTableSt, rFib.m_fcPlcfBkfFactoid, rFib.m_lcbPlcfBkfFactoid, 6));
4682 m_pBook[1].reset(new WW8PLCFspecial(pTableSt, rFib.m_fcPlcfBklFactoid, rFib.m_lcbPlcfBklFactoid, 4));
4683
4684 m_nIMax = m_pBook[0]->GetIMax();
4685 if (m_pBook[1]->GetIMax() < m_nIMax)
4686 m_nIMax = m_pBook[1]->GetIMax();
4687 }
4688}
4689
4691{
4692}
4693
4695{
4696 return m_nIMax ? m_pBook[0]->GetIdx() : 0;
4697}
4698
4700{
4701 if (m_nIMax)
4702 m_pBook[0]->SetIdx(nI);
4703}
4704
4706{
4707 if (m_nIMax)
4708 return m_pBook[1]->GetIdx() | (m_bIsEnd ? 0x80000000 : 0);
4709 else
4710 return 0;
4711}
4712
4714{
4715 if (m_nIMax)
4716 {
4717 m_pBook[1]->SetIdx(nI & 0x7fffffff);
4718 m_bIsEnd = static_cast<bool>((nI >> 31) & 1);
4719 }
4720}
4721
4723{
4724 if (!m_pBook[0])
4725 return false;
4726
4727 bool bOk = m_pBook[0]->SeekPosExact(nCpPos);
4728 bOk &= m_pBook[1]->SeekPosExact(nCpPos);
4729 m_bIsEnd = false;
4730
4731 return bOk;
4732}
4733
4735{
4736 return m_pBook[static_cast<int>(m_bIsEnd)]->Where();
4737}
4738
4740{
4741 void* pData;
4742 rEnd = WW8_CP_MAX;
4743 rLen = 0;
4744
4745 if (!m_pBook[0] || !m_pBook[1] || !m_nIMax || (m_pBook[static_cast<int>(m_bIsEnd)]->GetIdx()) >= m_nIMax)
4746 {
4747 rStart = rEnd = WW8_CP_MAX;
4748 return -1;
4749 }
4750
4751 (void)m_pBook[static_cast<int>(m_bIsEnd)]->Get(rStart, pData);
4752 return m_pBook[static_cast<int>(m_bIsEnd)]->GetIdx();
4753}
4754
4756{
4757 if (!(m_pBook[0] && m_pBook[1] && m_nIMax))
4758 return;
4759
4760 (*m_pBook[static_cast<int>(m_bIsEnd)]).advance();
4761
4762 sal_uLong l0 = m_pBook[0]->Where();
4763 sal_uLong l1 = m_pBook[1]->Where();
4764 if (l0 < l1)
4765 m_bIsEnd = false;
4766 else if (l1 < l0)
4767 m_bIsEnd = true;
4768 else
4769 {
4770 const void * p = m_pBook[0]->GetData(m_pBook[0]->GetIdx());
4771 tools::Long nPairFor = (p == nullptr) ? 0 : SVBT16ToUInt16(*static_cast<SVBT16 const *>(p));
4772 if (nPairFor == m_pBook[1]->GetIdx())
4773 m_bIsEnd = false;
4774 else
4775 m_bIsEnd = !m_bIsEnd;
4776 }
4777}
4778
4780{
4781 if (!m_pBook[0] || !m_pBook[1])
4782 return LONG_MAX;
4783
4784 if (m_bIsEnd)
4785 return m_pBook[1]->GetIdx();
4786 else
4787 {
4788 if (const void* p = m_pBook[0]->GetData(m_pBook[0]->GetIdx()))
4789 return SVBT16ToUInt16(*static_cast<const SVBT16*>(p));
4790 else
4791 return LONG_MAX;
4792 }
4793}
4794
4796{
4797 return m_bIsEnd;
4798}
4799
4800// In the end of a paragraph in WW6 the attribute extends after the <CR>.
4801// This will be reset by one character to be used with SW,
4802// if we don't expect trouble thereby.
4804{
4805 // might be necessary to do this for pChp and/or pSep as well,
4806 // but its definitely the case for paragraphs that EndPos > StartPos
4807 // for a well formed paragraph as those always have a paragraph
4808 // <cr> in them
4809 if (&rDesc == m_pPap && rDesc.bRealLineEnd)
4810 {
4811 if (rDesc.nStartPos == rDesc.nEndPos && rDesc.nEndPos != WW8_CP_MAX)
4812 {
4813 SAL_WARN("sw.ww8", "WW8PLCFxDesc End same as Start, abandoning to avoid looping");
4814 rDesc.nEndPos = WW8_CP_MAX;
4815 }
4816 }
4817
4818 //Store old end position for supercool new property finder that uses
4819 //cp instead of fc's as nature intended
4820 rDesc.nOrigEndPos = rDesc.nEndPos;
4821 rDesc.nOrigStartPos = rDesc.nStartPos;
4822
4823 /*
4824 Normally given ^XXX{para end}^ we don't actually insert a para end
4825 character into the document, so we clip the para end property one to the
4826 left to make the para properties end when the paragraph text does. In a
4827 drawing textbox we actually do insert a para end character, so we don't
4828 clip it. Making the para end properties end after the para end char.
4829 */
4830 if (GetDoingDrawTextBox())
4831 return;
4832
4833 if ( (&rDesc == m_pPap) && rDesc.bRealLineEnd )
4834 {
4835 if ( m_pPap->nEndPos != WW8_CP_MAX ) // Para adjust
4836 {
4837 m_nLineEnd = m_pPap->nEndPos;// nLineEnd points *after* the <CR>
4838 m_pPap->nEndPos--; // shorten paragraph end by one character
4839
4840 // Is there already a sep end, which points to the current paragraph end?
4841 // Then we also must shorten by one character
4842 if( m_pSep->nEndPos == m_nLineEnd )
4843 m_pSep->nEndPos--;
4844 }
4845 }
4846 else if (&rDesc == m_pSep)
4847 {
4848 // Sep Adjust if end Char-Attr == paragraph end ...
4849 if( (rDesc.nEndPos == m_nLineEnd) && (rDesc.nEndPos > rDesc.nStartPos) )
4850 rDesc.nEndPos--; // ... then shorten by one character
4851 }
4852}
4853
4855{
4857 "End " << nEndPos << " before Start " << nStartPos);
4858
4859 if( nStartPos != WW8_CP_MAX )
4860 {
4861 /*
4862 ##516##,##517##
4863 Force the property change to happen at the beginning of this
4864 subdocument, same as in GetNewNoSprms, except that the target type is
4865 attributes attached to a piece that might span subdocument boundaries
4866 */
4867 if (nCpOfs > nStartPos)
4868 nStartPos = 0;
4869 else
4870 nStartPos -= nCpOfs;
4871 }
4872 if (nEndPos != WW8_CP_MAX)
4873 {
4874 if (nCpOfs > nEndPos)
4875 {
4876 SAL_WARN("sw.ww8", "broken subdocument piece entry");
4878 }
4879 else
4880 nEndPos -= nCpOfs;
4881 }
4882}
4883
4885{
4886 rDesc.pPLCFx->GetSprms(&rDesc);
4887 rDesc.ReduceByOffset();
4888
4889 rDesc.bFirstSprm = true;
4890 AdjustEnds( rDesc );
4891 rDesc.nOrigSprmsLen = rDesc.nSprmsLen;
4892}
4893
4895{
4896 rDesc.nCp2OrIdx = rDesc.pPLCFx->GetNoSprms(rDesc.nStartPos, rDesc.nEndPos,
4897 rDesc.nSprmsLen);
4898
4899 SAL_WARN_IF(WW8_CP_MAX != rDesc.nStartPos && rDesc.nStartPos > rDesc.nEndPos, "sw.ww8",
4900 "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos);
4901
4902 rDesc.ReduceByOffset();
4903
4904 rDesc.bFirstSprm = true;
4905 rDesc.nOrigSprmsLen = rDesc.nSprmsLen;
4906}
4907
4908sal_uInt16 WW8PLCFMan::GetId(const WW8PLCFxDesc* p) const
4909{
4910 sal_uInt16 nId = 0; // Id = 0 for empty attributes
4911
4912 if (p == m_pField)
4913 nId = eFLD;
4914 else if (p == m_pFootnote)
4915 nId = eFTN;
4916 else if (p == m_pEdn)
4917 nId = eEDN;
4918 else if (p == m_pAnd)
4919 nId = eAND;
4920 else if (p->nSprmsLen >= maSprmParser.MinSprmLen())
4921 nId = maSprmParser.GetSprmId(p->pMemPos);
4922
4923 return nId;
4924}
4925
4927 bool bDoingDrawTextBox)
4928 : maSprmParser(*pBase->m_pWw8Fib),
4929 m_nLineEnd(WW8_CP_MAX),
4930 mbDoingDrawTextBox(bDoingDrawTextBox)
4931{
4932 m_pWwFib = pBase->m_pWw8Fib;
4933
4934 m_nManType = nType;
4935
4936 if( MAN_MAINTEXT == nType )
4937 {
4938 // search order of the attributes
4940 m_pField = &m_aD[0];
4941 m_pBkm = &m_aD[1];
4942 m_pEdn = &m_aD[2];
4943 m_pFootnote = &m_aD[3];
4944 m_pAnd = &m_aD[4];
4945
4946 m_pPcd = pBase->m_pPLCFx_PCD ? &m_aD[5] : nullptr;
4947 //pPcdA index == pPcd index + 1
4948 m_pPcdA = pBase->m_pPLCFx_PCDAttrs ? &m_aD[6] : nullptr;
4949
4950 m_pChp = &m_aD[7];
4951 m_pPap = &m_aD[8];
4952 m_pSep = &m_aD[9];
4953 m_pAtnBkm = &m_aD[10];
4954 m_pFactoidBkm = &m_aD[11];
4955
4956 m_pSep->pPLCFx = pBase->m_pSepPLCF.get();
4957 m_pFootnote->pPLCFx = pBase->m_pFootnotePLCF.get();
4958 m_pEdn->pPLCFx = pBase->m_pEdnPLCF.get();
4959 m_pBkm->pPLCFx = pBase->m_pBook.get();
4960 m_pAnd->pPLCFx = pBase->m_pAndPLCF.get();
4961 m_pAtnBkm->pPLCFx = pBase->m_pAtnBook.get();
4962 m_pFactoidBkm->pPLCFx = pBase->m_pFactoidBook.get();
4963
4964 }
4965 else
4966 {
4967 // search order of the attributes
4968 m_nPLCF = 7;
4969 m_pField = &m_aD[0];
4970 m_pBkm = pBase->m_pBook ? &m_aD[1] : nullptr;
4971
4972 m_pPcd = pBase->m_pPLCFx_PCD ? &m_aD[2] : nullptr;
4973 //pPcdA index == pPcd index + 1
4974 m_pPcdA= pBase->m_pPLCFx_PCDAttrs ? &m_aD[3] : nullptr;
4975
4976 m_pChp = &m_aD[4];
4977 m_pPap = &m_aD[5];
4978 m_pSep = &m_aD[6]; // Dummy
4979
4980 m_pAnd = m_pAtnBkm = m_pFactoidBkm = m_pFootnote = m_pEdn = nullptr; // not used at SpezText
4981 }
4982
4983 m_pChp->pPLCFx = pBase->m_pChpPLCF.get();
4984 m_pPap->pPLCFx = pBase->m_pPapPLCF.get();
4985 if( m_pPcd )
4986 m_pPcd->pPLCFx = pBase->m_pPLCFx_PCD.get();
4987 if( m_pPcdA )
4988 m_pPcdA->pPLCFx= pBase->m_pPLCFx_PCDAttrs.get();
4989 if( m_pBkm )
4990 m_pBkm->pPLCFx = pBase->m_pBook.get();
4991
4992 m_pMagicTables = pBase->m_pMagicTables.get();
4993 m_pSubdocs = pBase->m_pSubdocs.get();
4994 m_pExtendedAtrds = pBase->m_pExtendedAtrds.get();
4995
4996 switch( nType ) // field initialization
4997 {
4998 case MAN_HDFT:
4999 m_pField->pPLCFx = pBase->m_pFieldHdFtPLCF.get();
5000 m_pFdoa = pBase->m_pHdFtFdoa.get();
5001 m_pTxbx = pBase->m_pHdFtTxbx.get();
5002 m_pTxbxBkd = pBase->m_pHdFtTxbxBkd.get();
5003 break;
5004 case MAN_FTN:
5005 m_pField->pPLCFx = pBase->m_pFieldFootnotePLCF.get();
5006 m_pFdoa = m_pTxbx = m_pTxbxBkd = nullptr;
5007 break;
5008 case MAN_EDN:
5009 m_pField->pPLCFx = pBase->m_pFieldEdnPLCF.get();
5010 m_pFdoa = m_pTxbx = m_pTxbxBkd = nullptr;
5011 break;
5012 case MAN_AND:
5013 m_pField->pPLCFx = pBase->m_pFieldAndPLCF.get();
5014 m_pFdoa = m_pTxbx = m_pTxbxBkd = nullptr;
5015 break;
5016 case MAN_TXBX:
5017 m_pField->pPLCFx = pBase->m_pFieldTxbxPLCF.get();
5018 m_pTxbx = pBase->m_pMainTxbx.get();
5019 m_pTxbxBkd = pBase->m_pMainTxbxBkd.get();
5020 m_pFdoa = nullptr;
5021 break;
5022 case MAN_TXBX_HDFT:
5023 m_pField->pPLCFx = pBase->m_pFieldTxbxHdFtPLCF.get();
5024 m_pTxbx = pBase->m_pHdFtTxbx.get();
5025 m_pTxbxBkd = pBase->m_pHdFtTxbxBkd.get();
5026 m_pFdoa = nullptr;
5027 break;
5028 default:
5029 m_pField->pPLCFx = pBase->m_pFieldPLCF.get();
5030 m_pFdoa = pBase->m_pMainFdoa.get();
5031 m_pTxbx = pBase->m_pMainTxbx.get();
5032 m_pTxbxBkd = pBase->m_pMainTxbxBkd.get();
5033 break;
5034 }
5035
5036 WW8_CP cp = 0;
5037 m_pWwFib->GetBaseCp(nType, &cp); //TODO: check return value
5038 m_nCpO = cp;
5039
5040 if( nStartCp || m_nCpO )
5041 SeekPos( nStartCp ); // adjust PLCFe at text StartPos
5042
5043 // initialization to the member vars Low-Level
5046 for( sal_uInt16 i=0; i < m_nPLCF; ++i)
5047 {
5048 WW8PLCFxDesc* p = &m_aD[i];
5049
5050 /*
5051 ##516##,##517##
5052 For subdocuments we modify the cp of properties to be relative to
5053 the beginning of subdocuments, we should also do the same for
5054 piecetable changes, and piecetable properties, otherwise a piece
5055 change that happens in a subdocument is lost.
5056 */
5057 p->nCpOfs = ( p == m_pChp || p == m_pPap || p == m_pBkm || p == m_pPcd ||
5058 p == m_pPcdA ) ? m_nCpO : 0;
5059
5060 p->nCp2OrIdx = 0;
5061 p->bFirstSprm = false;
5062 p->xIdStack.reset();
5063
5064 if ((p == m_pChp) || (p == m_pPap))
5065 p->nStartPos = p->nEndPos = nStartCp;
5066 else
5067 p->nStartPos = p->nEndPos = WW8_CP_MAX;
5068 }
5069
5070 // initialization to the member vars High-Level
5071 for( sal_uInt16 i=0; i<m_nPLCF; ++i){
5072 WW8PLCFxDesc* p = &m_aD[i];
5073
5074 if( !p->pPLCFx )
5075 {
5076 p->nStartPos = p->nEndPos = WW8_CP_MAX;
5077 continue;
5078 }
5079
5080 if( p->pPLCFx->IsSprm() )
5081 {
5082 // Careful: nEndPos must be
5083 p->xIdStack.emplace();
5084 if ((p == m_pChp) || (p == m_pPap))
5085 {
5086 WW8_CP nTemp = p->nEndPos+p->nCpOfs;
5087 p->pMemPos = nullptr;
5088 p->nSprmsLen = 0;
5089 p->nStartPos = nTemp;
5090 if (!(*p->pPLCFx).SeekPos(p->nStartPos))
5091 p->nEndPos = p->nStartPos = WW8_CP_MAX;
5092 else
5093 GetNewSprms( *p );
5094 }
5095 else
5096 GetNewSprms( *p ); // initialized at all PLCFs
5097 }
5098 else if( p->pPLCFx )
5099 GetNewNoSprms( *p );
5100 }
5101}
5102
5104{
5105 for( sal_uInt16 i=0; i<m_nPLCF; i++)
5106 m_aD[i].xIdStack.reset();
5107}
5108
5109// 0. which attr class,
5110// 1. if it's an attr start,
5111// 2. CP, where is next attr change
5112sal_uInt16 WW8PLCFMan::WhereIdx(bool *const pbStart, WW8_CP *const pPos) const
5113{
5114 OSL_ENSURE(m_nPLCF,"What the hell");
5115 WW8_CP nNext = WW8_CP_MAX; // search order:
5116 sal_uInt16 nNextIdx = m_nPLCF;// first ending found ( CHP, PAP, ( SEP ) ),
5117 bool bStart = true; // now find beginnings ( ( SEP ), PAP, CHP )
5118 const WW8PLCFxDesc* pD;
5119 for (sal_uInt16 i=0; i < m_nPLCF; ++i)
5120 {
5121 pD = &m_aD[i];
5122 if (pD != m_pPcdA)
5123 {
5124 if( (pD->nEndPos < nNext) && (pD->nStartPos == WW8_CP_MAX) )
5125 {
5126 // otherwise start = end
5127 nNext = pD->nEndPos;
5128 nNextIdx = i;
5129 bStart = false;
5130 }
5131 }
5132 }
5133 for (sal_uInt16 i=m_nPLCF; i > 0; --i)
5134 {
5135 pD = &m_aD[i-1];
5136 if (pD != m_pPcdA && pD->nStartPos < nNext )
5137 {
5138 nNext = pD->nStartPos;
5139 nNextIdx = i-1;
5140 bStart = true;
5141 }
5142 }
5143 if( pPos )
5144 *pPos = nNext;
5145 if( pbStart )
5146 *pbStart = bStart;
5147 return nNextIdx;
5148}
5149
5150// gives the CP pos of the next attr change
5152{
5153 WW8_CP l;
5154 WhereIdx(nullptr, &l);
5155 return l;
5156}
5157
5159{
5160 m_pChp->pPLCFx->SeekPos( nNewCp + m_nCpO ); // create new attr
5161 m_pPap->pPLCFx->SeekPos( nNewCp + m_nCpO );
5162 m_pField->pPLCFx->SeekPos( nNewCp );
5163 if( m_pPcd )
5164 m_pPcd->pPLCFx->SeekPos( nNewCp + m_nCpO );
5165 if( m_pBkm )
5166 m_pBkm->pPLCFx->SeekPos( nNewCp + m_nCpO );
5167}
5168
5170{
5171 sal_uInt16 n=0;
5172 if( m_pPcd )
5173 m_pPcd->Save( rSave.aS[n++] );
5174 if( m_pPcdA )
5175 m_pPcdA->Save( rSave.aS[n++] );
5176
5177 for(sal_uInt16 i=0; i<m_nPLCF; ++i)
5178 if( m_pPcd != &m_aD[i] && m_pPcdA != &m_aD[i] )
5179 m_aD[i].Save( rSave.aS[n++] );
5180}
5181
5183{
5184 sal_uInt16 n=0;
5185 if( m_pPcd )
5186 m_pPcd->Restore( rSave.aS[n++] );
5187 if( m_pPcdA )
5188 m_pPcdA->Restore( rSave.aS[n++] );
5189
5190 for(sal_uInt16 i=0; i<m_nPLCF; ++i)
5191 if( m_pPcd != &m_aD[i] && m_pPcdA != &m_aD[i] )
5192 m_aD[i].Restore( rSave.aS[n++] );
5193}
5194
5195namespace
5196{
5197 bool IsSizeLegal(tools::Long nSprmLen, sal_Int32 nSprmsLen)
5198 {
5199 if (nSprmLen > nSprmsLen)
5200 {
5201 SAL_WARN("sw.ww8", "Short sprm, len " << nSprmLen << " claimed, max possible is " << nSprmsLen);
5202 return false;
5203 }
5204 return true;
5205 }
5206}
5207
5208bool WW8PLCFMan::IsSprmLegalForCategory(sal_uInt16 nSprmId, short nIdx) const
5209{
5210 const WW8PLCFxDesc* p = &m_aD[nIdx];
5211 if (p != m_pSep) // just check sep for now
5212 return true;
5213
5214 bool bRet;
5216 if (eVersion <= ww::eWW2)
5217 bRet = nSprmId >= 112 && nSprmId <= 145;
5218 else if (eVersion < ww::eWW8)
5219 bRet = nSprmId >= NS_sprm::v6::sprmSScnsPgn && nSprmId <= NS_sprm::v6::sprmSDMPaperReq;
5220 else
5221 {
5222 /*
5223 Sprm bits: 10-12 sgc sprm group; type of sprm (PAP, CHP, etc)
5224
5225 sgc value type of sprm
5226 1 PAP
5227 2 CHP
5228 3 PIC
5229 4 SEP
5230 5 TAP
5231 */
5232 auto nSGC = ((nSprmId & 0x1C00) >> 10);
5233 bRet = nSGC == 4;
5234 }
5235 if (!bRet)
5236 SAL_INFO("sw.ww8", "sprm, id " << nSprmId << " wrong category for section properties");
5237 return bRet;
5238}
5239
5240void WW8PLCFMan::GetSprmStart( short nIdx, WW8PLCFManResult* pRes ) const
5241{
5242 memset( pRes, 0, sizeof( WW8PLCFManResult ) );
5243
5244 // verifying !!!
5245
5246 pRes->nMemLen = 0;
5247
5248 const WW8PLCFxDesc* p = &m_aD[nIdx];
5249
5250 // first Sprm in a Group
5251 if( p->bFirstSprm )
5252 {
5253 if( p == m_pPap )
5254 pRes->nFlags |= MAN_MASK_NEW_PAP;
5255 else if( p == m_pSep )
5256 pRes->nFlags |= MAN_MASK_NEW_SEP;
5257 }
5258 pRes->pMemPos = p->pMemPos;
5259 pRes->nSprmId = GetId(p);
5260 pRes->nCp2OrIdx = p->nCp2OrIdx;
5261 if ((p == m_pFootnote) || (p == m_pEdn) || (p == m_pAnd))
5262 pRes->nMemLen = p->nSprmsLen;
5263 else if (p->nSprmsLen >= maSprmParser.MinSprmLen()) //normal
5264 {
5265 // Length of actual sprm
5266 pRes->nMemLen = maSprmParser.GetSprmSize(pRes->nSprmId, pRes->pMemPos, p->nSprmsLen);
5267 if (!IsSizeLegal(pRes->nMemLen, p->nSprmsLen) || !IsSprmLegalForCategory(pRes->nSprmId, nIdx))
5268 {
5269 pRes->nSprmId = 0;
5270 }
5271 }
5272}
5273
5274void WW8PLCFMan::GetSprmEnd( short nIdx, WW8PLCFManResult* pRes ) const
5275{
5276 memset( pRes, 0, sizeof( WW8PLCFManResult ) );
5277
5278 const WW8PLCFxDesc* p = &m_aD[nIdx];
5279
5280 if (!(p->xIdStack->empty()))
5281 pRes->nSprmId = p->xIdStack->top(); // get end position
5282 else
5283 {
5284 OSL_ENSURE( false, "No Id on the Stack" );
5285 pRes->nSprmId = 0;
5286 }
5287}
5288
5289void WW8PLCFMan::GetNoSprmStart( short nIdx, WW8PLCFManResult* pRes ) const
5290{
5291 const WW8PLCFxDesc* p = &m_aD[nIdx];
5292
5293 pRes->nCpPos = p->nStartPos;
5294 pRes->nMemLen = p->nSprmsLen;
5295 pRes->nCp2OrIdx = p->nCp2OrIdx;
5296
5297 if( p == m_pField )
5298 pRes->nSprmId = eFLD;
5299 else if( p == m_pFootnote )
5300 pRes->nSprmId = eFTN;
5301 else if( p == m_pEdn )
5302 pRes->nSprmId = eEDN;
5303 else if( p == m_pBkm )
5304 pRes->nSprmId = eBKN;
5305 else if (p == m_pAtnBkm)
5306 pRes->nSprmId = eATNBKN;
5307 else if (p == m_pFactoidBkm)
5308 pRes->nSprmId = eFACTOIDBKN;
5309 else if( p == m_pAnd )
5310 pRes->nSprmId = eAND;
5311 else if( p == m_pPcd )
5312 {
5313 //We slave the piece table attributes to the piece table, the piece
5314 //table attribute iterator contains the sprms for this piece.
5315 GetSprmStart( nIdx+1, pRes );
5316 }
5317 else
5318 pRes->nSprmId = 0; // default: not found
5319}
5320
5321void WW8PLCFMan::GetNoSprmEnd( short nIdx, WW8PLCFManResult* pRes ) const
5322{
5323 pRes->nMemLen = -1; // end tag
5324
5325 if( &m_aD[nIdx] == m_pBkm )
5326 pRes->nSprmId = eBKN;
5327 else if (&m_aD[nIdx] == m_pAtnBkm)
5328 pRes->nSprmId = eATNBKN;
5329 else if (&m_aD[nIdx] == m_pFactoidBkm)
5330 pRes->nSprmId = eFACTOIDBKN;
5331 else if( &m_aD[nIdx] == m_pPcd )
5332 {
5333 //We slave the piece table attributes to the piece table, the piece
5334 //table attribute iterator contains the sprms for this piece.
5335 GetSprmEnd( nIdx+1, pRes );
5336 }
5337 else
5338 pRes->nSprmId = 0;
5339}
5340
5341void WW8PLCFMan::TransferOpenSprms(std::stack<sal_uInt16> &rStack)
5342{
5343 for (sal_uInt16 i = 0; i < m_nPLCF; ++i)
5344 {
5345 WW8PLCFxDesc* p = &m_aD[i];
5346 if (!p || !p->xIdStack)
5347 continue;
5348 while (!p->xIdStack->empty())
5349 {
5350 rStack.push(p->xIdStack->top());
5351 p->xIdStack->pop();
5352 }
5353 }
5354}
5355
5356void WW8PLCFMan::AdvSprm(short nIdx, bool bStart)
5357{
5358 WW8PLCFxDesc* p = &m_aD[nIdx]; // determine sprm class(!)
5359
5360 p->bFirstSprm = false;
5361 if( bStart )
5362 {
5363 const sal_uInt16 nLastId = GetId(p);
5364
5365 const sal_uInt16 nLastAttribStarted = IsSprmLegalForCategory(nLastId, nIdx) ? nLastId : 0;
5366
5367 p->xIdStack->push(nLastAttribStarted); // remember Id for attribute end
5368
5369 if( p->nSprmsLen )
5370 { /*
5371 Check, if we have to process more sprm(s).
5372 */
5373 if( p->pMemPos )
5374 {
5375 // Length of last sprm
5376 const sal_Int32 nSprmL = maSprmParser.GetSprmSize(nLastId, p->pMemPos, p->nSprmsLen);
5377
5378 // Reduce length of all sprms by length of last sprm
5379 p->nSprmsLen -= nSprmL;
5380
5381 // pos of next possible sprm
5382 if (p->nSprmsLen < maSprmParser.MinSprmLen())
5383 {
5384 // preventively set to 0, because the end follows!
5385 p->pMemPos = nullptr;
5386 p->nSprmsLen = 0;
5387 }
5388 else
5389 p->pMemPos += nSprmL;
5390 }
5391 else
5392 p->nSprmsLen = 0;
5393 }
5394 if (p->nSprmsLen < maSprmParser.MinSprmLen())
5395 p->nStartPos = WW8_CP_MAX; // the ending follows
5396 }
5397 else
5398 {
5399 if (!(p->xIdStack->empty()))
5400 p->xIdStack->pop();
5401 if (p->xIdStack->empty())
5402 {
5403 if ( (p == m_pChp) || (p == m_pPap) )
5404 {
5405 p->pMemPos = nullptr;
5406 p->nSprmsLen = 0;
5407 p->nStartPos = p->nOrigEndPos+p->nCpOfs;
5408
5409 /*
5410 On failed seek we have run out of sprms, probably. But if it's
5411 a fastsaved file (has pPcd) then we may be just in a sprm free
5412 gap between pieces that have them, so set dirty flag in sprm
5413 finder to consider than.
5414 */
5415 if (!(*p->pPLCFx).SeekPos(p->nStartPos))
5416 {
5417 p->nEndPos = WW8_CP_MAX;
5418 p->pPLCFx->SetDirty(true);
5419 }
5420 if (!p->pPLCFx->GetDirty() || m_pPcd)
5421 GetNewSprms( *p );
5422 p->pPLCFx->SetDirty(false);
5423
5424 /*
5425 #i2325#
5426 To get the character and paragraph properties you first get
5427 the pap and chp and then apply the fastsaved pPcd properties
5428 to the range. If a pap or chp starts inside the pPcd range
5429 then we must bring the current pPcd range to a halt so as to
5430 end those sprms, then the pap/chp will be processed, and then
5431 we must force a restart of the pPcd on that pap/chp starting
5432 boundary. Doing that effectively means that the pPcd sprms will
5433 be applied to the new range. Not doing it means that the pPcd
5434 sprms will only be applied to the first pap/chp set of
5435 properties contained in the pap/chp range.
5436
5437 So we bring the pPcd to a halt on this location here, by
5438 settings its end to the current start, then store the starting
5439 position of the current range to clipstart. The pPcd sprms
5440 will end as normal (albeit earlier than originally expected),
5441 and the existence of a clipstart will force the pPcd iterator
5442 to reread the current set of sprms instead of advancing to its
5443 next set. Then the clipstart will be set as the starting
5444 position which will force them to be applied directly after
5445 the pap and chps.
5446 */
5447 if (m_pPcd && ((p->nStartPos > m_pPcd->nStartPos) ||
5448 (m_pPcd->nStartPos == WW8_CP_MAX)) &&
5449 (m_pPcd->nEndPos != p->nStartPos))
5450 {
5451 m_pPcd->nEndPos = p->nStartPos;
5452 static_cast<WW8PLCFx_PCD *>(m_pPcd->pPLCFx)->SetClipStart(
5453 p->nStartPos);
5454 }
5455
5456 }
5457 else
5458 {
5459 p->pPLCFx->advance(); // next Group of Sprms
5460 p->pMemPos = nullptr; // !!!
5461 p->nSprmsLen = 0;
5462 GetNewSprms( *p );
5463 }
5464 SAL_WARN_IF(p->nStartPos > p->nEndPos, "sw.ww8",
5465 "End " << p->nEndPos << " before Start " << p->nStartPos);
5466 }
5467 }
5468}
5469
5470void WW8PLCFMan::AdvNoSprm(short nIdx, bool bStart)
5471{
5472 /*
5473 For the case of a piece table we slave the piece table attribute iterator
5474 to the piece table and access it through that only. They are two separate
5475 structures, but act together as one logical one. The attributes only go
5476 to the next entry when the piece changes
5477 */
5478 WW8PLCFxDesc* p = &m_aD[nIdx];
5479
5480 if( p == m_pPcd )
5481 {
5482 AdvSprm(nIdx+1,bStart);
5483 if( bStart )
5484 p->nStartPos = m_aD[nIdx+1].nStartPos;
5485 else
5486 {
5487 if (m_aD[nIdx+1].xIdStack->empty())
5488 {
5489 WW8PLCFx_PCD *pTemp = static_cast<WW8PLCFx_PCD*>(m_pPcd->pPLCFx);
5490 /*
5491 #i2325#
5492 As per normal, go on to the next set of properties, i.e. we
5493 have traversed over to the next piece. With a clipstart set
5494 we are being told to reread the current piece sprms so as to
5495 reapply them to a new chp or pap range.
5496 */
5497 if (pTemp->GetClipStart() == -1)
5498 p->pPLCFx->advance();
5499 p->pMemPos = nullptr;
5500 p->nSprmsLen = 0;
5501 GetNewSprms( m_aD[nIdx+1] );
5502 GetNewNoSprms( *p );
5503 if (pTemp->GetClipStart() != -1)
5504 {
5505 /*
5506 #i2325#, now we will force our starting position to the
5507 clipping start so as to force the application of these
5508 sprms after the current pap/chp sprms so as to apply the
5509 fastsave sprms to the current range.
5510 */
5511 p->nStartPos = pTemp->GetClipStart();
5512 pTemp->SetClipStart(-1);
5513 }
5514 }
5515 }
5516 }
5517 else
5518 { // NoSprm without end
5519 p->pPLCFx->advance();
5520 p->pMemPos = nullptr; // MemPos invalid
5521 p->nSprmsLen = 0;
5522 GetNewNoSprms( *p );
5523 }
5524}
5525
5527{
5528 bool bStart;
5529 const sal_uInt16 nIdx = WhereIdx(&bStart);
5530 if (nIdx < m_nPLCF)
5531 {
5532 WW8PLCFxDesc* p = &m_aD[nIdx];
5533
5534 p->bFirstSprm = true; // Default
5535
5536 if( p->pPLCFx->IsSprm() )
5537 AdvSprm( nIdx, bStart );
5538 else // NoSprm
5539 AdvNoSprm( nIdx, bStart );
5540 }
5541}
5542
5543// return true for the beginning of an attribute or error,
5544// false for the end of an attribute
5545// remaining return values are delivered to the caller from WW8PclxManResults.
5547{
5548 memset( pRes, 0, sizeof( WW8PLCFManResult ) );
5549 bool bStart;
5550 const sal_uInt16 nIdx = WhereIdx(&bStart);
5551
5552 if( nIdx >= m_nPLCF )
5553 {
5554 OSL_ENSURE( false, "Position not found" );
5555 return true;
5556 }
5557
5558 if( m_aD[nIdx].pPLCFx->IsSprm() )
5559 {
5560 if( bStart )
5561 {
5562 GetSprmStart( nIdx, pRes );
5563 return true;
5564 }
5565 else
5566 {
5567 GetSprmEnd( nIdx, pRes );
5568 return false;
5569 }
5570 }
5571 else
5572 {
5573 if( bStart )
5574 {
5575 GetNoSprmStart( nIdx, pRes );
5576 return true;
5577 }
5578 else
5579 {
5580 GetNoSprmEnd( nIdx, pRes );
5581 return false;
5582 }
5583 }
5584}
5585
5586sal_uInt16 WW8PLCFMan::GetColl() const
5587{
5588 if( m_pPap->pPLCFx )
5589 return m_pPap->pPLCFx->GetIstd();
5590 else
5591 {
5592 OSL_ENSURE( false, "GetColl without PLCF_Pap" );
5593 return 0;
5594 }
5595}
5596
5598{
5599 return static_cast<WW8PLCFx_FLD*>(m_pField->pPLCFx);
5600}
5601
5603{
5604 return static_cast<WW8PLCFx_Cp_FKP*>(m_pPap->pPLCFx)->HasSprm( nId );
5605}
5606
5608{
5609 return static_cast<WW8PLCFx_Cp_FKP*>(m_pChp->pPLCFx)->HasSprm( nId );
5610}
5611
5612void WW8PLCFMan::HasCharSprm(sal_uInt16 nId,
5613 std::vector<SprmResult> &rResult) const
5614{
5615 static_cast<WW8PLCFx_Cp_FKP*>(m_pChp->pPLCFx)->HasSprm(nId, rResult);
5616}
5617
5618void WW8PLCFx::Save( WW8PLCFxSave1& rSave ) const
5619{
5620 rSave.nPLCFxPos = GetIdx();
5621 rSave.nPLCFxPos2 = GetIdx2();
5622 rSave.nPLCFxMemOfs = 0;
5623 rSave.nStartFC = GetStartFc();
5624}
5625
5627{
5628 SetIdx( rSave.nPLCFxPos );
5629 SetIdx2( rSave.nPLCFxPos2 );
5630 SetStartFc( rSave.nStartFC );
5631}
5632
5634{
5635 return GetPCDIdx();
5636}
5637
5638void WW8PLCFx_Cp_FKP::SetIdx2(sal_uInt32 nIdx)
5639{
5640 if( m_pPcd )
5641 m_pPcd->SetIdx( nIdx );
5642}
5643
5645{
5646 if (m_pFkp)
5648 WW8PLCFx::Save( rSave );
5649
5650 rSave.nAttrStart = m_nAttrStart;
5651 rSave.nAttrEnd = m_nAttrEnd;
5652 rSave.bLineEnd = m_bLineEnd;
5653}
5654
5656{
5657 WW8PLCFx::Restore( rSave );
5658
5659 m_nAttrStart = rSave.nAttrStart;
5660 m_nAttrEnd = rSave.nAttrEnd;
5661 m_bLineEnd = rSave.bLineEnd;
5662
5663 if (m_pFkp)
5665}
5666
5668{
5669 if( !pPLCFx )
5670 return;
5671
5672 pPLCFx->Save( rSave );
5673 if( !pPLCFx->IsSprm() )
5674 return;
5675
5676 WW8PLCFxDesc aD;
5678 aD.nCpOfs = rSave.nCpOfs = nCpOfs;
5679 if (!(pPLCFx->SeekPos(aD.nStartPos)))
5680 {
5681 aD.nEndPos = WW8_CP_MAX;
5682 pPLCFx->SetDirty(true);
5683 }
5684 pPLCFx->GetSprms(&aD);
5685 pPLCFx->SetDirty(false);
5686 aD.ReduceByOffset();
5687 rSave.nStartCp = aD.nStartPos;
5689}
5690
5692{
5693 if( !pPLCFx )
5694 return;
5695
5696 pPLCFx->Restore( rSave );
5697 if( !pPLCFx->IsSprm() )
5698 return;
5699
5700 WW8PLCFxDesc aD;
5701 aD.nStartPos = rSave.nStartCp+rSave.nCpOfs;
5702 nCpOfs = aD.nCpOfs = rSave.nCpOfs;
5703 if (!(pPLCFx->SeekPos(aD.nStartPos)))
5704 {
5705 aD.nEndPos = WW8_CP_MAX;
5706 pPLCFx->SetDirty(true);
5707 }
5708 pPLCFx->GetSprms(&aD);
5709 pPLCFx->SetDirty(false);
5710 aD.ReduceByOffset();
5711
5712 if (nOrigSprmsLen > aD.nSprmsLen)
5713 {
5714 //two entries exist for the same offset, cut and run
5715 SAL_WARN("sw.ww8", "restored properties don't match saved properties, bailing out");
5716 nSprmsLen = 0;
5717 pMemPos = nullptr;
5718 }
5719 else
5720 {
5722 pMemPos = aD.pMemPos == nullptr ? nullptr : aD.pMemPos + rSave.nPLCFxMemOfs;
5723 }
5724}
5725
5726namespace
5727{
5728 sal_uInt32 Readcb(SvStream& rSt, ww::WordVersion eVer)
5729 {
5730 if (eVer <= ww::eWW2)
5731 {
5732 sal_uInt16 nShort(0);
5733 rSt.ReadUInt16(nShort);
5734 return nShort;
5735 }
5736 else
5737 {
5738 sal_uInt32 nLong(0);
5739 rSt.ReadUInt32(nLong);
5740 return nLong;
5741 }
5742 }
5743}
5744
5745bool WW8Fib::GetBaseCp(ManTypes nType, WW8_CP * cp) const
5746{
5747 assert(cp != nullptr);
5748 WW8_CP nOffset = 0;
5749
5750 switch (nType)
5751 {
5752 case MAN_TXBX_HDFT:
5753 if (m_ccpTxbx < 0) {
5754 return false;
5755 }
5756 nOffset = m_ccpTxbx;
5757 [[fallthrough]];
5758 case MAN_TXBX:
5759 if (m_ccpEdn < 0 || m_ccpEdn > std::numeric_limits<WW8_CP>::max() - nOffset) {
5760 return false;
5761 }
5762 nOffset += m_ccpEdn;
5763 [[fallthrough]];
5764 case MAN_EDN:
5765 if (m_ccpAtn < 0 || m_ccpAtn > std::numeric_limits<WW8_CP>::max() - nOffset) {
5766 return false;
5767 }
5768 nOffset += m_ccpAtn;
5769 [[fallthrough]];
5770 case MAN_AND:
5771 if (m_ccpMcr < 0 || m_ccpMcr > std::numeric_limits<WW8_CP>::max() - nOffset) {
5772 return false;
5773 }
5774 nOffset += m_ccpMcr;
5775 /*
5776 // fall through
5777
5778 A subdocument of this kind (MAN_MACRO) probably exists in some defunct
5779 version of MSWord, but now ccpMcr is always 0. If some example that
5780 uses this comes to light, this is the likely calculation required
5781
5782 case MAN_MACRO:
5783 */
5784 if (m_ccpHdr < 0 || m_ccpHdr > std::numeric_limits<WW8_CP>::max() - nOffset) {
5785 return false;
5786 }
5787 nOffset += m_ccpHdr;
5788 [[fallthrough]];
5789 case MAN_HDFT:
5790 if (m_ccpFootnote < 0 || m_ccpFootnote > std::numeric_limits<WW8_CP>::max() - nOffset) {
5791 return false;
5792 }
5793 nOffset += m_ccpFootnote;
5794 [[fallthrough]];
5795 case MAN_FTN:
5796 if (m_ccpText < 0 || m_ccpText > std::numeric_limits<WW8_CP>::max() - nOffset) {
5797 return false;
5798 }
5799 nOffset += m_ccpText;
5800 [[fallthrough]];
5801 case MAN_MAINTEXT:
5802 break;
5803 }
5804 *cp = nOffset;
5805 return true;
5806}
5807
5809{
5811 /*
5812 * Word for Windows 2 I think (1.X might work too if anyone has an example.
5813 *
5814 * 0xA59B for Word 1 for Windows
5815 * 0xA59C for Word 1 for OS/2 "PM Word"
5816 *
5817 * Various pages claim that the fileformats of Word 1 and 2 for Windows are
5818 * equivalent to Word for Macintosh 4 and 5. On the other hand
5819 *
5820 * wIdents for Word for Mac versions...
5821 * 0xFE32 for Word 1
5822 * 0xFE34 for Word 3
5823 * 0xFE37 for Word 4 et 5.
5824 *
5825 * and this document
5826 * http://cmsdoc.cern.ch/documents/docformat/CMS_CERN_LetterHead.word is
5827 * claimed to be "Word 5 for Mac" by Office etc and has that wIdent, but
5828 * its format isn't the same as that of Word 2 for windows. Nor is it
5829 * the same as that of Word for DOS/PCWord 5
5830 */
5831 if (m_wIdent == 0xa59b || m_wIdent == 0xa59c)
5832 eVer = ww::eWW1;
5833 else if (m_wIdent == 0xa5db)
5834 eVer = ww::eWW2;
5835 else
5836 {
5837 switch (m_nVersion)
5838 {
5839 case 6:
5840 eVer = ww::eWW6;
5841 break;
5842 case 7:
5843 eVer = ww::eWW7;
5844 break;
5845 case 8:
5846 eVer = ww::eWW8;
5847 break;
5848 }
5849 }
5850 return eVer;
5851}
5852
5853WW8Fib::WW8Fib(SvStream& rSt, sal_uInt8 nWantedVersion, sal_uInt32 nOffset):
5854 m_fDot(false), m_fGlsy(false), m_fComplex(false), m_fHasPic(false), m_cQuickSaves(0),
5855 m_fEncrypted(false), m_fWhichTableStm(false), m_fReadOnlyRecommended(false),
5856 m_fWriteReservation(false), m_fExtChar(false), m_fFarEast(false), m_fObfuscated(false),
5857 m_fMac(false), m_fEmptySpecial(false), m_fLoadOverridePage(false), m_fFuturesavedUndo(false),
5858 m_fWord97Saved(false), m_fWord2000Saved(false)
5859 // in C++20 with P06831R1 "Default member initializers for bit-fields (revision 1)", the
5860 // above bit-field member initializations can be moved to the class definition
5861{
5862 // See [MS-DOC] 2.5.15 "How to read the FIB".
5863 rSt.Seek( nOffset );
5864 /*
5865 note desired number, identify file version number
5866 and check against desired number!
5867 */
5868 m_nVersion = nWantedVersion;
5869 rSt.ReadUInt16( m_wIdent );
5870 rSt.ReadUInt16( m_nFib );
5871 rSt.ReadUInt16( m_nProduct );
5872 if( ERRCODE_NONE != rSt.GetError() )
5873 {
5874 sal_Int16 nFibMin;
5875 sal_Int16 nFibMax;
5876 // note: 6 stands for "6 OR 7", 7 stands for "ONLY 7"
5877 switch( m_nVersion )
5878 {
5879 case 6:
5880 nFibMin = 0x0065; // from 101 WinWord 6.0
5881 // 102 "
5882 // and 103 WinWord 6.0 for Macintosh
5883 // 104 "
5884 nFibMax = 0x0069; // to 105 WinWord 95
5885 break;
5886 case 7:
5887 nFibMin = 0x0069; // from 105 WinWord 95
5888 nFibMax = 0x0069; // to 105 WinWord 95
5889 break;
5890 case 8:
5891 nFibMin = 0x006A; // from 106 WinWord 97
5892 nFibMax = 0x00c1; // to 193 WinWord 97 (?)
5893 break;
5894 default:
5895 nFibMin = 0; // program error!
5896 nFibMax = 0;
5897 m_nFib = 1;
5898 OSL_ENSURE( false, "nVersion not implemented!" );
5899 break;
5900 }
5901 if ( (m_nFib < nFibMin) || (m_nFib > nFibMax) )
5902 {
5903 m_nFibError = ERR_SWG_READ_ERROR; // report error
5904 return;
5905 }
5906 }
5907
5909
5910 // helper vars for Ver67:
5911 sal_Int16 pnChpFirst_Ver67=0;
5912 sal_Int16 pnPapFirst_Ver67=0;
5913 sal_Int16 cpnBteChp_Ver67=0;
5914 sal_Int16 cpnBtePap_Ver67=0;
5915
5916 // read FIB
5917 sal_uInt16 nTmpLid = 0;
5918 rSt.ReadUInt16(nTmpLid);
5919 m_lid = LanguageType(nTmpLid);
5920 rSt.ReadInt16( m_pnNext );
5921 sal_uInt8 aBits1(0);
5922 rSt.ReadUChar( aBits1 );
5923 sal_uInt8 aBits2(0);
5924 rSt.ReadUChar( aBits2 );
5925 rSt.ReadUInt16( m_nFibBack );
5926 rSt.ReadUInt16( m_nHash );
5927 rSt.ReadUInt16( m_nKey );
5928 rSt.ReadUChar( m_envr );
5929 sal_uInt8 aVer8Bits1(0); // only used starting with WinWord 8
5930 rSt.ReadUChar( aVer8Bits1 ); // only have an empty reserve field under Ver67
5931 // content from aVer8Bits1
5932
5933 // sal_uInt8 fMac :1;
5934 // sal_uInt8 fEmptySpecial :1;
5935 // sal_uInt8 fLoadOverridePage :1;
5936 // sal_uInt8 fFuturesavedUndo :1;
5937 // sal_uInt8 fWord97Saved :1;
5938 // sal_uInt8 :3;
5939 rSt.ReadUInt16( m_chse );
5940 rSt.ReadUInt16( m_chseTables );
5941 rSt.ReadInt32( m_fcMin );
5942 rSt.ReadInt32( m_fcMac );
5943
5944// insertion for WW8
5945 if (IsEightPlus(eVer))
5946 {
5947 rSt.ReadUInt16( m_csw );
5948
5949 // Marke: "rgsw" Beginning of the array of shorts
5954 rSt.SeekRel( 9 * sizeof( sal_Int16 ) );
5955
5956 /*
5957 // these are the 9 unused fields:
5958 && (bVer67 || WW8ReadINT16( rSt, pnFbpChpFirst_W6 )) // 1
5959 && (bVer67 || WW8ReadINT16( rSt, pnChpFirst_W6 )) // 2
5960 && (bVer67 || WW8ReadINT16( rSt, cpnBteChp_W6 )) // 3
5961 && (bVer67 || WW8ReadINT16( rSt, pnFbpPapFirst_W6 )) // 4
5962 && (bVer67 || WW8ReadINT16( rSt, pnPapFirst_W6 )) // 5
5963 && (bVer67 || WW8ReadINT16( rSt, cpnBtePap_W6 )) // 6
5964 && (bVer67 || WW8ReadINT16( rSt, pnFbpLvcFirst_W6 )) // 7
5965 && (bVer67 || WW8ReadINT16( rSt, pnLvcFirst_W6 )) // 8
5966 && (bVer67 || WW8ReadINT16( rSt, cpnBteLvc_W6 )) // 9
5967 */
5968 sal_uInt16 nTmpFE = 0;
5969 rSt.ReadUInt16(nTmpFE);
5970 m_lidFE = LanguageType(nTmpFE);
5971 rSt.ReadUInt16( m_clw );
5972 }
5973
5974// end of the insertion for WW8
5975
5976 // Marke: "rglw" Beginning of the array of longs
5977 rSt.ReadInt32( m_cbMac );
5978
5979 // ignore 2 longs, because they are unimportant
5980 rSt.SeekRel( 2 * sizeof( sal_Int32) );
5981
5982 // skipping 2 more longs only at Ver67
5983 if (IsSevenMinus(eVer))
5984 rSt.SeekRel( 2 * sizeof( sal_Int32) );
5985
5986 rSt.ReadInt32( m_ccpText );
5987 rSt.ReadInt32( m_ccpFootnote );
5988 rSt.ReadInt32( m_ccpHdr );
5989 rSt.ReadInt32( m_ccpMcr );
5990 rSt.ReadInt32( m_ccpAtn );
5991 rSt.ReadInt32( m_ccpEdn );
5992 rSt.ReadInt32( m_ccpTxbx );
5993 rSt.ReadInt32( m_ccpHdrTxbx );
5994
5995 // only skip one more long at Ver67
5996 if (IsSevenMinus(eVer))
5997 rSt.SeekRel( 1 * sizeof( sal_Int32) );
5998 else
5999 {
6000// insertion for WW8
6002 rSt.ReadInt32( m_pnChpFirst );
6003 rSt.ReadInt32( m_cpnBteChp );
6005 rSt.ReadInt32( m_pnPapFirst );
6006 rSt.ReadInt32( m_cpnBtePap );
6008 rSt.ReadInt32( m_pnLvcFirst );
6009 rSt.ReadInt32( m_cpnBteLvc );
6011 rSt.ReadInt32( m_fcIslandLim );
6012 rSt.ReadUInt16( m_cfclcb );
6013
6014 // Read cswNew to find out if nFib should be ignored.
6015 sal_uInt32 nPos = rSt.Tell();
6016 rSt.SeekRel(m_cfclcb * 8);
6017 if (rSt.good() && rSt.remainingSize() >= 2)
6018 {
6019 rSt.ReadUInt16(m_cswNew);
6020 }
6021 rSt.Seek(nPos);
6022 }
6023
6024// end of the insertion for WW8
6025
6026 // Marke: "rgfclcb" Beginning of array of FC/LCB pairs.
6027 rSt.ReadInt32( m_fcStshfOrig );
6028 m_lcbStshfOrig = Readcb(rSt, eVer);
6029 rSt.ReadInt32( m_fcStshf );
6030 m_lcbStshf = Readcb(rSt, eVer);
6032 m_lcbPlcffndRef = Readcb(rSt, eVer);
6034 m_lcbPlcffndText = Readcb(rSt, eVer);
6036 m_lcbPlcfandRef = Readcb(rSt, eVer);
6038 m_lcbPlcfandText = Readcb(rSt, eVer);
6039 rSt.ReadInt32( m_fcPlcfsed );
6040 m_lcbPlcfsed = Readcb(rSt, eVer);
6041 rSt.ReadInt32( m_fcPlcfpad );
6042 m_lcbPlcfpad = Readcb(rSt, eVer);
6043 rSt.ReadInt32( m_fcPlcfphe );
6044 m_lcbPlcfphe = Readcb(rSt, eVer);
6045 rSt.ReadInt32( m_fcSttbfglsy );
6046 m_lcbSttbfglsy = Readcb(rSt, eVer);
6047 rSt.ReadInt32( m_fcPlcfglsy );
6048 m_lcbPlcfglsy = Readcb(rSt, eVer);
6049 rSt.ReadInt32( m_fcPlcfhdd );
6050 m_lcbPlcfhdd = Readcb(rSt, eVer);
6052 m_lcbPlcfbteChpx = Readcb(rSt, eVer);
6054 m_lcbPlcfbtePapx = Readcb(rSt, eVer);
6055 rSt.ReadInt32( m_fcPlcfsea );
6056 m_lcbPlcfsea = Readcb(rSt, eVer);
6057 rSt.ReadInt32( m_fcSttbfffn );
6058 m_lcbSttbfffn = Readcb(rSt, eVer);
6060 m_lcbPlcffldMom = Readcb(rSt, eVer);
6062 m_lcbPlcffldHdr = Readcb(rSt, eVer);
6064 m_lcbPlcffldFootnote = Readcb(rSt, eVer);
6066 m_lcbPlcffldAtn = Readcb(rSt, eVer);
6068 m_lcbPlcffldMcr = Readcb(rSt, eVer);
6069 rSt.ReadInt32( m_fcSttbfbkmk );
6070 m_lcbSttbfbkmk = Readcb(rSt, eVer);
6071 rSt.ReadInt32( m_fcPlcfbkf );
6072 m_lcbPlcfbkf = Readcb(rSt, eVer);
6073 rSt.ReadInt32( m_fcPlcfbkl );
6074 m_lcbPlcfbkl = Readcb(rSt, eVer);
6075 rSt.ReadInt32( m_fcCmds );
6076 m_lcbCmds = Readcb(rSt, eVer);
6077 rSt.ReadInt32( m_fcPlcfmcr );
6078 m_lcbPlcfmcr = Readcb(rSt, eVer);
6079 rSt.ReadInt32( m_fcSttbfmcr );
6080 m_lcbSttbfmcr = Readcb(rSt, eVer);
6081 if (eVer >= ww::eWW2)
6082 {
6083 rSt.ReadInt32( m_fcPrDrvr );
6084 m_lcbPrDrvr = Readcb(rSt, eVer);
6085 rSt.ReadInt32( m_fcPrEnvPort );
6086 m_lcbPrEnvPort = Readcb(rSt, eVer);
6087 rSt.ReadInt32( m_fcPrEnvLand );
6088 m_lcbPrEnvLand = Readcb(rSt, eVer);
6089 }
6090 else
6091 {
6092 rSt.ReadInt32( m_fcPrEnvPort );
6093 m_lcbPrEnvPort = Readcb(rSt, eVer);
6094 }
6095 rSt.ReadInt32( m_fcWss );
6096 m_lcbWss = Readcb(rSt, eVer);
6097 rSt.ReadInt32( m_fcDop );
6098 m_lcbDop = Readcb(rSt, eVer);
6100 m_lcbSttbfAssoc = Readcb(rSt, eVer);
6101 rSt.ReadInt32( m_fcClx );
6102 m_lcbClx = Readcb(rSt, eVer);
6104 m_lcbPlcfpgdFootnote = Readcb(rSt, eVer);
6106 m_lcbAutosaveSource = Readcb(rSt, eVer);
6108 m_lcbGrpStAtnOwners = Readcb(rSt, eVer);
6110 m_lcbSttbfAtnbkmk = Readcb(rSt, eVer);
6111
6112 // only skip more shot at Ver67
6113 if (IsSevenMinus(eVer))
6114 {
6115 if (eVer == ww::eWW1)
6116 rSt.SeekRel(1*sizeof(sal_Int32));
6117 rSt.SeekRel(1*sizeof(sal_Int16));
6118
6119 if (eVer >= ww::eWW2)
6120 {
6121 rSt.ReadInt16(pnChpFirst_Ver67);
6122 rSt.ReadInt16(pnPapFirst_Ver67);
6123 }
6124 rSt.ReadInt16(cpnBteChp_Ver67);
6125 rSt.ReadInt16(cpnBtePap_Ver67);
6126 }
6127
6128 if (eVer > ww::eWW2)
6129 {
6138
6143 rSt.ReadInt32( m_fcPms );
6144 rSt.ReadInt32( m_lcbPMS );
6155 rSt.ReadInt32( m_fcDggInfo );
6156 rSt.ReadInt32( m_lcbDggInfo );
6163 rSt.ReadInt32( m_fcPlcfwkb );
6164 rSt.ReadInt32( m_lcbPlcfwkb );
6165 rSt.ReadInt32( m_fcPlcfspl );
6166 rSt.ReadInt32( m_lcbPlcfspl );
6175 rSt.ReadInt32( m_fcStwUser );
6176 rSt.ReadUInt32( m_lcbStwUser );
6177 rSt.ReadInt32( m_fcSttbttmbd );
6179 }
6180
6181 if( ERRCODE_NONE == rSt.GetError() )
6182 {
6183 // set bit flag
6184 m_fDot = aBits1 & 0x01 ;
6185 m_fGlsy = ( aBits1 & 0x02 ) >> 1;
6186 m_fComplex = ( aBits1 & 0x04 ) >> 2;
6187 m_fHasPic = ( aBits1 & 0x08 ) >> 3;
6188 m_cQuickSaves = ( aBits1 & 0xf0 ) >> 4;
6189 m_fEncrypted = aBits2 & 0x01 ;
6190 m_fWhichTableStm= ( aBits2 & 0x02 ) >> 1;
6191 m_fReadOnlyRecommended = (aBits2 & 0x4) >> 2;
6192 m_fWriteReservation = (aBits2 & 0x8) >> 3;
6193 m_fExtChar = ( aBits2 & 0x10 ) >> 4;
6194 // dummy = ( aBits2 & 0x20 ) >> 5;
6195 m_fFarEast = ( aBits2 & 0x40 ) >> 6; // #i90932#
6196 // dummy = ( aBits2 & 0x80 ) >> 7;
6197
6198 /*
6199 p.r.n. fill targeted variable with xxx_Ver67
6200 or set flags
6201 */
6202 if (IsSevenMinus(eVer))
6203 {
6204 m_pnChpFirst = pnChpFirst_Ver67;
6205 m_pnPapFirst = pnPapFirst_Ver67;
6206 m_cpnBteChp = cpnBteChp_Ver67;
6207 m_cpnBtePap = cpnBtePap_Ver67;
6208 }
6209 else if (IsEightPlus(eVer))
6210 {
6211 m_fMac = aVer8Bits1 & 0x01 ;
6212 m_fEmptySpecial = ( aVer8Bits1 & 0x02 ) >> 1;
6213 m_fLoadOverridePage = ( aVer8Bits1 & 0x04 ) >> 2;
6214 m_fFuturesavedUndo = ( aVer8Bits1 & 0x08 ) >> 3;
6215 m_fWord97Saved = ( aVer8Bits1 & 0x10 ) >> 4;
6216 m_fWord2000Saved = ( aVer8Bits1 & 0x20 ) >> 5;
6217
6218 /*
6219 especially for WW8:
6220 identify the values for PLCF and PLF LFO
6221 and PLCF for the textbox break descriptors
6222 */
6223 sal_uInt64 nOldPos = rSt.Tell();
6224
6225 rSt.Seek( 0x02da );
6226 rSt.ReadInt32( m_fcSttbFnm );
6227 rSt.ReadInt32( m_lcbSttbFnm );
6228 rSt.ReadInt32( m_fcPlcfLst );
6229 rSt.ReadInt32( m_lcbPlcfLst );
6230 rSt.ReadInt32( m_fcPlfLfo );
6231 rSt.ReadInt32( m_lcbPlfLfo );
6236 if( ERRCODE_NONE != rSt.GetError() )
6237 {
6239 }
6240
6241 rSt.Seek( 0x372 ); // fcSttbListNames
6244
6245 if (m_cfclcb > 93)
6246 {
6247 rSt.Seek( 0x382 ); // MagicTables
6248 rSt.ReadInt32( m_fcPlcfTch );
6249 rSt.ReadInt32( m_lcbPlcfTch );
6250 }
6251
6252 if (m_cfclcb > 113)
6253 {
6254 rSt.Seek( 0x41A ); // new ATRD
6255 rSt.ReadInt32( m_fcAtrdExtra );
6257 }
6258
6259 // Factoid bookmarks
6260 if (m_cfclcb > 134)
6261 {
6262 rSt.Seek(0x432);
6265
6266 rSt.Seek(0x442);
6269
6270 rSt.Seek(0x44a);
6273 }
6274
6275 if( ERRCODE_NONE != rSt.GetError() )
6277
6278 rSt.Seek( 0x5bc ); // Actual nFib introduced in Word 2003
6280
6281 rSt.Seek( nOldPos );
6282 }
6283 }
6284 else
6285 {
6286 m_nFibError = ERR_SWG_READ_ERROR; // report error
6287 }
6288}
6289
6290WW8Fib::WW8Fib(sal_uInt8 nVer, bool bDot):
6291 m_nVersion(nVer), m_fDot(false), m_fGlsy(false), m_fComplex(false), m_fHasPic(false), m_cQuickSaves(0),
6292 m_fEncrypted(false), m_fWhichTableStm(false), m_fReadOnlyRecommended(false),
6293 m_fWriteReservation(false), m_fExtChar(false), m_fFarEast(false), m_fObfuscated(false),
6294 m_fMac(false), m_fEmptySpecial(false), m_fLoadOverridePage(false), m_fFuturesavedUndo(false),
6295 m_fWord97Saved(false), m_fWord2000Saved(false)
6296 // in C++20 with P06831R1 "Default member initializers for bit-fields (revision 1)", the
6297 // above bit-field member initializations can be moved to the class definition
6298{
6299 if (8 == nVer)
6300 {
6301 m_fcMin = 0x800;
6302 m_wIdent = 0xa5ec;
6303 m_nFib = 0x0101;
6304 m_nFibBack = 0xbf;
6305 m_nProduct = 0x204D;
6306 m_fDot = bDot;
6307
6308 m_csw = 0x0e; // Is this really necessary???
6309 m_cfclcb = 0x88; // -""-
6310 m_clw = 0x16; // -""-
6312 m_fExtChar = true;
6314
6315 // Just a fancy way to write 'Caolan80'.
6316 m_wMagicCreated = 0x6143;
6317 m_wMagicRevised = 0x6C6F;
6318 m_wMagicCreatedPrivate = 0x6E61;
6319 m_wMagicRevisedPrivate = 0x3038;
6320 }
6321 else
6322 {
6323 m_fcMin = 0x300;
6324 m_wIdent = 0xa5dc;
6325 m_nFib = m_nFibBack = 0x65;
6326 m_nProduct = 0xc02d;
6327 }
6328
6329 //If nFib is 0x00D9 or greater, then cQuickSaves MUST be 0xF
6330 m_cQuickSaves = m_nFib >= 0x00D9 ? 0xF : 0;
6331
6332 // --> #i90932#
6333 m_lid = LanguageType(0x409); // LANGUAGE_ENGLISH_US
6334
6337 if (m_fFarEast)
6338 m_lidFE = nLang;
6339 else
6340 m_lidFE = m_lid;
6341
6342 LanguageTag aLanguageTag( m_lid );
6343 LocaleDataWrapper aLocaleWrapper( std::move(aLanguageTag) );
6344 m_nNumDecimalSep = aLocaleWrapper.getNumDecimalSep()[0];
6345}
6346
6347
6349{
6350 bool bVer8 = 8 == m_nVersion;
6351
6352 size_t nUnencryptedHdr = bVer8 ? 0x44 : 0x24;
6353 std::unique_ptr<sal_uInt8[]> pDataPtr( new sal_uInt8[ nUnencryptedHdr ] );
6354 sal_uInt8 *pData = pDataPtr.get();
6355 memset( pData, 0, nUnencryptedHdr );
6356
6357 m_cbMac = rStrm.TellEnd();
6358
6362 Set_UInt16( pData, static_cast<sal_uInt16>(m_lid) );
6364
6365 sal_uInt16 nBits16 = 0;
6366 if( m_fDot ) nBits16 |= 0x0001;
6367 if( m_fGlsy) nBits16 |= 0x0002;
6368 if( m_fComplex ) nBits16 |= 0x0004;
6369 if( m_fHasPic ) nBits16 |= 0x0008;
6370 nBits16 |= (0xf0 & ( m_cQuickSaves << 4 ));
6371 if( m_fEncrypted ) nBits16 |= 0x0100;
6372 if( m_fWhichTableStm ) nBits16 |= 0x0200;
6373
6375 nBits16 |= 0x0400;
6377 nBits16 |= 0x0800;
6378
6379 if( m_fExtChar ) nBits16 |= 0x1000;
6380 if( m_fFarEast ) nBits16 |= 0x4000; // #i90932#
6381 if( m_fObfuscated ) nBits16 |= 0x8000;
6382 Set_UInt16( pData, nBits16 );
6383
6388
6389 sal_uInt8 nBits8 = 0;
6390 if( bVer8 )
6391 {
6392 if( m_fMac ) nBits8 |= 0x0001;
6393 if( m_fEmptySpecial ) nBits8 |= 0x0002;
6394 if( m_fLoadOverridePage ) nBits8 |= 0x0004;
6395 if( m_fFuturesavedUndo ) nBits8 |= 0x0008;
6396 if( m_fWord97Saved ) nBits8 |= 0x0010;
6397 if( m_fWord2000Saved ) nBits8 |= 0x0020;
6398 }
6399 // under Ver67 these are only reserved
6400 Set_UInt8( pData, nBits8 );
6401
6406
6407// insertion for WW8
6408
6409 // Marke: "rgsw" Beginning of the array of shorts
6410 if( bVer8 )
6411 {
6417 pData += 9 * sizeof( sal_Int16 );
6418 Set_UInt16( pData, static_cast<sal_uInt16>(m_lidFE) );
6420 }
6421
6422// end of the insertion for WW8
6423
6424 // Marke: "rglw" Beginning of the array of longs
6426
6427 rStrm.WriteBytes(pDataPtr.get(), nUnencryptedHdr);
6428}
6429
6431{
6432 bool bVer8 = 8 == m_nVersion;
6433
6434 WriteHeader( rStrm );
6435
6436 size_t nUnencryptedHdr = bVer8 ? 0x44 : 0x24;
6437
6438 std::unique_ptr<sal_uInt8[]> pDataPtr( new sal_uInt8[ m_fcMin - nUnencryptedHdr ] );
6439 sal_uInt8 *pData = pDataPtr.get();
6440 memset( pData, 0, m_fcMin - nUnencryptedHdr );
6441
6442 m_cbMac = rStrm.TellEnd();
6443
6444 // ignore 2 longs, because they are unimportant
6445 pData += 2 * sizeof( sal_Int32);
6446
6447 // skipping 2 more longs only at Ver67
6448 if( !bVer8 )
6449 pData += 2 * sizeof( sal_Int32);
6450
6459
6460 // only skip one more long at Ver67
6461 if( !bVer8 )
6462 pData += 1 * sizeof( sal_Int32);
6463
6464// insertion for WW8
6465 if( bVer8 )
6466 {
6479 }
6480// end of the insertion for WW8
6481
6482 // Marke: "rgfclcb" Beginning of array of FC/LCB pairs.
6559
6560 // only skip one more short at Ver67
6561 if( !bVer8 )
6562 {
6563 pData += 1*sizeof( sal_Int16);
6564 Set_UInt16( pData, o3tl::narrowing<sal_uInt16>(m_pnChpFirst) );
6565 Set_UInt16( pData, o3tl::narrowing<sal_uInt16>(m_pnPapFirst) );
6566 Set_UInt16( pData, o3tl::narrowing<sal_uInt16>(m_cpnBteChp) );
6567 Set_UInt16( pData, o3tl::narrowing<sal_uInt16>(m_cpnBtePap) );
6568 }
6569
6570 Set_UInt32( pData, m_fcPlcfdoaMom ); // only at Ver67, in Ver8 unused
6571 Set_UInt32( pData, m_lcbPlcfdoaMom ); // only at Ver67, in Ver8 unused
6572 Set_UInt32( pData, m_fcPlcfdoaHdr ); // only at Ver67, in Ver8 unused
6573 Set_UInt32( pData, m_lcbPlcfdoaHdr ); // only at Ver67, in Ver8 unused
6574
6575 Set_UInt32( pData, m_fcPlcfspaMom ); // in Ver67 empty reserve
6576 Set_UInt32( pData, m_lcbPlcfspaMom ); // in Ver67 empty reserve
6577 Set_UInt32( pData, m_fcPlcfspaHdr ); // in Ver67 empty reserve
6578 Set_UInt32( pData, m_lcbPlcfspaHdr ); // in Ver67 empty reserve
6579
6596 Set_UInt32( pData, m_fcDggInfo ); // in Ver67 empty reserve
6597 Set_UInt32( pData, m_lcbDggInfo ); // in Ver67 empty reserve
6606 Set_UInt32( pData, m_fcPlcfspl ); // in Ver67 empty reserve
6607 Set_UInt32( pData, m_lcbPlcfspl ); // in Ver67 empty reserve
6616
6617 if( bVer8 )
6618 {
6619 pData += 0x2da - 0x27a; // Pos + Offset (fcPlcfLst - fcStwUser)
6630
6631 pData += 0x372 - 0x302; // Pos + Offset (fcSttbListNames - fcDocUndo)
6634
6635 pData += 0x382 - 0x37A;
6638
6639 pData += 0x3FA - 0x38A;
6640 Set_UInt16( pData, sal_uInt16(0x0002));
6641 Set_UInt16( pData, sal_uInt16(0x00D9));
6642
6643 pData += 0x41A - 0x3FE;
6646
6647 pData += 0x42a - 0x422;
6652
6653 pData += 0x442 - 0x43A;
6658
6659 pData += 0x4BA - 0x452;
6662
6663 pData += 0x4DA - 0x4c2;
6665 Set_UInt32( pData, 0);
6666 }
6667
6668 rStrm.WriteBytes(pDataPtr.get(), m_fcMin - nUnencryptedHdr);
6669}
6670
6671rtl_TextEncoding WW8Fib::GetFIBCharset(sal_uInt16 chs, LanguageType nLidLocale)
6672{
6673 OSL_ENSURE(chs <= 0x100, "overflowed winword charset set");
6674 if (chs == 0x0100)
6675 return RTL_TEXTENCODING_APPLE_ROMAN;
6676 if (chs == 0 && static_cast<sal_uInt16>(nLidLocale) >= 999)
6677 {
6678 /*
6679 nLidLocale:
6680 language stamp -- localized version In pre-WinWord 2.0 files this
6681 value was the nLocale. If value is < 999, then it is the nLocale,
6682 otherwise it is the lid.
6683 */
6684 css::lang::Locale aLocale(LanguageTag::convertToLocale(nLidLocale));
6686 }
6687 return rtl_getTextEncodingFromWindowsCharset(static_cast<sal_uInt8>(chs));
6688}
6689
6691 : m_nId(0)
6692{
6693}
6694
6696{
6697static OUString Read(SvStream& rStream)
6698{
6699 OUString aRet;
6700
6701 sal_uInt16 nBuf(0);
6702 rStream.ReadUInt16(nBuf);
6703 sal_uInt16 nCch = nBuf & 0x7fff; // Bits 1..15.
6704 bool bAnsiString = (nBuf & (1 << 15)) >> 15; // 16th bit.
6705 if (bAnsiString)
6706 aRet = OStringToOUString(read_uInt8s_ToOString(rStream, nCch), RTL_TEXTENCODING_ASCII_US);
6707 else
6708 aRet = read_uInt16s_ToOUString(rStream, nCch);
6709
6710 return aRet;
6711}
6712
6713static void Write(std::u16string_view aString, SvStream& rStream)
6714{
6715 sal_uInt16 nBuf = 0;
6716 nBuf |= sal_Int32(aString.size()); // cch, 0..14th bits.
6717 nBuf |= 0x8000; // fAnsiString, 15th bit.
6718 rStream.WriteUInt16(nBuf);
6719 SwWW8Writer::WriteString8(rStream, aString, false, RTL_TEXTENCODING_ASCII_US);
6720}
6721};
6722
6724{
6725 sal_uInt32 cbFactoid(0);
6726 rStream.ReadUInt32(cbFactoid);
6727 rStream.ReadUInt32(m_nId);
6728 m_aUri = MSOPBString::Read(rStream);
6729 m_aTag = MSOPBString::Read(rStream);
6730 MSOPBString::Read(rStream); // rgbDownloadURL
6731}
6732
6734{
6735 SvStream& rStream = *rExport.m_pTableStrm;
6736
6737 SvMemoryStream aStream;
6738 aStream.WriteUInt32(m_nId); // id
6739 MSOPBString::Write(m_aUri, aStream);
6740 MSOPBString::Write(m_aTag, aStream);
6741 MSOPBString::Write(u"", aStream); // rgbDownloadURL
6742 rStream.WriteUInt32(aStream.Tell());
6743 aStream.Seek(0);
6744 rStream.WriteStream(aStream);
6745}
6746
6748{
6749 sal_uInt32 cFactoidType(0);
6750 rStream.ReadUInt32(cFactoidType);
6751 for (sal_uInt32 i = 0; i < cFactoidType && rStream.good(); ++i)
6752 {
6753 MSOFactoidType aFactoidType;
6754 aFactoidType.Read(rStream);
6755 m_aFactoidTypes.push_back(aFactoidType);
6756 }
6757 sal_uInt16 cbHdr(0);
6758 rStream.ReadUInt16(cbHdr);
6759 SAL_WARN_IF(cbHdr != 0xc, "sw.ww8", "MSOPropertyBagStore::Read: unexpected cbHdr");
6760 sal_uInt16 nVer(0);
6761 rStream.ReadUInt16(nVer);
6762 SAL_WARN_IF(nVer != 0x0100, "sw.ww8", "MSOPropertyBagStore::Read: unexpected nVer");
6763 rStream.SeekRel(4); // cfactoid
6764 sal_uInt32 nCste(0);
6765 rStream.ReadUInt32(nCste);
6766
6767 //each string has a 2 byte len record at the start
6768 const size_t nMaxPossibleRecords = rStream.remainingSize() / sizeof(sal_uInt16);
6769 if (nCste > nMaxPossibleRecords)
6770 {
6771 SAL_WARN("sw.ww8", nCste << " records claimed, but max possible is " << nMaxPossibleRecords);
6772 nCste = nMaxPossibleRecords;
6773 }
6774
6775 for (sal_uInt32 i = 0; i < nCste; ++i)
6776 {
6777 OUString aString = MSOPBString::Read(rStream);
6778 m_aStringTable.push_back(aString);
6779 }
6780}
6781
6783{
6784 SvStream& rStream = *rExport.m_pTableStrm;
6785 rStream.WriteUInt32(m_aFactoidTypes.size()); // cFactoidType
6786 for (MSOFactoidType& rType : m_aFactoidTypes)
6787 rType.Write(rExport);
6788 rStream.WriteUInt16(0xc); // cbHdr
6789 rStream.WriteUInt16(0x0100); // sVer
6790 rStream.WriteUInt32(0); // cfactoid
6791 rStream.WriteUInt32(m_aStringTable.size()); // cste
6792 for (const OUString& rString : m_aStringTable)
6793 MSOPBString::Write(rString, rStream);
6794}
6795
6797 : m_nKey(0)
6798 , m_nValue(0)
6799{
6800}
6801
6803{
6804 rStream.ReadUInt32(m_nKey);
6805 rStream.ReadUInt32(m_nValue);
6806}
6807
6809{
6810 rStream.WriteUInt32(m_nKey);
6811 rStream.WriteUInt32(m_nValue);
6812}
6813
6815 : m_nId(0)
6816{
6817}
6818
6820{
6821 rStream.ReadUInt16(m_nId);
6822 sal_uInt16 cProp(0);
6823 rStream.ReadUInt16(cProp);
6824 if (!rStream.good())
6825 return false;
6826 rStream.SeekRel(2); // cbUnknown
6827 //each MSOProperty is 8 bytes in size
6828 const size_t nMaxPossibleRecords = rStream.remainingSize() / 8;
6829 if (cProp > nMaxPossibleRecords)
6830 {
6831 SAL_WARN("sw.ww8", cProp << " records claimed, but max possible is " << nMaxPossibleRecords);
6832 cProp = nMaxPossibleRecords;
6833 }
6834 for (sal_uInt16 i = 0; i < cProp && rStream.good(); ++i)
6835 {
6836 MSOProperty aProperty;
6837 aProperty.Read(rStream);
6838 m_aProperties.push_back(aProperty);
6839 }
6840 return rStream.good();
6841}
6842
6844{
6845 SvStream& rStream = *rExport.m_pTableStrm;
6846 rStream.WriteUInt16(m_nId);
6847 rStream.WriteUInt16(m_aProperties.size());
6848 rStream.WriteUInt16(0); // cbUnknown
6849 for (MSOProperty& rProperty : m_aProperties)
6850 rProperty.Write(rStream);
6851}
6852
6853void WW8SmartTagData::Read(SvStream& rStream, WW8_FC fcFactoidData, sal_uInt32 lcbFactoidData)
6854{
6855 sal_uInt64 nOldPosition = rStream.Tell();
6856 if (!checkSeek(rStream, fcFactoidData))
6857 return;
6858
6859 m_aPropBagStore.Read(rStream);
6860 while (rStream.good() && rStream.Tell() < fcFactoidData + lcbFactoidData)
6861 {
6862 MSOPropertyBag aPropertyBag;
6863 if (!aPropertyBag.Read(rStream))
6864 break;
6865 m_aPropBags.push_back(aPropertyBag);
6866 }
6867
6868 rStream.Seek(nOldPosition);
6869}
6870
6872{
6873 m_aPropBagStore.Write(rExport);
6874 for (MSOPropertyBag& rPropertyBag : m_aPropBags)
6875 rPropertyBag.Write(rExport);
6876}
6877
6879 : m_rFib(rFibPara), m_rStream(rStream), m_cstd(0), m_cbSTDBaseInFile(0), m_fStdStylenamesWritten(0)
6880 , m_stiMaxWhenSaved(0), m_istdMaxFixedWhenSaved(0), m_nVerBuiltInNamesWhenSaved(0)
6881 , m_ftcAsci(0), m_ftcFE(0), m_ftcOther(0), m_ftcBi(0)
6882{
6884 return;
6885
6886 sal_uInt16 cbStshi = 0; // 2 bytes size of the following STSHI structure
6887 sal_uInt32 nRemaining = m_rFib.m_lcbStshf;
6888 const sal_uInt32 nMinValidStshi = 4;
6889
6890 if (m_rFib.GetFIBVersion() <= ww::eWW2)
6891 {
6892 cbStshi = 0;
6893 m_cstd = 256;
6894 }
6895 else
6896 {
6897 if (m_rFib.m_nFib < 67) // old Version ? (need to find this again to fix)
6898 cbStshi = nMinValidStshi;
6899 else // new version
6900 {
6901 if (nRemaining < sizeof(cbStshi))
6902 return;
6903 // reads the length of the structure in the file
6904 m_rStream.ReadUInt16( cbStshi );
6905 nRemaining-=2;
6906 }
6907 }
6908
6909 cbStshi = std::min(static_cast<sal_uInt32>(cbStshi), nRemaining);
6910 if (cbStshi < nMinValidStshi)
6911 return;
6912
6913 const sal_uInt16 nRead = cbStshi;
6914 do
6915 {
6917
6919
6920 if( 6 > nRead ) break;
6921
6922 sal_uInt16 a16Bit;
6923 m_rStream.ReadUInt16( a16Bit );
6924 m_fStdStylenamesWritten = a16Bit & 0x0001;
6925
6926 if( 8 > nRead ) break;
6928
6929 if( 10 > nRead ) break;
6931
6932 if( 12 > nRead ) break;
6934
6935 if( 14 > nRead ) break;
6937
6938 if( 16 > nRead ) break;
6940
6941 if ( 18 > nRead ) break;
6943
6945
6946 if ( 20 > nRead ) break;
6948
6949 // p.r.n. ignore the rest
6950 if( 20 < nRead )
6951 m_rStream.SeekRel( nRead-20 );
6952 }
6953 while( false ); // trick: the block above will be passed through exactly one time
6954 // and that's why we can early exit with "break".
6955
6956 nRemaining -= cbStshi;
6957
6958 //There will be stshi.cstd (cbSTD, STD) pairs in the file following the
6959 //STSHI. Note that styles can be empty, i.e. cbSTD == 0
6960 const sal_uInt32 nMinRecordSize = sizeof(sal_uInt16);
6961 const sal_uInt16 nMaxPossibleRecords = nRemaining/nMinRecordSize;
6962
6963 OSL_ENSURE(m_cstd <= nMaxPossibleRecords,
6964 "allegedly more styles that available data");
6965 m_cstd = o3tl::sanitizing_min(m_cstd, nMaxPossibleRecords);
6966}
6967
6968// Read1STDFixed() reads a style. If the style is completely existent,
6969// so it has no empty slot, we should allocate memory and a pointer should
6970// reference to STD (perhaps filled with 0). If the slot is empty,
6971// it will return a null pointer.
6972std::unique_ptr<WW8_STD> WW8Style::Read1STDFixed(sal_uInt16& rSkip)
6973{
6974 if (m_rStream.remainingSize() < 2)
6975 {
6976 rSkip = 0;
6977 return nullptr;
6978 }
6979
6980 std::unique_ptr<WW8_STD> pStd;
6981
6982 sal_uInt16 cbStd(0);
6983 m_rStream.ReadUInt16(cbStd); // read length
6984
6985 const sal_uInt16 nRead = m_cbSTDBaseInFile;
6986 if( cbStd >= m_cbSTDBaseInFile )
6987 {
6988 // Fixed part completely available
6989
6990 // read fixed part of STD
6991 pStd.reset(new WW8_STD);
6992 memset( pStd.get(), 0, sizeof( *pStd ) );
6993
6994 do
6995 {
6996 if( 2 > nRead ) break;
6997
6998 sal_uInt16 a16Bit = 0;
6999 m_rStream.ReadUInt16( a16Bit );
7000 pStd->sti = a16Bit & 0x0fff ;
7001 pStd->fScratch = sal_uInt16(0 != ( a16Bit & 0x1000 ));
7002 pStd->fInvalHeight = sal_uInt16(0 != ( a16Bit & 0x2000 ));
7003 pStd->fHasUpe = sal_uInt16(0 != ( a16Bit & 0x4000 ));
7004 pStd->fMassCopy = sal_uInt16(0 != ( a16Bit & 0x8000 ));
7005
7006 if( 4 > nRead ) break;
7007 a16Bit = 0;
7008 m_rStream.ReadUInt16( a16Bit );
7009 pStd->sgc = a16Bit & 0x000f ;
7010 pStd->istdBase = ( a16Bit & 0xfff0 ) >> 4;
7011
7012 if( 6 > nRead ) break;
7013 a16Bit = 0;
7014 m_rStream.ReadUInt16( a16Bit );
7015 pStd->cupx = a16Bit & 0x000f ;
7016 pStd->istdNext = ( a16Bit & 0xfff0 ) >> 4;
7017
7018 if( 8 > nRead ) break;
7019 m_rStream.ReadUInt16( pStd->bchUpe );
7020
7021 // from Ver8 this two fields should be added:
7022 if(10 > nRead ) break;
7023 a16Bit = 0;
7024 m_rStream.ReadUInt16( a16Bit );
7025 pStd->fAutoRedef = a16Bit & 0x0001 ;
7026 pStd->fHidden = ( a16Bit & 0x0002 ) >> 1;
7027 // You never know: cautionary skipped
7028 if (nRead > 10)
7029 {
7030 auto nSkip = std::min<sal_uInt64>(nRead - 10, m_rStream.remainingSize());
7031 m_rStream.Seek(m_rStream.Tell() + nSkip);
7032 }
7033 }
7034 while( false ); // trick: the block above will passed through exactly one time
7035 // and can be left early with a "break"
7036
7037 if (!m_rStream.good() || !nRead)
7038 {
7039 pStd.reset(); // report error with NULL
7040 }
7041
7042 rSkip = cbStd - m_cbSTDBaseInFile;
7043 }
7044 else
7045 { // Fixed part too short
7046 if( cbStd )
7047 m_rStream.SeekRel( cbStd ); // skip leftovers
7048 rSkip = 0;
7049 }
7050 return pStd;
7051}
7052
7053std::unique_ptr<WW8_STD> WW8Style::Read1Style(sal_uInt16& rSkip, OUString* pString)
7054{
7055 // Attention: MacWord-Documents have their Stylenames
7056 // always in ANSI, even if eStructCharSet == CHARSET_MAC !!
7057
7058 std::unique_ptr<WW8_STD> pStd = Read1STDFixed(rSkip); // read STD
7059
7060 // string desired?
7061 if( pString )
7062 { // real style?
7063 if ( pStd )
7064 {
7065 sal_Int32 nLenStringBytes = 0;
7066 switch( m_rFib.m_nVersion )
7067 {
7068 case 6:
7069 case 7:
7070 // read pascal string
7071 *pString = read_uInt8_BeltAndBracesString(m_rStream, RTL_TEXTENCODING_MS_1252);
7072 // leading len and trailing zero --> 2
7073 nLenStringBytes = pString->getLength() + 2;
7074 break;
7075 case 8:
7076 // handle Unicode-String with leading length short and
7077 // trailing zero
7078 if (TestBeltAndBraces(m_rStream))
7079 {
7081 nLenStringBytes = (pString->getLength() + 2) * 2;
7082 }
7083 else
7084 {
7085 /*
7086 #i8114#
7087 This is supposed to be impossible, it's just supposed
7088 to be 16 bit count followed by the string and ending
7089 in a 0 short. But "Lotus SmartSuite Product: Word Pro"
7090 is creating invalid style names in ww7- format. So we
7091 use the belt and braces of the ms strings to see if
7092 they are not corrupt. If they are then we try them as
7093 8bit ones
7094 */
7095 *pString = read_uInt8_BeltAndBracesString(m_rStream,RTL_TEXTENCODING_MS_1252);
7096 // leading len and trailing zero --> 2
7097 nLenStringBytes = pString->getLength() + 2;
7098 }
7099 break;
7100 default:
7101 OSL_ENSURE(false, "It was forgotten to code nVersion!");
7102 break;
7103 }
7104 if (nLenStringBytes > rSkip)
7105 {
7106 SAL_WARN("sw.ww8", "WW8Style structure corrupt");
7107 nLenStringBytes = rSkip;
7108 }
7109 rSkip -= nLenStringBytes;
7110 }
7111 else
7112 pString->clear(); // can not return a name
7113 }
7114 return pStd;
7115}
7116
7117namespace {
7118const sal_uInt16 maxStrSize = 65;
7119
7120struct WW8_FFN_Ver6
7121{
7123 // from Ver6
7124 char szFfn[maxStrSize]; // 0x6 or 0x40 from Ver8 on zero terminated string that
7125 // records name of font.
7126 // Maximal size of szFfn is 65 characters.
7127 // Attention: This array can also be smaller!!!
7128 // Possibly followed by a second sz which records the
7129 // name of an alternate font to use if the first named
7130 // font does not exist on this system.
7131};
7132
7133}
7134
7135// #i43762# check font name for illegal characters
7136static void lcl_checkFontname( OUString& sString )
7137{
7138 // for efficiency, we'd like to use String methods as far as possible.
7139 // Hence, we will:
7140 // 1) convert all invalid chars to \u0001
7141 // 2) then erase all \u0001 chars (if anywhere found), and
7142 // 3) erase leading/trailing ';', in case a font name was
7143 // completely removed
7144
7145 // convert all invalid chars to \u0001
7146 OUStringBuffer aBuf(sString);
7147 const sal_Int32 nLen = aBuf.getLength();
7148 bool bFound = false;
7149 for ( sal_Int32 n = 0; n < nLen; ++n )
7150 {
7151 if ( aBuf[n] < 0x20 )
7152 {
7153 aBuf[n] = 1;
7154 bFound = true;
7155 }
7156 }
7157 sString = aBuf.makeStringAndClear();
7158
7159 // if anything was found, remove \u0001 + leading/trailing ';'
7160 if( bFound )
7161 {
7162 sString = comphelper::string::strip(sString.replaceAll("\001", ""), ';');
7163 }
7164}
7165
7166namespace
7167{
7168 sal_uInt16 calcMaxFonts(sal_uInt8 *p, sal_Int32 nFFn)
7169 {
7170 // Figure out the max number of fonts defined here
7171 sal_uInt16 nMax = 0;
7172 sal_Int32 nRemaining = nFFn;
7173 while (nRemaining)
7174 {
7175 //p[0] is cbFfnM1, the alleged total length of FFN - 1.
7176 //i.e. length after cbFfnM1
7177 const sal_uInt16 cbFfnM1 = *p++;
7178 --nRemaining;
7179
7180 if (cbFfnM1 > nRemaining)
7181 break;
7182
7183 nMax++;
7184 nRemaining -= cbFfnM1;
7185 p += cbFfnM1;
7186 }
7187 return nMax;
7188 }
7189
7190 template<typename T> bool readU8(
7191 sal_uInt8 const * p, std::size_t offset, sal_uInt8 const * pEnd,
7192 T * value)
7193 {
7194 assert(p <= pEnd);
7195 assert(value != nullptr);
7196 if (offset >= o3tl::make_unsigned(pEnd - p)) {
7197 return false;
7198 }
7199 *value = p[offset];
7200 return true;
7201 }
7202
7203 bool readS16(
7204 sal_uInt8 const * p, std::size_t offset, sal_uInt8 const * pEnd,
7205 short * value)
7206 {
7207 assert(p <= pEnd);
7208 assert(value != nullptr);
7209 if (offset > o3tl::make_unsigned(pEnd - p)
7210 || static_cast<std::size_t>(pEnd - p) - offset < 2)
7211 {
7212 return false;
7213 }
7214 *value = unsigned(p[offset]) + (unsigned(p[offset + 1]) << 8);
7215 return true;
7216 }
7217
7218 sal_Int32 getStringLengthWithMax(
7219 sal_uInt8 const * p, std::size_t offset, sal_uInt8 const * pEnd, std::size_t maxchars)
7220 {
7221 assert(p <= pEnd);
7222 assert(pEnd - p <= SAL_MAX_INT32);
7223 if (offset >= o3tl::make_unsigned(pEnd - p)) {
7224 return -1;
7225 }
7226 std::size_t nbytes = static_cast<std::size_t>(pEnd - p) - offset;
7227 std::size_t nsearch = std::min(nbytes, maxchars + 1);
7228 void const * p2 = std::memchr(p + offset, 0, nsearch);
7229 if (p2 == nullptr) {
7230 return -1;
7231 }
7232 return static_cast<sal_uInt8 const *>(p2) - (p + offset);
7233 }
7234}
7235
7237{
7238 // Attention: MacWord-Documents have their Fontnames
7239 // always in ANSI, even if eStructCharSet == CHARSET_MAC !!
7240 if( rFib.m_lcbSttbfffn <= 2 )
7241 {
7242 OSL_ENSURE( false, "font table is broken! (rFib.lcbSttbfffn < 2)" );
7243 return;
7244 }
7245
7246 if (!checkSeek(rSt, rFib.m_fcSttbfffn))
7247 return;
7248
7249 sal_Int32 nFFn = rFib.m_lcbSttbfffn - 2;
7250
7251 const sal_uInt64 nMaxPossible = rSt.remainingSize();
7252 if (o3tl::make_unsigned(nFFn) > nMaxPossible)
7253 {
7254 SAL_WARN("sw.ww8", "FFN structure longer than available data");
7255 nFFn = nMaxPossible;
7256 }
7257
7258 // allocate Font Array
7259 std::vector<sal_uInt8> aA(nFFn);
7260 memset(aA.data(), 0, nFFn);
7261
7262 ww::WordVersion eVersion = rFib.GetFIBVersion();
7263
7264 sal_uInt16 nMax(0);
7265 if( eVersion >= ww::eWW8 )
7266 {
7267 // bVer8: read the count of strings in nMax
7268 rSt.ReadUInt16(nMax);
7269 }
7270
7271 // Ver8: skip undefined uint16
7272 // Ver67: skip the herein stored total byte of structure
7273 // - we already got that information in rFib.lcbSttbfffn
7274 rSt.SeekRel( 2 );
7275
7276 // read all font information
7277 nFFn = rSt.ReadBytes(aA.data(), nFFn);
7278 sal_uInt8 * const pEnd = aA.data() + nFFn;
7279 const sal_uInt16 nCalcMax = calcMaxFonts(aA.data(), nFFn);
7280
7281 if (eVersion < ww::eWW8)
7282 nMax = nCalcMax;
7283 else
7284 {
7285 //newer versions include supportive count of fonts, so take min of that
7286 //and calced max
7287 nMax = std::min(nMax, nCalcMax);
7288 }
7289
7290 if (nMax)
7291 {
7292 // allocate Index Array
7293 m_aFontA.resize(nMax);
7294 WW8_FFN* p = m_aFontA.data();
7295
7296 if( eVersion <= ww::eWW2 )
7297 {
7298 sal_uInt8 const * pVer2 = aA.data();
7299 sal_uInt16 i = 0;
7300 for(; i<nMax; ++i, ++p)
7301 {
7302 if (!readU8(
7303 pVer2, offsetof(WW8_FFN_BASE, cbFfnM1), pEnd,
7304 &p->aFFNBase.cbFfnM1))
7305 {
7306 break;
7307 }
7308
7309 p->aFFNBase.prg = 0;
7310 p->aFFNBase.fTrueType = 0;
7311 p->aFFNBase.ff = 0;
7312
7313 if (!(readU8(pVer2, 1, pEnd, &p->aFFNBase.wWeight)
7314 && readU8(pVer2, 2, pEnd, &p->aFFNBase.chs)))
7315 {
7316 break;
7317 }
7318 /*
7319 #i8726# 7- seems to encode the name in the same encoding as
7320 the font, e.g load the doc in 97 and save to see the unicode
7321 ver of the asian fontnames in that example to confirm.
7322 */
7323 rtl_TextEncoding eEnc = WW8Fib::GetFIBCharset(p->aFFNBase.chs, rFib.m_lid);
7324 if ((eEnc == RTL_TEXTENCODING_SYMBOL) || (eEnc == RTL_TEXTENCODING_DONTKNOW))
7325 eEnc = RTL_TEXTENCODING_MS_1252;
7326
7327 const size_t nStringOffset = 1 + 2;
7328 sal_Int32 n = getStringLengthWithMax(pVer2, nStringOffset, pEnd, maxStrSize);
7329 if (n == -1) {
7330 break;
7331 }
7332 p->sFontname = OUString(
7333 reinterpret_cast<char const *>(pVer2 + nStringOffset), n, eEnc);
7334 pVer2 = pVer2 + p->aFFNBase.cbFfnM1 + 1;
7335 }
7336 nMax = i;
7337 }
7338 else if( eVersion < ww::eWW8 )
7339 {
7340 sal_uInt8 const * pVer6 = aA.data();
7341 sal_uInt16 i = 0;
7342 for(; i<nMax; ++i, ++p)
7343 {
7344 if (!readU8(
7345 pVer6, offsetof(WW8_FFN_BASE, cbFfnM1), pEnd,
7346 &p->aFFNBase.cbFfnM1))
7347 {
7348 break;
7349 }
7350 sal_uInt8 c2;
7351 if (!readU8(pVer6, 1, pEnd, &c2)) {
7352 break;
7353 }
7354
7355 p->aFFNBase.prg = c2 & 0x02;
7356 p->aFFNBase.fTrueType = (c2 & 0x04) >> 2;
7357 // skip a reserve bit
7358 p->aFFNBase.ff = (c2 & 0x70) >> 4;
7359
7360 if (!(readS16(
7361 pVer6, offsetof(WW8_FFN_BASE, wWeight), pEnd,
7362 &p->aFFNBase.wWeight)
7363 && readU8(
7364 pVer6, offsetof(WW8_FFN_BASE, chs), pEnd, &p->aFFNBase.chs)
7365 && readU8(
7366 pVer6, offsetof(WW8_FFN_BASE, ibszAlt), pEnd,
7367 &p->aFFNBase.ibszAlt)))
7368 {
7369 break;
7370 }
7371 /*
7372 #i8726# 7- seems to encode the name in the same encoding as
7373 the font, e.g load the doc in 97 and save to see the unicode
7374 ver of the asian fontnames in that example to confirm.
7375 */
7376 rtl_TextEncoding eEnc = WW8Fib::GetFIBCharset(p->aFFNBase.chs, rFib.m_lid);
7377 if ((eEnc == RTL_TEXTENCODING_SYMBOL) || (eEnc == RTL_TEXTENCODING_DONTKNOW))
7378 eEnc = RTL_TEXTENCODING_MS_1252;
7379 const size_t nStringOffset = offsetof(WW8_FFN_Ver6, szFfn);
7380 sal_Int32 n = getStringLengthWithMax(pVer6, nStringOffset, pEnd, maxStrSize);
7381 if (n == -1) {
7382 break;
7383 }
7384 p->sFontname = OUString(reinterpret_cast<char const*>(pVer6 + nStringOffset), n, eEnc);
7385 if (p->aFFNBase.ibszAlt && p->aFFNBase.ibszAlt < maxStrSize) //don't start after end of string
7386 {
7387 const size_t nAltStringOffset = offsetof(WW8_FFN_Ver6, szFfn) + p->aFFNBase.ibszAlt;
7388 n = getStringLengthWithMax(pVer6, nAltStringOffset, pEnd, maxStrSize);
7389 if (n == -1) {
7390 break;
7391 }
7392 p->sFontname += ";" + OUString(reinterpret_cast<char const*>(pVer6 + nAltStringOffset),
7393 n, eEnc);
7394 }
7395 else
7396 {
7397 //#i18369# if it's a symbol font set Symbol as fallback
7398 if (
7399 RTL_TEXTENCODING_SYMBOL == WW8Fib::GetFIBCharset(p->aFFNBase.chs, rFib.m_lid)
7400 && p->sFontname!="Symbol"
7401 )
7402 {
7403 p->sFontname += ";Symbol";
7404 }
7405 }
7406 pVer6 = pVer6 + p->aFFNBase.cbFfnM1 + 1;
7407 }
7408 nMax = i;
7409 }
7410 else
7411 {
7412 //count of bytes in minimum FontFamilyInformation payload
7413 const sal_uInt8 cbMinFFNPayload = 41;
7414 sal_uInt16 nValidFonts = 0;
7415 sal_Int32 nRemainingFFn = nFFn;
7416 sal_uInt8* pRaw = aA.data();
7417 for (sal_uInt16 i=0; i < nMax && nRemainingFFn; ++i, ++p)
7418 {
7419 //pRaw[0] is cbFfnM1, the alleged total length of FFN - 1
7420 //i.e. length after cbFfnM1
7421 sal_uInt8 cbFfnM1 = *pRaw++;
7422 --nRemainingFFn;
7423
7424 if (cbFfnM1 > nRemainingFFn)
7425 break;
7426
7427 if (cbFfnM1 < cbMinFFNPayload)
7428 break;
7429
7430 p->aFFNBase.cbFfnM1 = cbFfnM1;
7431
7432 sal_uInt8 *pVer8 = pRaw;
7433
7434 sal_uInt8 c2 = *pVer8++;
7435 --cbFfnM1;
7436
7437 p->aFFNBase.prg = c2 & 0x02;
7438 p->aFFNBase.fTrueType = (c2 & 0x04) >> 2;
7439 // skip a reserve bit
7440 p->aFFNBase.ff = (c2 & 0x70) >> 4;
7441
7442 p->aFFNBase.wWeight = SVBT16ToUInt16(*reinterpret_cast<SVBT16*>(pVer8));
7443 pVer8+=2;
7444 cbFfnM1-=2;
7445
7446 p->aFFNBase.chs = *pVer8++;
7447 --cbFfnM1;
7448
7449 p->aFFNBase.ibszAlt = *pVer8++;
7450 --cbFfnM1;
7451
7452 pVer8 += 10; //PANOSE
7453 cbFfnM1-=10;
7454 pVer8 += 24; //FONTSIGNATURE
7455 cbFfnM1-=24;
7456
7457 assert(cbFfnM1 >= 2);
7458
7459 sal_uInt8 nMaxNullTerminatedPossible = cbFfnM1/2 - 1;
7460 sal_Unicode *pPrimary = reinterpret_cast<sal_Unicode*>(pVer8);
7461 pPrimary[nMaxNullTerminatedPossible] = 0;
7462#ifdef OSL_BIGENDIAN
7463 swapEndian(pPrimary);
7464#endif
7465 p->sFontname = pPrimary;
7466 if (p->aFFNBase.ibszAlt && p->aFFNBase.ibszAlt < nMaxNullTerminatedPossible)
7467 {
7468 sal_Unicode *pSecondary = pPrimary + p->aFFNBase.ibszAlt;
7469#ifdef OSL_BIGENDIAN
7470 swapEndian(pSecondary);
7471#endif
7472 p->sFontname += OUString::Concat(";") + pSecondary;
7473 }
7474
7475 // #i43762# check font name for illegal characters
7476 lcl_checkFontname( p->sFontname );
7477
7478 // set pointer one font back to original array
7479 pRaw += p->aFFNBase.cbFfnM1;
7480 nRemainingFFn -= p->aFFNBase.cbFfnM1;
7481 ++nValidFonts;
7482 }
7483 OSL_ENSURE(nMax == nValidFonts, "Font count differs with availability");
7484 nMax = std::min(nMax, nValidFonts);
7485 }
7486 }
7487 m_aFontA.resize(nMax);
7488 m_aFontA.shrink_to_fit();
7489}
7490
7491const WW8_FFN* WW8Fonts::GetFont( sal_uInt16 nNum ) const
7492{
7493 if (nNum >= m_aFontA.size())
7494 return nullptr;
7495
7496 return &m_aFontA[nNum];
7497}
7498
7499// Search after a header/footer for an index in the ww list from header/footer
7500
7501// specials for WinWord6 and -7:
7502//
7503// 1) At the start of reading we must build WWPLCF_HdFt with Fib and Dop
7504// 2) The main text must be read sequentially over all sections
7505// 3) For every header/footer in the main text, we must call UpdateIndex()
7506// exactly once with the parameter from the attribute.
7507// (per section can be maximally one). This call must take place *after*
7508// the last call from GetTextPos().
7509// 4) GetTextPos() can be called with exactly one flag
7510// out of WW8_{FOOTER,HEADER}_{ODD,EVEN,FIRST} (Do not change!)
7511// -> maybe we can get a right result then
7512
7513WW8PLCF_HdFt::WW8PLCF_HdFt( SvStream* pSt, WW8Fib const & rFib, WW8Dop const & rDop )
7514 : m_aPLCF(*pSt, rFib.m_fcPlcfhdd , rFib.m_lcbPlcfhdd , 0)
7515{
7516 m_nIdxOffset = 0;
7517
7518 /*
7519 This dop.grpfIhdt has a bit set for each special
7520 footnote *and endnote!!* separator,continuation separator, and
7521 continuation notice entry, the documentation does not mention the
7522 endnote separators, the documentation also gets the index numbers
7523 backwards when specifying which bits to test. The bottom six bits
7524 of this value must be tested and skipped over. Each section's
7525 grpfIhdt is then tested for the existence of the appropriate headers
7526 and footers, at the end of each section the nIdxOffset must be updated
7527 to point to the beginning of the next section's group of headers and
7528 footers in this PLCF, UpdateIndex does that task.
7529 */
7530 for( sal_uInt8 nI = 0x1; nI <= 0x20; nI <<= 1 )
7531 if( nI & rDop.grpfIhdt ) // bit set?
7532 m_nIdxOffset++;
7533}
7534
7536 WW8_CP& rLen)
7537{
7538 sal_uInt8 nI = 0x01;
7539 short nIdx = m_nIdxOffset;
7540 while (true)
7541 {
7542 if( nI & nWhich )
7543 break; // found
7544 if( grpfIhdt & nI )
7545 nIdx++; // uninteresting Header / Footer
7546 nI <<= 1; // text next bit
7547 if( nI > 0x20 )
7548 return false; // not found
7549 }
7550 // nIdx is HdFt-Index
7551 WW8_CP nEnd;
7552 void* pData;
7553
7554 m_aPLCF.SetIdx( nIdx ); // Lookup suitable CP
7555 m_aPLCF.Get( rStart, nEnd, pData );
7556 if (nEnd < rStart)
7557 {
7558 SAL_WARN("sw.ww8", "End " << nEnd << " before Start " << rStart);
7559 return false;
7560 }
7561
7562 bool bFail = o3tl::checked_sub(nEnd, rStart, rLen);
7563 if (bFail)
7564 {
7565 SAL_WARN("sw.ww8", "broken offset, ignoring");
7566 return false;
7567 }
7568
7569 m_aPLCF.advance();
7570
7571 return true;
7572}
7573
7574void WW8PLCF_HdFt::GetTextPosExact(short nIdx, WW8_CP& rStart, WW8_CP& rLen)
7575{
7576 WW8_CP nEnd;
7577 void* pData;
7578
7579 m_aPLCF.SetIdx( nIdx ); // Lookup suitable CP
7580 m_aPLCF.Get( rStart, nEnd, pData );
7581 if (nEnd < rStart)
7582 {
7583 SAL_WARN("sw.ww8", "End " << nEnd << " before Start " << rStart);
7584 rLen = 0;
7585 return;
7586 }
7587 if (o3tl::checked_sub(nEnd, rStart, rLen))
7588 {
7589 SAL_WARN("sw.ww8", "GetTextPosExact overflow");
7590 rLen = 0;
7591 }
7592}
7593
7595{
7596 // Caution: Description is not correct
7597 for( sal_uInt8 nI = 0x01; nI <= 0x20; nI <<= 1 )
7598 if( nI & grpfIhdt )
7599 m_nIdxOffset++;
7600}
7601
7602WW8Dop::WW8Dop(SvStream& rSt, sal_Int16 nFib, sal_Int32 nPos, sal_uInt32 nSize):
7603 fFacingPages(false), fWidowControl(false), fPMHMainDoc(false), grfSuppression(0), fpc(0),
7604 grpfIhdt(0), rncFootnote(0), nFootnote(0), fOutlineDirtySave(false), fOnlyMacPics(false),
7605 fOnlyWinPics(false), fLabelDoc(false), fHyphCapitals(false), fAutoHyphen(false),
7606 fFormNoFields(false), fLinkStyles(false), fRevMarking(false), fBackup(false),
7607 fExactCWords(false), fPagHidden(false), fPagResults(false), fLockAtn(false),
7608 fMirrorMargins(false), fReadOnlyRecommended(false), fDfltTrueType(false),
7609 fPagSuppressTopSpacing(false), fProtEnabled(false), fDispFormFieldSel(false), fRMView(false),
7610 fRMPrint(false), fWriteReservation(false), fLockRev(false), fEmbedFonts(false),
7611 copts_fNoTabForInd(false), copts_fNoSpaceRaiseLower(false), copts_fSuppressSpbfAfterPgBrk(false),
7612 copts_fWrapTrailSpaces(false), copts_fMapPrintTextColor(false), copts_fNoColumnBalance(false),
7613 copts_fConvMailMergeEsc(false), copts_fSuppressTopSpacing(false),
7614 copts_fOrigWordTableRules(false), copts_fTransparentMetafiles(false),
7615 copts_fShowBreaksInFrames(false), copts_fSwapBordersFacingPgs(false), copts_fExpShRtn(false),
7616 rncEdn(0), nEdn(0), epc(0), fPrintFormData(false), fSaveFormData(false), fShadeFormData(false),
7617 fWCFootnoteEdn(false), wvkSaved(0), wScaleSaved(0), zkSaved(0), fRotateFontW6(false),
7618 iGutterPos(false), fNoTabForInd(false), fNoSpaceRaiseLower(false),
7619 fSuppressSpbfAfterPageBreak(false), fWrapTrailSpaces(false), fMapPrintTextColor(false),
7620 fNoColumnBalance(false), fConvMailMergeEsc(false), fSuppressTopSpacing(false),
7621 fOrigWordTableRules(false), fTransparentMetafiles(false), fShowBreaksInFrames(false),
7622 fSwapBordersFacingPgs(false), fCompatibilityOptions_Unknown1_13(false), fExpShRtn(false),
7623 fCompatibilityOptions_Unknown1_15(false), fCompatibilityOptions_Unknown1_16(false),
7624 fSuppressTopSpacingMac5(false), fTruncDxaExpand(false), fPrintBodyBeforeHdr(false),
7625 fNoLeading(false), fCompatibilityOptions_Unknown1_21(false), fMWSmallCaps(false),
7626 fCompatibilityOptions_Unknown1_23(false), fCompatibilityOptions_Unknown1_24(false),
7627 fCompatibilityOptions_Unknown1_25(false), fCompatibilityOptions_Unknown1_26(false),
7628 fCompatibilityOptions_Unknown1_27(false), fCompatibilityOptions_Unknown1_28(false),
7629 fCompatibilityOptions_Unknown1_29(false), fCompatibilityOptions_Unknown1_30(false),
7630 fCompatibilityOptions_Unknown1_31(false), fUsePrinterMetrics(false), lvl(0), fHtmlDoc(false),
7631 fSnapBorder(false), fIncludeHeader(false), fIncludeFooter(false), fForcePageSizePag(false),
7632 fMinFontSizePag(false), fHaveVersions(false), fAutoVersion(false),
7633 fCompatibilityOptions_Unknown2_1(false), fCompatibilityOptions_Unknown2_2(false),
7634 fDontUseHTMLAutoSpacing(false), fCompatibilityOptions_Unknown2_4(false),
7635 fCompatibilityOptions_Unknown2_5(false), fCompatibilityOptions_Unknown2_6(false),
7636 fCompatibilityOptions_Unknown2_7(false), fCompatibilityOptions_Unknown2_8(false),
7637 fCompatibilityOptions_Unknown2_9(false), fCompatibilityOptions_Unknown2_10(false),
7638 fDontBreakWrappedTables(false), fCompatibilityOptions_Unknown2_12(false),
7639 fCompatibilityOptions_Unknown2_13(false), fCompatibilityOptions_Unknown2_14(false),
7640 fCompatibilityOptions_Unknown2_15(false), fCompatibilityOptions_Unknown2_16(false),
7641 fCompatibilityOptions_Unknown2_17(false), fCompatibilityOptions_Unknown2_18(false),
7642 fCompatibilityOptions_Unknown2_19(false), fCompatibilityOptions_Unknown2_20(false),
7643 fCompatibilityOptions_Unknown2_21(false), fCompatibilityOptions_Unknown2_22(false),
7644 fCompatibilityOptions_Unknown2_23(false), fCompatibilityOptions_Unknown2_24(false),
7645 fCompatibilityOptions_Unknown2_25(false), fCompatibilityOptions_Unknown2_26(false),
7646 fCompatibilityOptions_Unknown2_27(false), fCompatibilityOptions_Unknown2_28(false),
7647 fCompatibilityOptions_Unknown2_29(false), fCompatibilityOptions_Unknown2_30(false),
7648 fCompatibilityOptions_Unknown2_31(false), fCompatibilityOptions_Unknown2_32(false),
7649 fUnknown3(0), fUseBackGroundInAllmodes(false), fDoNotEmbedSystemFont(false), fWordCompat(false),
7650 fLiveRecover(false), fEmbedFactoids(false), fFactoidXML(false), fFactoidAllDone(false),
7651 fFolioPrint(false), fReverseFolio(false), iTextLineEnding(0), fHideFcc(false),
7652 fAcetateShowMarkup(false), fAcetateShowAtn(false), fAcetateShowInsDel(false),
7653 fAcetateShowProps(false)
7654 // in C++20 with P06831R1 "Default member initializers for bit-fields (revision 1)", the
7655 // above bit-field member initializations can be moved to the class definition
7656{
7657 fDontUseHTMLAutoSpacing = true; //default
7658 fAcetateShowAtn = true; //default
7659 const sal_uInt32 nMaxDopSize = 0x268;
7660 std::unique_ptr<sal_uInt8[]> pDataPtr( new sal_uInt8[ nMaxDopSize ] );
7661 sal_uInt8* pData = pDataPtr.get();
7662
7663 sal_uInt32 nRead = std::min(nMaxDopSize, nSize);
7664 if (nSize < 2 || !checkSeek(rSt, nPos) || nRead != rSt.ReadBytes(pData, nRead))
7665 nDopError = ERR_SWG_READ_ERROR; // report error
7666 else
7667 {
7668 if (nMaxDopSize > nRead)
7669 memset( pData + nRead, 0, nMaxDopSize - nRead );
7670
7671 // interpret the data
7672 sal_uInt32 a32Bit;
7673 sal_uInt16 a16Bit;
7674 sal_uInt8 a8Bit;
7675
7676 a16Bit = Get_UShort( pData ); // 0 0x00
7677 fFacingPages = 0 != ( a16Bit & 0x0001 ) ;
7678 fWidowControl = 0 != ( a16Bit & 0x0002 ) ;
7679 fPMHMainDoc = 0 != ( a16Bit & 0x0004 ) ;
7680 grfSuppression = ( a16Bit & 0x0018 ) >> 3;
7681 fpc = ( a16Bit & 0x0060 ) >> 5;
7682 grpfIhdt = ( a16Bit & 0xff00 ) >> 8;
7683
7684 a16Bit = Get_UShort( pData ); // 2 0x02
7685 rncFootnote = a16Bit & 0x0003 ;
7686 nFootnote = ( a16Bit & ~0x0003 ) >> 2 ;
7687
7688 a8Bit = Get_Byte( pData ); // 4 0x04
7689 fOutlineDirtySave = 0 != ( a8Bit & 0x01 );
7690
7691 a8Bit = Get_Byte( pData ); // 5 0x05
7692 fOnlyMacPics = 0 != ( a8Bit & 0x01 );
7693 fOnlyWinPics = 0 != ( a8Bit & 0x02 );
7694 fLabelDoc = 0 != ( a8Bit & 0x04 );
7695 fHyphCapitals = 0 != ( a8Bit & 0x08 );
7696 fAutoHyphen = 0 != ( a8Bit & 0x10 );
7697 fFormNoFields = 0 != ( a8Bit & 0x20 );
7698 fLinkStyles = 0 != ( a8Bit & 0x40 );
7699 fRevMarking = 0 != ( a8Bit & 0x80 );
7700
7701 a8Bit = Get_Byte( pData ); // 6 0x06
7702 fBackup = 0 != ( a8Bit & 0x01 );
7703 fExactCWords = 0 != ( a8Bit & 0x02 );
7704 fPagHidden = 0 != ( a8Bit & 0x04 );
7705 fPagResults = 0 != ( a8Bit & 0x08 );
7706 fLockAtn = 0 != ( a8Bit & 0x10 );
7707 fMirrorMargins = 0 != ( a8Bit & 0x20 );
7708 fReadOnlyRecommended = 0 != ( a8Bit & 0x40 );
7709 fDfltTrueType = 0 != ( a8Bit & 0x80 );
7710
7711 a8Bit = Get_Byte( pData ); // 7 0x07
7712 fPagSuppressTopSpacing = 0 != ( a8Bit & 0x01 );
7713 fProtEnabled = 0 != ( a8Bit & 0x02 );
7714 fDispFormFieldSel = 0 != ( a8Bit & 0x04 );
7715 fRMView = 0 != ( a8Bit & 0x08 );
7716 fRMPrint = 0 != ( a8Bit & 0x10 );
7717 fWriteReservation = 0 != ( a8Bit & 0x20 );
7718 fLockRev = 0 != ( a8Bit & 0x40 );
7719 fEmbedFonts = 0 != ( a8Bit & 0x80 );
7720
7721 a8Bit = Get_Byte( pData ); // 8 0x08
7722 copts_fNoTabForInd = 0 != ( a8Bit & 0x01 );
7723 copts_fNoSpaceRaiseLower = 0 != ( a8Bit & 0x02 );
7724 copts_fSuppressSpbfAfterPgBrk = 0 != ( a8Bit & 0x04 );
7725 copts_fWrapTrailSpaces = 0 != ( a8Bit & 0x08 );
7726 copts_fMapPrintTextColor = 0 != ( a8Bit & 0x10 );
7727 copts_fNoColumnBalance = 0 != ( a8Bit & 0x20 );
7728 copts_fConvMailMergeEsc = 0 != ( a8Bit & 0x40 );
7729 copts_fSuppressTopSpacing = 0 != ( a8Bit & 0x80 );
7730
7731 a8Bit = Get_Byte( pData ); // 9 0x09
7732 copts_fOrigWordTableRules = 0 != ( a8Bit & 0x01 );
7733 copts_fTransparentMetafiles = 0 != ( a8Bit & 0x02 );
7734 copts_fShowBreaksInFrames = 0 != ( a8Bit & 0x04 );
7735 copts_fSwapBordersFacingPgs = 0 != ( a8Bit & 0x08 );
7736 copts_fExpShRtn = 0 != ( a8Bit & 0x20 ); // #i56856#
7737
7738 dxaTab = Get_Short( pData ); // 10 0x0a
7739 wSpare = Get_UShort( pData ); // 12 0x0c
7740 dxaHotZ = Get_UShort( pData ); // 14 0x0e
7741 cConsecHypLim = Get_UShort( pData ); // 16 0x10
7742 wSpare2 = Get_UShort( pData ); // 18 0x12
7743 dttmCreated = Get_Long( pData ); // 20 0x14
7744 dttmRevised = Get_Long( pData ); // 24 0x18
7745 dttmLastPrint = Get_Long( pData ); // 28 0x1c
7746 nRevision = Get_Short( pData ); // 32 0x20
7747 tmEdited = Get_Long( pData ); // 34 0x22
7748 cWords = Get_Long( pData ); // 38 0x26
7749 cCh = Get_Long( pData ); // 42 0x2a
7750 cPg = Get_Short( pData ); // 46 0x2e
7751 cParas = Get_Long( pData ); // 48 0x30
7752
7753 a16Bit = Get_UShort( pData ); // 52 0x34
7754 rncEdn = a16Bit & 0x0003 ;
7755 nEdn = ( a16Bit & ~0x0003 ) >> 2;
7756
7757 a16Bit = Get_UShort( pData ); // 54 0x36
7758 epc = a16Bit & 0x0003 ;
7759 nfcFootnoteRef = ( a16Bit & 0x003c ) >> 2;
7760 nfcEdnRef = ( a16Bit & 0x03c0 ) >> 6;
7761 fPrintFormData = 0 != ( a16Bit & 0x0400 );
7762 fSaveFormData = 0 != ( a16Bit & 0x0800 );
7763 fShadeFormData = 0 != ( a16Bit & 0x1000 );
7764 fWCFootnoteEdn = 0 != ( a16Bit & 0x8000 );
7765
7766 cLines = Get_Long( pData ); // 56 0x38
7767 cWordsFootnoteEnd = Get_Long( pData ); // 60 0x3c
7768 cChFootnoteEdn = Get_Long( pData ); // 64 0x40
7769 cPgFootnoteEdn = Get_Short( pData ); // 68 0x44
7770 cParasFootnoteEdn = Get_Long( pData ); // 70 0x46
7771 cLinesFootnoteEdn = Get_Long( pData ); // 74 0x4a
7772 lKeyProtDoc = Get_Long( pData ); // 78 0x4e
7773
7774 a16Bit = Get_UShort( pData ); // 82 0x52
7775 wvkSaved = a16Bit & 0x0007 ;
7776 wScaleSaved = ( a16Bit & 0x0ff8 ) >> 3 ;
7777 zkSaved = ( a16Bit & 0x3000 ) >> 12;
7778 fRotateFontW6 = ( a16Bit & 0x4000 ) >> 14;
7779 iGutterPos = ( a16Bit & 0x8000 ) >> 15;
7780
7781 if (nFib >= 103) // Word 6/32bit, 95, 97, 2000, 2002, 2003, 2007
7782 {
7783 a32Bit = Get_ULong( pData ); // 84 0x54
7785 }
7786
7787 //#i22436#, for all WW7- documents
7788 if (nFib <= 104) // Word 95
7789 fUsePrinterMetrics = true;
7790
7791 if (nFib > 105) // Word 97, 2000, 2002, 2003, 2007
7792 {
7793 adt = Get_Short( pData ); // 88 0x58
7794
7795 doptypography.ReadFromMem(pData); // 90 0x5a
7796
7797 memcpy( &dogrid, pData, sizeof( WW8_DOGRID )); // 400 0x190
7798 pData += sizeof( WW8_DOGRID );
7799
7800 a16Bit = Get_UShort( pData ); // 410 0x19a
7801 // the following 9 bit are uninteresting
7802 fHtmlDoc = ( a16Bit & 0x0200 ) >> 9 ;
7803 fSnapBorder = ( a16Bit & 0x0800 ) >> 11 ;
7804 fIncludeHeader = ( a16Bit & 0x1000 ) >> 12 ;
7805 fIncludeFooter = ( a16Bit & 0x2000 ) >> 13 ;
7806 fForcePageSizePag = ( a16Bit & 0x4000 ) >> 14 ;
7807 fMinFontSizePag = ( a16Bit & 0x8000 ) >> 15 ;
7808
7809 a16Bit = Get_UShort( pData ); // 412 0x19c
7810 fHaveVersions = 0 != ( a16Bit & 0x0001 );
7811 fAutoVersion = 0 != ( a16Bit & 0x0002 );
7812
7813 pData += 12; // 414 0x19e
7814
7815 cChWS = Get_Long( pData ); // 426 0x1aa
7816 cChWSFootnoteEdn = Get_Long( pData ); // 430 0x1ae
7817 grfDocEvents = Get_Long( pData ); // 434 0x1b2
7818
7819 pData += 4+30+8; // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc
7820
7821 cDBC = Get_Long( pData ); // 480 0x1e0
7822 cDBCFootnoteEdn = Get_Long( pData ); // 484 0x1e4
7823
7824 pData += 1 * sizeof( sal_Int32); // 488 0x1e8
7825
7826 nfcFootnoteRef = Get_Short( pData ); // 492 0x1ec
7827 nfcEdnRef = Get_Short( pData ); // 494 0x1ee
7828 hpsZoomFontPag = Get_Short( pData ); // 496 0x1f0
7829 dywDispPag = Get_Short( pData ); // 498 0x1f2
7830
7831 if (nRead >= 516)
7832 {
7833 //500 -> 508, Appear to be repeated here in 2000+
7834 pData += 8; // 500 0x1f4
7835 a32Bit = Get_Long( pData ); // 508 0x1fc
7837 a32Bit = Get_Long( pData ); // 512 0x200
7838
7839 // i#78591#
7841 }
7842 if (nRead >= 550)
7843 {
7844 pData += 32;
7845 a16Bit = Get_UShort( pData );
7846 fDoNotEmbedSystemFont = ( a16Bit & 0x0001 );
7847 fWordCompat = ( a16Bit & 0x0002 ) >> 1;
7848 fLiveRecover = ( a16Bit & 0x0004 ) >> 2;
7849 fEmbedFactoids = ( a16Bit & 0x0008 ) >> 3;
7850 fFactoidXML = ( a16Bit & 0x00010 ) >> 4;
7851 fFactoidAllDone = ( a16Bit & 0x0020 ) >> 5;
7852 fFolioPrint = ( a16Bit & 0x0040 ) >> 6;
7853 fReverseFolio = ( a16Bit & 0x0080 ) >> 7;
7854 iTextLineEnding = ( a16Bit & 0x0700 ) >> 8;
7855 fHideFcc = ( a16Bit & 0x0800 ) >> 11;
7856 fAcetateShowMarkup = ( a16Bit & 0x1000 ) >> 12;
7857 fAcetateShowAtn = ( a16Bit & 0x2000 ) >> 13;
7858 fAcetateShowInsDel = ( a16Bit & 0x4000 ) >> 14;
7859 fAcetateShowProps = ( a16Bit & 0x8000 ) >> 15;
7860 }
7861 if (nRead >= 600)
7862 {
7863 pData += 48;
7864 a16Bit = Get_Short(pData);
7865 fUseBackGroundInAllmodes = (a16Bit & 0x0080) >> 7;
7866 }
7867 }
7868 }
7869}
7870
7872 fFacingPages(false), fWidowControl(true), fPMHMainDoc(false), grfSuppression(0), fpc(1),
7873 grpfIhdt(0), rncFootnote(0), nFootnote(1), fOutlineDirtySave(true), fOnlyMacPics(false),
7874 fOnlyWinPics(false), fLabelDoc(false), fHyphCapitals(true), fAutoHyphen(false),
7875 fFormNoFields(false), fLinkStyles(false), fRevMarking(false), fBackup(true),
7876 fExactCWords(false), fPagHidden(true), fPagResults(true), fLockAtn(false),
7877 fMirrorMargins(false), fReadOnlyRecommended(false), fDfltTrueType(true),
7878 fPagSuppressTopSpacing(false), fProtEnabled(false), fDispFormFieldSel(false), fRMView(true),
7879 fRMPrint(true), fWriteReservation(false), fLockRev(false), fEmbedFonts(false),
7880 copts_fNoTabForInd(false), copts_fNoSpaceRaiseLower(false), copts_fSuppressSpbfAfterPgBrk(false),
7881 copts_fWrapTrailSpaces(false), copts_fMapPrintTextColor(false), copts_fNoColumnBalance(false),
7882 copts_fConvMailMergeEsc(false), copts_fSuppressTopSpacing(false),
7883 copts_fOrigWordTableRules(false), copts_fTransparentMetafiles(false),
7884 copts_fShowBreaksInFrames(false), copts_fSwapBordersFacingPgs(false), copts_fExpShRtn(false),
7885 dxaTab(0x2d0), dxaHotZ(0x168), nRevision(1),
7886 rncEdn(0), nEdn(1), epc(3), fPrintFormData(false), fSaveFormData(false), fShadeFormData(true),
7887 fWCFootnoteEdn(false), wvkSaved(2), wScaleSaved(100), zkSaved(0), fRotateFontW6(false),
7888 iGutterPos(false), fNoTabForInd(false), fNoSpaceRaiseLower(false),
7889 fSuppressSpbfAfterPageBreak(false), fWrapTrailSpaces(false), fMapPrintTextColor(false),
7890 fNoColumnBalance(false), fConvMailMergeEsc(false), fSuppressTopSpacing(false),
7891 fOrigWordTableRules(false), fTransparentMetafiles(false), fShowBreaksInFrames(false),
7892 fSwapBordersFacingPgs(false), fCompatibilityOptions_Unknown1_13(false), fExpShRtn(false),
7893 fCompatibilityOptions_Unknown1_15(false), fCompatibilityOptions_Unknown1_16(false),
7894 fSuppressTopSpacingMac5(false), fTruncDxaExpand(false), fPrintBodyBeforeHdr(false),
7895 fNoLeading(true), fCompatibilityOptions_Unknown1_21(false), fMWSmallCaps(false),
7896 fCompatibilityOptions_Unknown1_23(false), fCompatibilityOptions_Unknown1_24(false),
7897 fCompatibilityOptions_Unknown1_25(false), fCompatibilityOptions_Unknown1_26(false),
7898 fCompatibilityOptions_Unknown1_27(false), fCompatibilityOptions_Unknown1_28(false),
7899 fCompatibilityOptions_Unknown1_29(false), fCompatibilityOptions_Unknown1_30(false),
7900 fCompatibilityOptions_Unknown1_31(false), fUsePrinterMetrics(true), lvl(9), fHtmlDoc(false),
7901 fSnapBorder(false), fIncludeHeader(true), fIncludeFooter(true), fForcePageSizePag(false),
7902 fMinFontSizePag(false), fHaveVersions(false), fAutoVersion(false),
7903 cChWS(0), cChWSFootnoteEdn(0), cDBC(0), cDBCFootnoteEdn(0), nfcEdnRef(2),
7904 fCompatibilityOptions_Unknown2_1(false), fCompatibilityOptions_Unknown2_2(false),
7905 fDontUseHTMLAutoSpacing(false), fCompatibilityOptions_Unknown2_4(false),
7906 fCompatibilityOptions_Unknown2_5(false), fCompatibilityOptions_Unknown2_6(false),
7907 fCompatibilityOptions_Unknown2_7(false), fCompatibilityOptions_Unknown2_8(false),
7908 fCompatibilityOptions_Unknown2_9(false), fCompatibilityOptions_Unknown2_10(false),
7909 fDontBreakWrappedTables(false), fCompatibilityOptions_Unknown2_12(false),
7910 fCompatibilityOptions_Unknown2_13(false), fCompatibilityOptions_Unknown2_14(false),
7911 fCompatibilityOptions_Unknown2_15(false), fCompatibilityOptions_Unknown2_16(false),
7912 fCompatibilityOptions_Unknown2_17(false), fCompatibilityOptions_Unknown2_18(false),
7913 fCompatibilityOptions_Unknown2_19(false), fCompatibilityOptions_Unknown2_20(false),
7914 fCompatibilityOptions_Unknown2_21(false), fCompatibilityOptions_Unknown2_22(false),
7915 fCompatibilityOptions_Unknown2_23(false), fCompatibilityOptions_Unknown2_24(false),
7916 fCompatibilityOptions_Unknown2_25(false), fCompatibilityOptions_Unknown2_26(false),
7917 fCompatibilityOptions_Unknown2_27(false), fCompatibilityOptions_Unknown2_28(false),
7918 fCompatibilityOptions_Unknown2_29(false), fCompatibilityOptions_Unknown2_30(false),
7919 fCompatibilityOptions_Unknown2_31(false), fCompatibilityOptions_Unknown2_32(false),
7920 fUnknown3(0), fUseBackGroundInAllmodes(false), fDoNotEmbedSystemFont(false), fWordCompat(false),
7921 fLiveRecover(false), fEmbedFactoids(false), fFactoidXML(false), fFactoidAllDone(false),
7922 fFolioPrint(false), fReverseFolio(false), iTextLineEnding(0), fHideFcc(false),
7923 fAcetateShowMarkup(false), fAcetateShowAtn(true), fAcetateShowInsDel(false),
7924 fAcetateShowProps(false)
7925 // in C++20 with P06831R1 "Default member initializers for bit-fields (revision 1)", the
7926 // above bit-field member initializations can be moved to the class definition
7927{
7928 /*
7929 Writer acts like this all the time at the moment, ideally we need an
7930 option for these two as well to import word docs that are not like
7931 this by default
7932 */
7933 // put in initialization list
7934 // fNoLeading = true;
7935 //fUsePrinterMetrics = true;
7936}
7937
7938void WW8Dop::SetCompatibilityOptions(sal_uInt32 a32Bit)
7939{
7940 fNoTabForInd = ( a32Bit & 0x00000001 ) ;
7941 fNoSpaceRaiseLower = ( a32Bit & 0x00000002 ) >> 1 ;
7942 fSuppressSpbfAfterPageBreak = ( a32Bit & 0x00000004 ) >> 2 ;
7943 fWrapTrailSpaces = ( a32Bit & 0x00000008 ) >> 3 ;
7944 fMapPrintTextColor = ( a32Bit & 0x00000010 ) >> 4 ;
7945 fNoColumnBalance = ( a32Bit & 0x00000020 ) >> 5 ;
7946 fConvMailMergeEsc = ( a32Bit & 0x00000040 ) >> 6 ;
7947 fSuppressTopSpacing = ( a32Bit & 0x00000080 ) >> 7 ;
7948 fOrigWordTableRules = ( a32Bit & 0x00000100 ) >> 8 ;
7949 fTransparentMetafiles = ( a32Bit & 0x00000200 ) >> 9 ;
7950 fShowBreaksInFrames = ( a32Bit & 0x00000400 ) >> 10 ;
7951 fSwapBordersFacingPgs = ( a32Bit & 0x00000800 ) >> 11 ;
7952 fCompatibilityOptions_Unknown1_13 = ( a32Bit & 0x00001000 ) >> 12 ;
7953 fExpShRtn = ( a32Bit & 0x00002000 ) >> 13 ; // #i56856#
7954 fCompatibilityOptions_Unknown1_15 = ( a32Bit & 0x00004000 ) >> 14 ;
7955 fCompatibilityOptions_Unknown1_16 = ( a32Bit & 0x00008000 ) >> 15 ;
7956 fSuppressTopSpacingMac5 = ( a32Bit & 0x00010000 ) >> 16 ;
7957 fTruncDxaExpand = ( a32Bit & 0x00020000 ) >> 17 ;
7958 fPrintBodyBeforeHdr = ( a32Bit & 0x00040000 ) >> 18 ;
7959 fNoLeading = ( a32Bit & 0x00080000 ) >> 19 ;
7960 fCompatibilityOptions_Unknown1_21 = ( a32Bit & 0x00100000 ) >> 20 ;
7961 fMWSmallCaps = ( a32Bit & 0x00200000 ) >> 21 ;
7962 fCompatibilityOptions_Unknown1_23 = ( a32Bit & 0x00400000 ) >> 22 ;
7963 fCompatibilityOptions_Unknown1_24 = ( a32Bit & 0x00800800 ) >> 23 ;
7964 fCompatibilityOptions_Unknown1_25 = ( a32Bit & 0x01000000 ) >> 24 ;
7965 fCompatibilityOptions_Unknown1_26 = ( a32Bit & 0x02000000 ) >> 25 ;
7966 fCompatibilityOptions_Unknown1_27 = ( a32Bit & 0x04000000 ) >> 26 ;
7967 fCompatibilityOptions_Unknown1_28 = ( a32Bit & 0x08000000 ) >> 27 ;
7968 fCompatibilityOptions_Unknown1_29 = ( a32Bit & 0x10000000 ) >> 28 ;
7969 fCompatibilityOptions_Unknown1_30 = ( a32Bit & 0x20000000 ) >> 29 ;
7970 fCompatibilityOptions_Unknown1_31 = ( a32Bit & 0x40000000 ) >> 30 ;
7971
7972 fUsePrinterMetrics = ( a32Bit & 0x80000000 ) >> 31 ;
7973}
7974
7976{
7977 sal_uInt32 a32Bit = 0;
7978 if (fNoTabForInd) a32Bit |= 0x00000001;
7979 if (fNoSpaceRaiseLower) a32Bit |= 0x00000002;
7980 if (fSuppressSpbfAfterPageBreak) a32Bit |= 0x00000004;
7981 if (fWrapTrailSpaces) a32Bit |= 0x00000008;
7982 if (fMapPrintTextColor) a32Bit |= 0x00000010;
7983 if (fNoColumnBalance) a32Bit |= 0x00000020;
7984 if (fConvMailMergeEsc) a32Bit |= 0x00000040;
7985 if (fSuppressTopSpacing) a32Bit |= 0x00000080;
7986 if (fOrigWordTableRules) a32Bit |= 0x00000100;
7987 if (fTransparentMetafiles) a32Bit |= 0x00000200;
7988 if (fShowBreaksInFrames) a32Bit |= 0x00000400;
7989 if (fSwapBordersFacingPgs) a32Bit |= 0x00000800;
7990 if (fCompatibilityOptions_Unknown1_13) a32Bit |= 0x00001000;
7991 if (fExpShRtn) a32Bit |= 0x00002000; // #i56856#
7992 if (fCompatibilityOptions_Unknown1_15) a32Bit |= 0x00004000;
7993 if (fCompatibilityOptions_Unknown1_16) a32Bit |= 0x00008000;
7994 if (fSuppressTopSpacingMac5) a32Bit |= 0x00010000;
7995 if (fTruncDxaExpand) a32Bit |= 0x00020000;
7996 if (fPrintBodyBeforeHdr) a32Bit |= 0x00040000;
7997 if (fNoLeading) a32Bit |= 0x00080000;
7998 if (fCompatibilityOptions_Unknown1_21) a32Bit |= 0x00100000;
7999 if (fMWSmallCaps) a32Bit |= 0x00200000;
8000 if (fCompatibilityOptions_Unknown1_23) a32Bit |= 0x00400000;
8001 if (fCompatibilityOptions_Unknown1_24) a32Bit |= 0x00800000;
8002 if (fCompatibilityOptions_Unknown1_25) a32Bit |= 0x01000000;
8003 if (fCompatibilityOptions_Unknown1_26) a32Bit |= 0x02000000;
8004 if (fCompatibilityOptions_Unknown1_27) a32Bit |= 0x04000000;
8005 if (fCompatibilityOptions_Unknown1_28) a32Bit |= 0x08000000;
8006 if (fCompatibilityOptions_Unknown1_29) a32Bit |= 0x10000000;
8007 if (fCompatibilityOptions_Unknown1_30) a32Bit |= 0x20000000;
8008 if (fCompatibilityOptions_Unknown1_31) a32Bit |= 0x40000000;
8009 if (fUsePrinterMetrics) a32Bit |= 0x80000000;
8010 return a32Bit;
8011}
8012
8013// i#78591#
8015{
8016 fCompatibilityOptions_Unknown2_1 = ( a32Bit & 0x00000001 );
8017 fCompatibilityOptions_Unknown2_2 = ( a32Bit & 0x00000002 ) >> 1 ;
8018 fDontUseHTMLAutoSpacing = ( a32Bit & 0x00000004 ) >> 2 ;
8019 fCompatibilityOptions_Unknown2_4 = ( a32Bit & 0x00000008 ) >> 3 ;
8020 fCompatibilityOptions_Unknown2_5 = ( a32Bit & 0x00000010 ) >> 4 ;
8021 fCompatibilityOptions_Unknown2_6 = ( a32Bit & 0x00000020 ) >> 5 ;
8022 fCompatibilityOptions_Unknown2_7 = ( a32Bit & 0x00000040 ) >> 6 ;
8023 fCompatibilityOptions_Unknown2_8 = ( a32Bit & 0x00000080 ) >> 7 ;
8024 fCompatibilityOptions_Unknown2_9 = ( a32Bit & 0x00000100 ) >> 8 ;
8025 fCompatibilityOptions_Unknown2_10 = ( a32Bit & 0x00000200 ) >> 9 ;
8026 fDontBreakWrappedTables = ( a32Bit & 0x00000400 ) >> 10 ;
8027 fCompatibilityOptions_Unknown2_12 = ( a32Bit & 0x00000800 ) >> 11 ;
8028 fCompatibilityOptions_Unknown2_13 = ( a32Bit & 0x00001000 ) >> 12 ;
8029 fCompatibilityOptions_Unknown2_14 = ( a32Bit & 0x00002000 ) >> 13 ;
8030 fCompatibilityOptions_Unknown2_15 = ( a32Bit & 0x00004000 ) >> 14 ;
8031 fCompatibilityOptions_Unknown2_16 = ( a32Bit & 0x00008000 ) >> 15 ;
8032 fCompatibilityOptions_Unknown2_17 = ( a32Bit & 0x00010000 ) >> 16 ;
8033 fCompatibilityOptions_Unknown2_18 = ( a32Bit & 0x00020000 ) >> 17 ;
8034 fCompatibilityOptions_Unknown2_19 = ( a32Bit & 0x00040000 ) >> 18 ;
8035 fCompatibilityOptions_Unknown2_20 = ( a32Bit & 0x00080000 ) >> 19 ;
8036 fCompatibilityOptions_Unknown2_21 = ( a32Bit & 0x00100000 ) >> 20 ;
8037 fCompatibilityOptions_Unknown2_22 = ( a32Bit & 0x00200000 ) >> 21 ;
8038 fCompatibilityOptions_Unknown2_23 = ( a32Bit & 0x00400000 ) >> 22 ;
8039 fCompatibilityOptions_Unknown2_24 = ( a32Bit & 0x00800800 ) >> 23 ;
8040 fCompatibilityOptions_Unknown2_25 = ( a32Bit & 0x01000800 ) >> 24 ;
8041 fCompatibilityOptions_Unknown2_26 = ( a32Bit & 0x02000800 ) >> 25 ;
8042 fCompatibilityOptions_Unknown2_27 = ( a32Bit & 0x04000800 ) >> 26 ;
8043 fCompatibilityOptions_Unknown2_28 = ( a32Bit & 0x08000800 ) >> 27 ;
8044 fCompatibilityOptions_Unknown2_29 = ( a32Bit & 0x10000800 ) >> 28 ;
8045 fCompatibilityOptions_Unknown2_30 = ( a32Bit & 0x20000800 ) >> 29 ;
8046 fCompatibilityOptions_Unknown2_31 = ( a32Bit & 0x40000800 ) >> 30 ;
8047 fCompatibilityOptions_Unknown2_32 = ( a32Bit & 0x80000000 ) >> 31 ;
8048}
8049
8051{
8052 sal_uInt32 a32Bit = 0;
8053 if (fCompatibilityOptions_Unknown2_1) a32Bit |= 0x00000001;
8054 if (fCompatibilityOptions_Unknown2_2) a32Bit |= 0x00000002;
8055 if (fDontUseHTMLAutoSpacing) a32Bit |= 0x00000004;
8056 if (fCompatibilityOptions_Unknown2_4) a32Bit |= 0x00000008;
8057 if (fCompatibilityOptions_Unknown2_5) a32Bit |= 0x00000010;
8058 if (fCompatibilityOptions_Unknown2_6) a32Bit |= 0x00000020;
8059 if (fCompatibilityOptions_Unknown2_7) a32Bit |= 0x00000040;
8060 if (fCompatibilityOptions_Unknown2_8) a32Bit |= 0x00000080;
8061 if (fCompatibilityOptions_Unknown2_9) a32Bit |= 0x00000100;
8062 if (fCompatibilityOptions_Unknown2_10) a32Bit |= 0x00000200;
8063 if (fDontBreakWrappedTables) a32Bit |= 0x00000400;
8064 if (fCompatibilityOptions_Unknown2_12) a32Bit |= 0x00000800;
8065 if (fCompatibilityOptions_Unknown2_13) a32Bit |= 0x00001000;
8066 //#i42909# set thai "line breaking rules" compatibility option
8067 // pflin, wonder whether bUseThaiLineBreakingRules is correct
8068 // when importing word document.
8069 if (bUseThaiLineBreakingRules) a32Bit |= 0x00002000;
8070 else if (fCompatibilityOptions_Unknown2_14) a32Bit |= 0x00002000;
8071 if (fCompatibilityOptions_Unknown2_15) a32Bit |= 0x00004000;
8072 if (fCompatibilityOptions_Unknown2_16) a32Bit |= 0x00008000;
8073 if (fCompatibilityOptions_Unknown2_17) a32Bit |= 0x00010000;
8074 if (fCompatibilityOptions_Unknown2_18) a32Bit |= 0x00020000;
8075 if (fCompatibilityOptions_Unknown2_19) a32Bit |= 0x00040000;
8076 if (fCompatibilityOptions_Unknown2_20) a32Bit |= 0x00080000;
8077 if (fCompatibilityOptions_Unknown2_21) a32Bit |= 0x00100000;
8078 if (fCompatibilityOptions_Unknown2_22) a32Bit |= 0x00200000;
8079 if (fCompatibilityOptions_Unknown2_23) a32Bit |= 0x00400000;
8080 if (fCompatibilityOptions_Unknown2_24) a32Bit |= 0x00800000;
8081 if (fCompatibilityOptions_Unknown2_25) a32Bit |= 0x01000000;
8082 if (fCompatibilityOptions_Unknown2_26) a32Bit |= 0x02000000;
8083 if (fCompatibilityOptions_Unknown2_27) a32Bit |= 0x04000000;
8084 if (fCompatibilityOptions_Unknown2_28) a32Bit |= 0x08000000;
8085 if (fCompatibilityOptions_Unknown2_29) a32Bit |= 0x10000000;
8086 if (fCompatibilityOptions_Unknown2_30) a32Bit |= 0x20000000;
8087 if (fCompatibilityOptions_Unknown2_31) a32Bit |= 0x40000000;
8088 if (fCompatibilityOptions_Unknown2_32) a32Bit |= 0x80000000;
8089 return a32Bit;
8090}
8091
8092void WW8Dop::Write(SvStream& rStrm, WW8Fib& rFib) const
8093{
8094 const int nMaxDopLen = 610;
8095 sal_uInt32 nLen = 8 == rFib.m_nVersion ? nMaxDopLen : 84;
8096 rFib.m_fcDop = rStrm.Tell();
8097 rFib.m_lcbDop = nLen;
8098
8099 sal_uInt8 aData[ nMaxDopLen ] = {};
8101
8102 // analyse the data
8103 sal_uInt16 a16Bit;
8104 sal_uInt8 a8Bit;
8105
8106 a16Bit = 0; // 0 0x00
8107 if (fFacingPages)
8108 a16Bit |= 0x0001;
8109 if (fWidowControl)
8110 a16Bit |= 0x0002;
8111 if (fPMHMainDoc)
8112 a16Bit |= 0x0004;
8113 a16Bit |= ( 0x0018 & (grfSuppression << 3));
8114 a16Bit |= ( 0x0060 & (fpc << 5));
8115 a16Bit |= ( 0xff00 & (grpfIhdt << 8));
8116 Set_UInt16( pData, a16Bit );
8117
8118 a16Bit = 0; // 2 0x02
8119 a16Bit |= ( 0x0003 & rncFootnote );
8120 a16Bit |= ( ~0x0003 & (nFootnote << 2));
8121 Set_UInt16( pData, a16Bit );
8122
8123 a8Bit = 0; // 4 0x04
8124 if( fOutlineDirtySave ) a8Bit |= 0x01;
8125 Set_UInt8( pData, a8Bit );
8126
8127 a8Bit = 0; // 5 0x05
8128 if( fOnlyMacPics ) a8Bit |= 0x01;
8129 if( fOnlyWinPics ) a8Bit |= 0x02;
8130 if( fLabelDoc ) a8Bit |= 0x04;
8131 if( fHyphCapitals ) a8Bit |= 0x08;
8132 if( fAutoHyphen ) a8Bit |= 0x10;
8133 if( fFormNoFields ) a8Bit |= 0x20;
8134 if( fLinkStyles ) a8Bit |= 0x40;
8135 if( fRevMarking ) a8Bit |= 0x80;
8136 Set_UInt8( pData, a8Bit );
8137
8138 a8Bit = 0; // 6 0x06
8139 if( fBackup ) a8Bit |= 0x01;
8140 if( fExactCWords ) a8Bit |= 0x02;
8141 if( fPagHidden ) a8Bit |= 0x04;
8142 if( fPagResults ) a8Bit |= 0x08;
8143 if( fLockAtn ) a8Bit |= 0x10;
8144 if( fMirrorMargins ) a8Bit |= 0x20;
8145 if( fReadOnlyRecommended ) a8Bit |= 0x40;
8146 if( fDfltTrueType ) a8Bit |= 0x80;
8147 Set_UInt8( pData, a8Bit );
8148
8149 a8Bit = 0; // 7 0x07
8150 if( fPagSuppressTopSpacing ) a8Bit |= 0x01;
8151 if( fProtEnabled ) a8Bit |= 0x02;
8152 if( fDispFormFieldSel ) a8Bit |= 0x04;
8153 if( fRMView ) a8Bit |= 0x08;
8154 if( fRMPrint ) a8Bit |= 0x10;
8155 if( fWriteReservation ) a8Bit |= 0x20;
8156 if( fLockRev ) a8Bit |= 0x40;
8157 if( fEmbedFonts ) a8Bit |= 0x80;
8158 Set_UInt8( pData, a8Bit );
8159
8160 a8Bit = 0; // 8 0x08
8161 if( copts_fNoTabForInd ) a8Bit |= 0x01;
8162 if( copts_fNoSpaceRaiseLower ) a8Bit |= 0x02;
8163 if( copts_fSuppressSpbfAfterPgBrk ) a8Bit |= 0x04;
8164 if( copts_fWrapTrailSpaces ) a8Bit |= 0x08;
8165 if( copts_fMapPrintTextColor ) a8Bit |= 0x10;
8166 if( copts_fNoColumnBalance ) a8Bit |= 0x20;
8167 if( copts_fConvMailMergeEsc ) a8Bit |= 0x40;
8168 if( copts_fSuppressTopSpacing ) a8Bit |= 0x80;
8169 Set_UInt8( pData, a8Bit );
8170
8171 a8Bit = 0; // 9 0x09
8172 if( copts_fOrigWordTableRules ) a8Bit |= 0x01;
8173 if( copts_fTransparentMetafiles ) a8Bit |= 0x02;
8174 if( copts_fShowBreaksInFrames ) a8Bit |= 0x04;
8175 if( copts_fSwapBordersFacingPgs ) a8Bit |= 0x08;
8176 if( copts_fExpShRtn ) a8Bit |= 0x20; // #i56856#
8177 Set_UInt8( pData, a8Bit );
8178
8179 Set_UInt16( pData, dxaTab ); // 10 0x0a
8180 Set_UInt16( pData, wSpare ); // 12 0x0c
8181 Set_UInt16( pData, dxaHotZ ); // 14 0x0e
8182 Set_UInt16( pData, cConsecHypLim ); // 16 0x10
8183 Set_UInt16( pData, wSpare2 ); // 18 0x12
8184 Set_UInt32( pData, dttmCreated ); // 20 0x14
8185 Set_UInt32( pData, dttmRevised ); // 24 0x18
8186 Set_UInt32( pData, dttmLastPrint ); // 28 0x1c
8187 Set_UInt16( pData, nRevision ); // 32 0x20
8188 Set_UInt32( pData, tmEdited ); // 34 0x22
8189 Set_UInt32( pData, cWords ); // 38 0x26
8190 Set_UInt32( pData, cCh ); // 42 0x2a
8191 Set_UInt16( pData, cPg ); // 46 0x2e
8192 Set_UInt32( pData, cParas ); // 48 0x30
8193
8194 a16Bit = 0; // 52 0x34
8195 a16Bit |= ( 0x0003 & rncEdn );
8196 a16Bit |= (~0x0003 & ( nEdn << 2));
8197 Set_UInt16( pData, a16Bit );
8198
8199 a16Bit = 0; // 54 0x36
8200 a16Bit |= (0x0003 & epc );
8201 a16Bit |= (0x003c & (nfcFootnoteRef << 2));
8202 a16Bit |= (0x03c0 & (nfcEdnRef << 6));
8203 if( fPrintFormData ) a16Bit |= 0x0400;
8204 if( fSaveFormData ) a16Bit |= 0x0800;
8205 if( fShadeFormData ) a16Bit |= 0x1000;
8206 if( fWCFootnoteEdn ) a16Bit |= 0x8000;
8207 Set_UInt16( pData, a16Bit );
8208
8209 Set_UInt32( pData, cLines ); // 56 0x38
8210 Set_UInt32( pData, cWordsFootnoteEnd ); // 60 0x3c
8211 Set_UInt32( pData, cChFootnoteEdn ); // 64 0x40
8212 Set_UInt16( pData, cPgFootnoteEdn ); // 68 0x44
8213 Set_UInt32( pData, cParasFootnoteEdn ); // 70 0x46
8214 Set_UInt32( pData, cLinesFootnoteEdn ); // 74 0x4a
8215 Set_UInt32( pData, lKeyProtDoc ); // 78 0x4e
8216
8217 a16Bit = 0; // 82 0x52
8218 if (wvkSaved)
8219 a16Bit |= 0x0007;
8220 a16Bit |= (0x0ff8 & (wScaleSaved << 3));
8221 a16Bit |= (0x3000 & (zkSaved << 12));
8222 if (iGutterPos)
8223 {
8224 // Last bit: gutter at top.
8225 a16Bit |= 0x8000;
8226 }
8227 Set_UInt16( pData, a16Bit );
8228
8229 if( 8 == rFib.m_nVersion )
8230 {
8232
8233 Set_UInt16( pData, adt ); // 88 0x58
8234
8235 doptypography.WriteToMem(pData); // 400 0x190
8236
8237 memcpy( pData, &dogrid, sizeof( WW8_DOGRID ));
8238 pData += sizeof( WW8_DOGRID );
8239
8240 a16Bit = 0x12; // set lvl to 9 // 410 0x19a
8241 if( fHtmlDoc ) a16Bit |= 0x0200;
8242 if( fSnapBorder ) a16Bit |= 0x0800;
8243 if( fIncludeHeader ) a16Bit |= 0x1000;
8244 if( fIncludeFooter ) a16Bit |= 0x2000;
8245 if( fForcePageSizePag ) a16Bit |= 0x4000;
8246 if( fMinFontSizePag ) a16Bit |= 0x8000;
8247 Set_UInt16( pData, a16Bit );
8248
8249 a16Bit = 0; // 412 0x19c
8250 if( fHaveVersions ) a16Bit |= 0x0001;
8251 if( fAutoVersion ) a16Bit |= 0x0002;
8252 Set_UInt16( pData, a16Bit );
8253
8254 pData += 12; // 414 0x19e
8255
8256 Set_UInt32( pData, cChWS ); // 426 0x1aa
8257 Set_UInt32( pData, cChWSFootnoteEdn ); // 430 0x1ae
8258 Set_UInt32( pData, grfDocEvents ); // 434 0x1b2
8259
8260 pData += 4+30+8; // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc
8261
8262 Set_UInt32( pData, cDBC ); // 480 0x1e0
8263 Set_UInt32( pData, cDBCFootnoteEdn ); // 484 0x1e4
8264
8265 pData += 1 * sizeof( sal_Int32); // 488 0x1e8
8266
8267 Set_UInt16( pData, nfcFootnoteRef ); // 492 0x1ec
8268 Set_UInt16( pData, nfcEdnRef ); // 494 0x1ee
8269 Set_UInt16( pData, hpsZoomFontPag ); // 496 0x1f0
8270 Set_UInt16( pData, dywDispPag ); // 498 0x1f2
8271
8272 //500 -> 508, Appear to be repeated here in 2000+
8273 pData += 8;
8276 pData += 32;
8277
8278 a16Bit = 0;
8279 if (fEmbedFactoids)
8280 a16Bit |= 0x8;
8282 a16Bit |= 0x1000;
8283 //Word XP at least requires fAcetateShowMarkup to honour fAcetateShowAtn
8284 if (fAcetateShowAtn)
8285 {
8286 a16Bit |= 0x1000;
8287 a16Bit |= 0x2000;
8288 }
8289 Set_UInt16(pData, a16Bit);
8290
8291 pData += 48;
8292 a16Bit = 0x0080;
8293 Set_UInt16(pData, a16Bit);
8294 }
8295 rStrm.WriteBytes(aData, nLen);
8296}
8297
8299{
8300 sal_uInt16 a16Bit = Get_UShort(pData);
8301 m_fKerningPunct = (a16Bit & 0x0001);
8302 m_iJustification = (a16Bit & 0x0006) >> 1;
8303 m_iLevelOfKinsoku = (a16Bit & 0x0018) >> 3;
8304 m_f2on1 = (a16Bit & 0x0020) >> 5;
8305 m_reserved1 = (a16Bit & 0x03C0) >> 6;
8306 m_reserved2 = (a16Bit & 0xFC00) >> 10;
8307
8310
8311 sal_Int16 i;
8312 for (i=0; i < nMaxFollowing; ++i)
8314 for (i=0; i < nMaxLeading; ++i)
8316
8319 else
8321
8324 else
8326
8327}
8328
8330{
8331 sal_uInt16 a16Bit = sal_uInt16(m_fKerningPunct);
8332 a16Bit |= (m_iJustification << 1) & 0x0006;
8333 a16Bit |= (m_iLevelOfKinsoku << 3) & 0x0018;
8334 a16Bit |= (int(m_f2on1) << 5) & 0x0020;
8335 a16Bit |= (m_reserved1 << 6) & 0x03C0;
8336 a16Bit |= (m_reserved2 << 10) & 0xFC00;
8337 Set_UInt16(pData,a16Bit);
8338
8341
8342 sal_Int16 i;
8343 for (i=0; i < nMaxFollowing; ++i)
8345 for (i=0; i < nMaxLeading; ++i)
8347}
8348
8350{
8352 //I have assumed people's republic/taiwan == simplified/traditional
8353
8354 //This isn't a documented issue, so we might have it all wrong,
8355 //i.e. i.e. what's with the powers of two ?
8356
8357 /*
8358 One example of 3 for reserved1 which was really Japanese, perhaps last bit
8359 is for some other use ?, or redundant. If more examples trigger the assert
8360 we might be able to figure it out.
8361 */
8362 switch(m_reserved1 & 0xE)
8363 {
8364 case 2: //Japan
8366 break;
8367 case 4: //Chinese (People's Republic)
8369 break;
8370 case 6: //Korean
8372 break;
8373 case 8: //Chinese (Taiwan)
8375 break;
8376 default:
8377 OSL_ENSURE(false, "Unknown MS Asian Typography language, report");
8379 break;
8380 case 0:
8381 //And here we have the possibility that it says 2, but it's really
8382 //a bug and only japanese level 2 has been selected after a custom
8383 //version was chosen on last save!
8385 break;
8386 }
8387 return nLang;
8388}
8389
8390// Sprms
8391
8392sal_uInt16 wwSprmParser::GetSprmTailLen(sal_uInt16 nId, const sal_uInt8* pSprm, sal_Int32 nRemLen)
8393 const
8394{
8395 SprmInfo aSprm = GetSprmInfo(nId);
8396 sal_uInt16 nL = 0; // number of Bytes to read
8397
8398 //sprmPChgTabs
8399 switch( nId )
8400 {
8401 case 23:
8402 case 0xC615:
8403 if( pSprm[1 + mnDelta] != 255 )
8404 nL = static_cast< sal_uInt16 >(pSprm[1 + mnDelta] + aSprm.nLen);
8405 else
8406 {
8407 sal_uInt8 nDelIdx = 2 + mnDelta;
8408 sal_uInt8 nDel = nDelIdx < nRemLen ? pSprm[nDelIdx] : 0;
8409 sal_uInt8 nInsIdx = 3 + mnDelta + 4 * nDel;
8410 sal_uInt8 nIns = nInsIdx < nRemLen ? pSprm[nInsIdx] : 0;
8411
8412 nL = 2 + 4 * nDel + 3 * nIns;
8413 }
8414 break;
8415 default:
8416 switch (aSprm.nVari)
8417 {
8418 case L_FIX:
8419 nL = aSprm.nLen; // Excl. Token
8420 break;
8421 case L_VAR:
8422 // Variable 1-Byte Length
8423 // parameter length (i.e. excluding token and length byte)
8424 nL = static_cast< sal_uInt16 >(pSprm[1 + mnDelta] + aSprm.nLen);
8425 break;
8426 case L_VAR2:
8427 {
8428 // Variable 2-Byte Length
8429 // For sprmTDefTable and sprmTDefTable10, the length of the
8430 // parameter plus 1 is recorded in the two bytes beginning
8431 // at offset (WW7-) 1 or (WW8+) 2
8432 sal_uInt8 nIndex = 1 + mnDelta;
8433 sal_uInt16 nCount;
8434 if (nIndex + 1 >= nRemLen)
8435 {
8436 SAL_WARN("sw.ww8", "sprm longer than remaining bytes, doc or parser is wrong");
8437 nCount = 0;
8438 }
8439 else
8440 {
8441 nCount = SVBT16ToUInt16(&pSprm[nIndex]);
8442 SAL_WARN_IF(nCount < 1, "sw.ww8", "length should have been at least 1");
8443 if (nCount)
8444 --nCount;
8445 }
8446 nL = static_cast<sal_uInt16>(nCount + aSprm.nLen);
8447 break;
8448 }
8449 default:
8450 OSL_ENSURE(false, "Unknown sprm variant");
8451 break;
8452 }
8453 break;
8454 }
8455 return nL;
8456}
8457
8458// one or two bytes at the beginning at the sprm id
8459sal_uInt16 wwSprmParser::GetSprmId(const sal_uInt8* pSp) const
8460{
8461 OSL_ENSURE(pSp, "Why GetSprmId with pSp of 0");
8462 if (!pSp)
8463 return 0;
8464
8465 sal_uInt16 nId = 0;
8466
8468 {
8469 nId = *pSp; // [0..0xff]
8470 }
8471 else
8472 {
8473 nId = SVBT16ToUInt16(pSp);
8474 if (0x0800 > nId)
8475 nId = 0;
8476 }
8477
8478 return nId;
8479}
8480
8481// with tokens and length byte
8482sal_Int32 wwSprmParser::GetSprmSize(sal_uInt16 nId, const sal_uInt8* pSprm, sal_Int32 nRemLen) const
8483{
8484 return GetSprmTailLen(nId, pSprm, nRemLen) + 1 + mnDelta + SprmDataOfs(nId);
8485}
8486
8488{
8489 return GetSprmInfo(nId).nVari;
8490}
8491
8492sal_Int32 wwSprmParser::DistanceToData(sal_uInt16 nId) const
8493{
8494 return 1 + mnDelta + SprmDataOfs(nId);
8495}
8496
8498 sal_Int32 nLen) const
8499{
8500 while (nLen >= MinSprmLen())
8501 {
8502 const sal_uInt16 nCurrentId = GetSprmId(pSprms);
8503 // set pointer to data
8504 sal_Int32 nSize = GetSprmSize(nCurrentId, pSprms, nLen);
8505
8506 bool bValid = nSize <= nLen;
8507
8508 SAL_WARN_IF(!bValid, "sw.ww8",
8509 "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " <<
8510 nSize << " vs " << nLen << "doc or parser is wrong");
8511
8512 if (nCurrentId == nId && bValid) // Sprm found
8513 {
8514 sal_Int32 nFixedLen = DistanceToData(nId);
8515 return SprmResult(pSprms + nFixedLen, nSize - nFixedLen);
8516 }
8517
8518 //Clip to available size if wrong
8519 nSize = std::min(nSize, nLen);
8520 pSprms += nSize;
8521 nLen -= nSize;
8522 }
8523 // Sprm not found
8524 return SprmResult();
8525}
8526
8528 bkc(2), fTitlePage(0), fAutoPgn(0), nfcPgn(0), fUnlocked(0), cnsPgn(0),
8529 fPgnRestart(0), fEndNote(1), lnc(0), grpfIhdt(0), nLnnMod(0), dxaLnn(0),
8530 dxaPgn(720), dyaPgn(720), fLBetween(0), vjc(0), dmBinFirst(0),
8531 dmBinOther(0), dmPaperReq(0), fPropRMark(0), ibstPropRMark(0),
8532 dttmPropRMark(0), dxtCharSpace(0), dyaLinePitch(0), clm(0), reserved1(0),
8533 dmOrientPage(0), iHeadingPgn(0), pgnStart(1), lnnMin(0), wTextFlow(0),
8534 reserved2(0), pgbApplyTo(0), pgbPageDepth(0), pgbOffsetFrom(0),
8535 xaPage(lLetterWidth), yaPage(lLetterHeight), xaPageNUp(lLetterWidth), yaPageNUp(lLetterHeight),
8536 dxaLeft(1800), dxaRight(1800), dyaTop(1440), dyaBottom(1440), dzaGutter(0),
8537 dyaHdrTop(720), dyaHdrBottom(720), ccolM1(0), fEvenlySpaced(1),
8538 reserved3(0), fBiDi(0), fFacingCol(0), fRTLGutter(0), fRTLAlignment(0),
8539 dxaColumns(720), dxaColumnWidth(0), dmOrientFirst(0), fLayout(0),
8540 reserved4(0)
8541{
8542}
8543
8544bool checkRead(SvStream &rSt, void *pDest, sal_uInt32 nLength)
8545{
8546 return (rSt.ReadBytes(pDest, nLength) == static_cast<std::size_t>(nLength));
8547}
8548
8549#ifdef OSL_BIGENDIAN
8550void swapEndian(sal_Unicode *pString)
8551{
8552 for (sal_Unicode *pWork = pString; *pWork; ++pWork)
8553 *pWork = OSL_SWAPWORD(*pWork);
8554}
8555#endif
8556
8557/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::ptrdiff_t mnIdx
const LanguageTag & GetLanguageTag() const
static const AllSettings & GetSettings()
LanguageType getLanguageType(bool bResolveSystem=true) const
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
const OUString & getNumDecimalSep() const
[MS-OSHARED] FactoidType: one smart tag type.
Definition: ww8struc.hxx:1096
OUString m_aUri
Definition: ww8struc.hxx:1103
OUString m_aTag
Definition: ww8struc.hxx:1104
sal_uInt32 m_nId
Definition: ww8struc.hxx:1102
void Write(WW8Export &rExport)
Definition: ww8scan.cxx:6733
void Read(SvStream &rStream)
Definition: ww8scan.cxx:6723
void Write(WW8Export &rExport)
Definition: ww8scan.cxx:6782
void Read(SvStream &rStream)
Definition: ww8scan.cxx:6747
std::vector< MSOFactoidType > m_aFactoidTypes
Definition: ww8struc.hxx:1114
std::vector< OUString > m_aStringTable
Definition: ww8struc.hxx:1115
[MS-OSHARED] PropertyBag: stores information about one smart tag.
Definition: ww8struc.hxx:1134
bool Read(SvStream &rStream)
Definition: ww8scan.cxx:6819
void Write(WW8Export &rExport)
Definition: ww8scan.cxx:6843
std::vector< MSOProperty > m_aProperties
Definition: ww8struc.hxx:1142
sal_uInt16 m_nId
Matches MSOFactoidType::m_nId in MSOPropertyBagStore::m_aFactoidTypes.
Definition: ww8struc.hxx:1141
[MS-OSHARED] Property: stores information about one smart-tag key/value.
Definition: ww8struc.hxx:1120
sal_uInt32 m_nValue
Index into MSOPropertyBagStore::m_aStringTable.
Definition: ww8struc.hxx:1129
void Write(SvStream &rStream)
Definition: ww8scan.cxx:6808
sal_uInt32 m_nKey
Index into MSOPropertyBagStore::m_aStringTable.
Definition: ww8struc.hxx:1127
void Read(SvStream &rStream)
Definition: ww8scan.cxx:6802
static bool isCJK(LanguageType nLang)
sal_uInt64 Tell() const
bool good() const
virtual sal_uInt64 TellEnd()
SvStream & ReadInt16(sal_Int16 &rInt16)
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStream & WriteUInt16(sal_uInt16 nUInt16)
SvStream & WriteUInt32(sal_uInt32 nUInt32)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
SvStream & ReadUtf16(sal_Unicode &rUtf16)
sal_uInt64 Seek(sal_uInt64 nPos)
SvStream & ReadInt32(sal_Int32 &rInt32)
std::size_t ReadBytes(void *pData, std::size_t nSize)
sal_uInt64 SeekRel(sal_Int64 nPos)
ErrCode GetError() const
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
sal_uInt64 remainingSize()
SvStream & ReadUChar(unsigned char &rChar)
SvStream & WriteStream(SvStream &rStream)
static Color GetCol(sal_uInt8 nIco)
Definition: ww8par6.cxx:121
static void WriteString8(SvStream &rStrm, std::u16string_view rStr, bool bAddZero, rtl_TextEncoding eCodeSet)
Definition: wrtww8.cxx:1769
sal_Int16 m_cchFollowingPunct
Definition: ww8struc.hxx:410
void ReadFromMem(sal_uInt8 *&pData)
Definition: ww8scan.cxx:8298
sal_uInt16 m_reserved1
Definition: ww8struc.hxx:384
sal_uInt16 m_iLevelOfKinsoku
Definition: ww8struc.hxx:379
void WriteToMem(sal_uInt8 *&pData) const
Definition: ww8scan.cxx:8329
sal_uInt16 m_fKerningPunct
Definition: ww8struc.hxx:374
sal_uInt16 m_f2on1
Definition: ww8struc.hxx:383
sal_Int16 m_cchLeadingPunct
Definition: ww8struc.hxx:411
LanguageType GetConvertedLang() const
Definition: ww8scan.cxx:8349
sal_Unicode m_rgxchLPunct[nMaxLeading]
Definition: ww8struc.hxx:416
sal_Unicode m_rgxchFPunct[nMaxFollowing]
Definition: ww8struc.hxx:414
sal_uInt16 m_iJustification
Definition: ww8struc.hxx:375
sal_uInt16 m_reserved2
Definition: ww8struc.hxx:385
Exporter of the binary Word file formats.
Definition: wrtww8.hxx:997
SvStream * m_pTableStrm
Definition: wrtww8.hxx:1001
FIB - the File Information Block.
Definition: ww8scan.hxx:1106
sal_Int32 m_lcbSttbListNames
Definition: ww8scan.hxx:1479
sal_uInt16 m_nFib_actual
Definition: ww8scan.hxx:1534
WW8_CP m_ccpHdr
Definition: ww8scan.hxx:1212
WW8_FC m_fcPlcfspl
Definition: ww8scan.hxx:1439
sal_Int32 m_lcbPlcfHdrtxbxBkd
Definition: ww8scan.hxx:1472
WW8_FC m_fcPlcfhdd
Definition: ww8scan.hxx:1289
sal_Int32 m_lcbSttbfffn
Definition: ww8scan.hxx:1303
sal_Int32 m_lcbPlcfspaHdr
Definition: ww8scan.hxx:1394
WW8_FC m_fcPlcfglsy
Definition: ww8scan.hxx:1284
WW8_FC m_fcPlcfAtnbkf
Definition: ww8scan.hxx:1397
WW8_FC m_fcPlcfsed
Definition: ww8scan.hxx:1267
WW8_FC m_fcPlcfspaHdr
Definition: ww8scan.hxx:1391
sal_Int32 m_lcbPlcftxbxBkd
Definition: ww8scan.hxx:1470
sal_Int32 m_lcbPlcfAtnbkf
Definition: ww8scan.hxx:1398
sal_Int32 m_lcbSttbAutoCaption
Definition: ww8scan.hxx:1434
WW8_FC m_fcSttbfffn
Definition: ww8scan.hxx:1302
sal_Int32 m_lcbSttbfRMark
Definition: ww8scan.hxx:1429
sal_Int32 m_lcbPlcfHdrtxbxText
Definition: ww8scan.hxx:1448
WW8_FC m_fcPlcffactoid
0x4ba Plcffactoid offset.
Definition: ww8scan.hxx:1513
bool m_fComplex
Definition: ww8scan.hxx:1150
WW8_FC m_fcFormFieldSttbf
Definition: ww8scan.hxx:1406
WW8_FC m_fcMac
Definition: ww8scan.hxx:1187
sal_uInt32 m_lcbStwUser
Definition: ww8scan.hxx:1452
bool m_fLoadOverridePage
Definition: ww8scan.hxx:1176
sal_Int32 m_lcbPlfLfo
Definition: ww8scan.hxx:1465
WW8_FC m_fcPlcftxbxBkd
Definition: ww8scan.hxx:1469
sal_Int32 m_lcbSttbfbkmk
Definition: ww8scan.hxx:1321
sal_Int32 m_lcbSttbfCaption
Definition: ww8scan.hxx:1431
sal_Int32 m_lcbFormFieldSttbf
Definition: ww8scan.hxx:1407
sal_Int32 m_lcbPlcfpgdEdn
Definition: ww8scan.hxx:1420
LanguageType m_lid
Definition: ww8scan.hxx:1145
ErrCode m_nFibError
Definition: ww8scan.hxx:1123
WW8Fib(SvStream &rStrm, sal_uInt8 nWantedVersion, sal_uInt32 nOffset=0)
Definition: ww8scan.cxx:5853
WW8_FC m_fcPlcfAtnbkl
Definition: ww8scan.hxx:1400
WW8_FC m_fcWss
Definition: ww8scan.hxx:1347
WW8_FC m_fcPrEnvPort
Definition: ww8scan.hxx:1341
bool m_fEncrypted
Definition: ww8scan.hxx:1153
LanguageType m_lidFE
Definition: ww8scan.hxx:1200
sal_uInt32 m_lcbAtrdExtra
Definition: ww8scan.hxx:1486
WW8_CP m_ccpFootnote
Definition: ww8scan.hxx:1211
WW8_FC m_fcPlcfsea
Definition: ww8scan.hxx:1299
WW8_CP m_ccpEdn
Definition: ww8scan.hxx:1215
sal_uInt32 m_lcbPlcfBklFactoid
0x446 smart-tag bookmark ends length.
Definition: ww8scan.hxx:1504
WW8_FC m_fcPlcfpgdEdn
Definition: ww8scan.hxx:1419
sal_uInt32 m_lcbCmds
Definition: ww8scan.hxx:1330
bool m_fFuturesavedUndo
Definition: ww8scan.hxx:1177
WW8_FC m_fcFactoidData
0x44a smart tag data offset.
Definition: ww8scan.hxx:1506
WW8_FC m_fcPlfLfo
Definition: ww8scan.hxx:1464
sal_Int32 m_lcbPlcfmcr
Definition: ww8scan.hxx:1333
WW8_FC m_fcPlcfphe
Definition: ww8scan.hxx:1275
bool m_fWord97Saved
Definition: ww8scan.hxx:1178
sal_uInt16 m_nFib
Definition: ww8scan.hxx:1143
sal_Int32 m_lcbPlcftxbxText
Definition: ww8scan.hxx:1444
sal_uInt32 m_lcbFactoidData
0x44e smart tag data length.
Definition: ww8scan.hxx:1508
sal_Int32 m_lcbPlcffldEdn
Definition: ww8scan.hxx:1417
void Write(SvStream &rStrm)
Definition: ww8scan.cxx:6430
WW8_FC m_fcAutosaveSource
Definition: ww8scan.hxx:1364
sal_Int32 m_lcbGrpStAtnOwners
Definition: ww8scan.hxx:1368
sal_Int32 m_lcbSttbfAtnbkmk
Definition: ww8scan.hxx:1371
WW8_CP m_ccpHdrTxbx
Definition: ww8scan.hxx:1217
sal_Int32 m_lcbPlcfpgdFootnote
Definition: ww8scan.hxx:1361
sal_Int32 m_lcbPlcfbteChpx
Definition: ww8scan.hxx:1294
sal_Int32 m_lcbPlcfspaMom
Definition: ww8scan.hxx:1389
WW8_FC m_fcPlcftxbxText
Definition: ww8scan.hxx:1443
void WriteHeader(SvStream &rStrm)
Definition: ww8scan.cxx:6348
sal_Int32 m_lcbPlcfbkf
Definition: ww8scan.hxx:1324
WW8_FC m_fcPlcfTch
Definition: ww8scan.hxx:1481
sal_Int32 m_fcIslandFirst
Definition: ww8scan.hxx:1238
sal_Int32 m_pnChpFirst
Definition: ww8scan.hxx:1526
sal_Int32 m_lcbPlcfhdd
Definition: ww8scan.hxx:1290
sal_uInt8 m_envr
Definition: ww8scan.hxx:1172
bool m_fHasPic
Definition: ww8scan.hxx:1151
WW8_FC m_fcSttbttmbd
Definition: ww8scan.hxx:1453
sal_uInt16 m_cQuickSaves
Definition: ww8scan.hxx:1152
sal_Int32 m_pnPapFirst
Definition: ww8scan.hxx:1527
sal_Int32 m_lcbPlcffldMcr
Definition: ww8scan.hxx:1318
WW8_FC m_fcPlcffldEdn
Definition: ww8scan.hxx:1416
sal_Int32 m_lcbStshfOrig
Definition: ww8scan.hxx:1250
WW8_FC m_fcPlcffldAtn
Definition: ww8scan.hxx:1314
sal_uInt16 m_nProduct
Definition: ww8scan.hxx:1144
WW8_FC m_fcSttbfAssoc
Definition: ww8scan.hxx:1354
WW8_FC m_fcStshf
Definition: ww8scan.hxx:1251
bool m_fWhichTableStm
Definition: ww8scan.hxx:1154
sal_Int32 m_lcbPlcfAtnbkl
Definition: ww8scan.hxx:1401
sal_uInt16 m_cfclcb
Definition: ww8scan.hxx:1240
sal_Int32 m_lcbSttbFnm
Definition: ww8scan.hxx:1457
sal_Int32 m_lcbSttbfmcr
Definition: ww8scan.hxx:1336
sal_Int32 m_pnLvcFirst
Definition: ww8scan.hxx:1233
sal_uInt16 m_chse
Definition: ww8scan.hxx:1182
sal_uInt8 m_nVersion
Program-Version asked for by us: in Ctor we check if it matches the value of nFib.
Definition: ww8scan.hxx:1119
sal_uInt16 m_clw
Definition: ww8scan.hxx:1202
WW8_FC m_fcAtrdExtra
Definition: ww8scan.hxx:1485
WW8_FC m_fcPlcfHdrtxbxText
Definition: ww8scan.hxx:1447
sal_Int32 m_lcbPlcfphe
Definition: ww8scan.hxx:1276
bool m_fWord2000Saved
Definition: ww8scan.hxx:1179
sal_Int32 m_pnFbpPapFirst
Definition: ww8scan.hxx:1224
WW8_FC m_fcSttbfmcr
Definition: ww8scan.hxx:1335
WW8_FC m_fcPlcfandRef
Definition: ww8scan.hxx:1261
WW8_FC m_fcSttbfBkmkFactoid
0x42a smart-tag bookmark string table offset.
Definition: ww8scan.hxx:1491
sal_uInt16 m_wMagicCreated
Definition: ww8scan.hxx:1193
sal_uInt16 m_cswNew
Specifies the count of 16-bit values corresponding to fibRgCswNew that follow.
Definition: ww8scan.hxx:1242
sal_Int32 m_lcbAutosaveSource
Definition: ww8scan.hxx:1365
sal_Int32 m_lcbPlcfandText
Definition: ww8scan.hxx:1265
sal_Int32 m_lcbPrDrvr
Definition: ww8scan.hxx:1339
WW8_FC m_fcPlcffndText
Definition: ww8scan.hxx:1257
WW8_PN m_pnNext
Definition: ww8scan.hxx:1146
WW8_CP m_ccpTxbx
Definition: ww8scan.hxx:1216
sal_uInt32 m_lcbPlcfBkfFactoid
0x436 smart-tag bookmark ends length.
Definition: ww8scan.hxx:1497
WW8_FC m_fcPrEnvLand
Definition: ww8scan.hxx:1344
WW8_FC m_fcSttbfglsy
Definition: ww8scan.hxx:1279
WW8_FC m_fcPms
Definition: ww8scan.hxx:1403
sal_uInt16 m_csw
Definition: ww8scan.hxx:1190
bool m_fExtChar
Definition: ww8scan.hxx:1164
sal_uInt16 m_wIdent
Definition: ww8scan.hxx:1129
WW8_FC m_fcPlcfspaMom
Definition: ww8scan.hxx:1386
bool m_fGlsy
Definition: ww8scan.hxx:1149
WW8_FC m_fcPlcfpad
Definition: ww8scan.hxx:1270
WW8_FC m_fcSttbfCaption
Definition: ww8scan.hxx:1430
sal_Int32 m_lcbPrEnvPort
Definition: ww8scan.hxx:1342
sal_uInt32 m_lcbSttbfBkmkFactoid
0x42e smart-tag bookmark string table length.
Definition: ww8scan.hxx:1493
WW8_FC m_fcStshfOrig
Definition: ww8scan.hxx:1247
sal_Int32 m_cpnBteLvc
Definition: ww8scan.hxx:1235
WW8_FC m_fcStwUser
Definition: ww8scan.hxx:1451
sal_Int32 m_lcbPlcfwkb
Definition: ww8scan.hxx:1437
sal_Int32 m_lcbPlcfpad
Definition: ww8scan.hxx:1271
WW8_FC m_fcPlcfHdrtxbxBkd
Definition: ww8scan.hxx:1471
sal_Int32 m_lcbPlcfdoaMom
Definition: ww8scan.hxx:1378
sal_Int32 m_lcbPlcfbtePapx
Definition: ww8scan.hxx:1297
ww::WordVersion GetFIBVersion() const
Definition: ww8scan.cxx:5808
WW8_FC m_fcSttbAutoCaption
Definition: ww8scan.hxx:1432
WW8_FC m_fcPlcffldMom
Definition: ww8scan.hxx:1305
WW8_FC m_fcPlcfwkb
Definition: ww8scan.hxx:1436
WW8_FC m_fcPlcfmcr
Definition: ww8scan.hxx:1332
sal_Int32 m_lcbPMS
Definition: ww8scan.hxx:1404
WW8_FC m_fcPlcfbteChpx
Definition: ww8scan.hxx:1293
sal_Int32 m_lcbPlcffldFootnote
Definition: ww8scan.hxx:1312
sal_uInt16 m_wMagicRevised
Definition: ww8scan.hxx:1196
sal_Int32 m_cpnBtePap
Definition: ww8scan.hxx:1529
sal_Int32 m_lcbPlcffldTxbx
Definition: ww8scan.hxx:1446
WW8_FC m_fcPlcfdoaMom
Definition: ww8scan.hxx:1375
WW8_FC m_fcPlcfdoaHdr
Definition: ww8scan.hxx:1380
static rtl_TextEncoding GetFIBCharset(sal_uInt16 chs, LanguageType nLidLocale)
Definition: ww8scan.cxx:6671
WW8_FC m_fcSttbfbkmk
Definition: ww8scan.hxx:1320
WW8_FC m_fcPlcffldFootnote
Definition: ww8scan.hxx:1311
sal_Int32 m_fcIslandLim
Definition: ww8scan.hxx:1239
WW8_FC m_fcSttbListNames
Definition: ww8scan.hxx:1478
sal_uInt32 m_lcbDop
Definition: ww8scan.hxx:1351
WW8_FC m_fcMin
Definition: ww8scan.hxx:1186
WW8_FC m_fcPlcfendText
Definition: ww8scan.hxx:1412
sal_Int32 m_lcbSttbfAssoc
Definition: ww8scan.hxx:1355
sal_Int32 m_lcbPlcfdoaHdr
Definition: ww8scan.hxx:1383
bool m_fReadOnlyRecommended
Definition: ww8scan.hxx:1155
sal_Int32 m_lcbPlcfLst
Definition: ww8scan.hxx:1463
sal_Unicode m_nNumDecimalSep
Definition: ww8scan.hxx:1108
WW8_FC m_fcSttbfAtnbkmk
Definition: ww8scan.hxx:1370
sal_Int32 m_lcbPlcfendText
Definition: ww8scan.hxx:1414
bool m_fFarEast
Definition: ww8scan.hxx:1165
sal_Int32 m_cpnBteChp
Definition: ww8scan.hxx:1528
sal_uInt16 m_nHash
Definition: ww8scan.hxx:1170
WW8_FC m_fcDggInfo
Definition: ww8scan.hxx:1422
WW8_FC m_fcPlcffldMcr
Definition: ww8scan.hxx:1317
bool m_fEmptySpecial
Definition: ww8scan.hxx:1175
sal_Int32 m_lcbPlcffndRef
Definition: ww8scan.hxx:1254
WW8_FC m_fcPlcfpgdFootnote
Definition: ww8scan.hxx:1360
sal_Int32 m_lcbSttbfglsy
Definition: ww8scan.hxx:1280
WW8_FC m_fcPlcfendRef
Definition: ww8scan.hxx:1409
sal_uInt16 m_nKey
Definition: ww8scan.hxx:1171
sal_uInt32 m_lcbPlcffactoid
0x4be Plcffactoid offset.
Definition: ww8scan.hxx:1515
sal_Int32 m_pnFbpLvcFirst
Definition: ww8scan.hxx:1229
WW8_FC m_fcPlcffndRef
Definition: ww8scan.hxx:1253
sal_uInt16 m_chseTables
Definition: ww8scan.hxx:1184
sal_Int32 m_lcbPlcffldMom
Definition: ww8scan.hxx:1306
sal_Int32 m_lcbPlcfglsy
Definition: ww8scan.hxx:1285
WW8_FC m_fcPlcffldHdrTxbx
Definition: ww8scan.hxx:1449
WW8_FC m_fcPlcffldHdr
Definition: ww8scan.hxx:1308
WW8_FC m_fcPlcfBkfFactoid
0x432 smart-tag bookmark starts offset.
Definition: ww8scan.hxx:1495
sal_uInt16 m_nFibBack
Definition: ww8scan.hxx:1169
sal_Int32 m_lcbPrEnvLand
Definition: ww8scan.hxx:1345
sal_Int32 m_lcbPlcffldAtn
Definition: ww8scan.hxx:1315
WW8_FC m_fcPlcfbtePapx
Definition: ww8scan.hxx:1296
WW8_FC m_cbMac
Definition: ww8scan.hxx:1207
sal_uInt16 m_wMagicRevisedPrivate
Definition: ww8scan.hxx:1198
sal_Int32 m_lcbPlcffldHdr
Definition: ww8scan.hxx:1309
WW8_FC m_fcPrDrvr
Definition: ww8scan.hxx:1338
WW8_FC m_fcCmds
Definition: ww8scan.hxx:1329
sal_Int32 m_lcbDggInfo
Definition: ww8scan.hxx:1425
WW8_FC m_fcPlcfbkf
Definition: ww8scan.hxx:1323
WW8_FC m_fcGrpStAtnOwners
Definition: ww8scan.hxx:1367
sal_Int32 m_lcbPlcfspl
Definition: ww8scan.hxx:1441
bool m_fObfuscated
Definition: ww8scan.hxx:1167
sal_Int32 m_lcbPlcfbkl
Definition: ww8scan.hxx:1327
sal_Int32 m_lcbClx
Definition: ww8scan.hxx:1358
sal_Int32 m_lcbWss
Definition: ww8scan.hxx:1348
bool m_fWriteReservation
Definition: ww8scan.hxx:1156
WW8_CP m_ccpAtn
Definition: ww8scan.hxx:1214
sal_uInt32 m_lcbSttbttmbd
Definition: ww8scan.hxx:1454
sal_Int32 m_lcbPlcfendRef
Definition: ww8scan.hxx:1410
sal_Int32 m_lcbPlcffldHdrTxbx
Definition: ww8scan.hxx:1450
WW8_FC m_fcSttbfRMark
Definition: ww8scan.hxx:1428
sal_Int32 m_lcbPlcfsed
Definition: ww8scan.hxx:1268
WW8_FC m_fcPlcfandText
Definition: ww8scan.hxx:1264
WW8_FC m_fcHplxsdr
Definition: ww8scan.hxx:1519
WW8_FC m_fcPlcffldTxbx
Definition: ww8scan.hxx:1445
sal_Int32 m_lcbPlcfandRef
Definition: ww8scan.hxx:1262
WW8_FC m_fcPlcfbkl
Definition: ww8scan.hxx:1326
WW8_FC m_fcClx
Definition: ww8scan.hxx:1357
sal_Int32 m_lcbStshf
Definition: ww8scan.hxx:1252
WW8_FC m_fcPlcfLst
Definition: ww8scan.hxx:1462
WW8_FC m_fcDop
Definition: ww8scan.hxx:1350
sal_uInt16 m_wMagicCreatedPrivate
Definition: ww8scan.hxx:1197
WW8_CP m_ccpText
Definition: ww8scan.hxx:1210
bool m_fMac
Definition: ww8scan.hxx:1174
WW8_CP m_ccpMcr
Definition: ww8scan.hxx:1213
sal_Int32 m_lcbPlcfsea
Definition: ww8scan.hxx:1300
WW8_FC m_fcPlcfBklFactoid
0x442 smart-tag bookmark ends offset.
Definition: ww8scan.hxx:1502
bool GetBaseCp(ManTypes nType, WW8_CP *cp) const
Definition: ww8scan.cxx:5745
sal_Int32 m_lcbPlcffndText
Definition: ww8scan.hxx:1258
WW8_FC m_fcSttbFnm
Definition: ww8scan.hxx:1456
bool m_fDot
Definition: ww8scan.hxx:1148
sal_Int32 m_lcbPlcfTch
Definition: ww8scan.hxx:1482
sal_Int32 m_pnFbpChpFirst
Definition: ww8scan.hxx:1220
std::vector< WW8_FFN > m_aFontA
Definition: ww8scan.hxx:1586
const WW8_FFN * GetFont(sal_uInt16 nNum) const
Definition: ww8scan.cxx:7491
WW8Fonts(const WW8Fonts &)=delete
const WW8Fib * m_pWwFib
Definition: ww8scan.hxx:955
void SaveAllPLCFx(WW8PLCFxSaveAll &rSave) const
Definition: ww8scan.cxx:5169
void GetNoSprmEnd(short nIdx, WW8PLCFManResult *pRes) const
Definition: ww8scan.cxx:5321
void TransferOpenSprms(std::stack< sal_uInt16 > &rStack)
Definition: ww8scan.cxx:5341
WW8PLCFx_Cp_FKP * GetPapPLCF() const
Definition: ww8scan.hxx:1002
sal_uInt16 WhereIdx(bool *pbStart, WW8_CP *pPos=nullptr) const
Definition: ww8scan.cxx:5112
WW8PLCFxDesc * m_pPap
Definition: ww8scan.hxx:950
SprmResult HasParaSprm(sal_uInt16 nId) const
Definition: ww8scan.cxx:5602
void SeekPos(tools::Long nNewCp)
Definition: ww8scan.cxx:5158
sal_uInt16 GetId(const WW8PLCFxDesc *p) const
Definition: ww8scan.cxx:4908
bool IsSprmLegalForCategory(sal_uInt16 nSprmId, short nIdx) const
Definition: ww8scan.cxx:5208
ManTypes m_nManType
Definition: ww8scan.hxx:943
WW8_CP m_nCpO
Definition: ww8scan.hxx:939
bool Get(WW8PLCFManResult *pResult) const
Definition: ww8scan.cxx:5546
@ MAN_PLCF_COUNT
Definition: ww8scan.hxx:935
void AdvNoSprm(short nIdx, bool bStart)
Definition: ww8scan.cxx:5470
sal_uInt8 * m_pExtendedAtrds
Definition: ww8scan.hxx:953
sal_uInt16 GetColl() const
Definition: ww8scan.cxx:5586
void RestoreAllPLCFx(const WW8PLCFxSaveAll &rSave)
Definition: ww8scan.cxx:5182
WW8PLCFspecial * m_pFdoa
Definition: ww8scan.hxx:952
WW8PLCFxDesc * m_pEdn
Definition: ww8scan.hxx:950
static void GetNewNoSprms(WW8PLCFxDesc &rDesc)
Definition: ww8scan.cxx:4894
void GetSprmEnd(short nIdx, WW8PLCFManResult *pRes) const
Definition: ww8scan.cxx:5274
wwSprmParser maSprmParser
Definition: ww8scan.hxx:938
WW8PLCFxDesc * m_pField
Definition: ww8scan.hxx:950
WW8PLCFspecial * m_pTxbx
Definition: ww8scan.hxx:952
WW8_CP Where() const
Definition: ww8scan.cxx:5151
WW8PLCFxDesc * m_pChp
Definition: ww8scan.hxx:950
void GetSprmStart(short nIdx, WW8PLCFManResult *pRes) const
Definition: ww8scan.cxx:5240
WW8PLCFxDesc * m_pFactoidBkm
Definition: ww8scan.hxx:951
WW8PLCFxDesc * m_pPcd
Definition: ww8scan.hxx:950
WW8PLCFxDesc m_aD[MAN_PLCF_COUNT]
Definition: ww8scan.hxx:949
WW8PLCFxDesc * m_pBkm
Definition: ww8scan.hxx:950
void AdjustEnds(WW8PLCFxDesc &rDesc)
Definition: ww8scan.cxx:4803
bool GetDoingDrawTextBox() const
Definition: ww8scan.hxx:1018
WW8PLCFMan(const WW8ScannerBase *pBase, ManTypes nType, tools::Long nStartCp, bool bDoingDrawTextBox=false)
Definition: ww8scan.cxx:4926
WW8PLCFxDesc * m_pAtnBkm
Definition: ww8scan.hxx:951
SprmResult HasCharSprm(sal_uInt16 nId) const
Definition: ww8scan.cxx:5607
WW8PLCFxDesc * m_pAnd
Definition: ww8scan.hxx:951
WW8_CP m_nLineEnd
Definition: ww8scan.hxx:941
WW8PLCFx_Cp_FKP * GetChpPLCF() const
Definition: ww8scan.hxx:1000
WW8PLCFspecial * m_pMagicTables
Definition: ww8scan.hxx:952
void advance()
Definition: ww8scan.cxx:5526
WW8PLCFxDesc * m_pSep
Definition: ww8scan.hxx:950
WW8PLCFx_FLD * GetField() const
Definition: ww8scan.cxx:5597
sal_uInt16 m_nPLCF
Definition: ww8scan.hxx:942
WW8PLCFspecial * m_pSubdocs
Definition: ww8scan.hxx:952
void GetNewSprms(WW8PLCFxDesc &rDesc)
Definition: ww8scan.cxx:4884
WW8PLCFxDesc * m_pPcdA
Definition: ww8scan.hxx:951
void AdvSprm(short nIdx, bool bStart)
Definition: ww8scan.cxx:5356
WW8PLCFxDesc * m_pFootnote
Definition: ww8scan.hxx:950
void GetNoSprmStart(short nIdx, WW8PLCFManResult *pRes) const
Definition: ww8scan.cxx:5289
WW8PLCFspecial * m_pTxbxBkd
Definition: ww8scan.hxx:952
WW8PLCF_HdFt(SvStream *pSt, WW8Fib const &rFib, WW8Dop const &rDop)
Definition: ww8scan.cxx:7513
WW8PLCF m_aPLCF
Definition: ww8scan.hxx:1863
void GetTextPosExact(short nIdx, WW8_CP &rStart, WW8_CP &rLen)
Definition: ww8scan.cxx:7574
void UpdateIndex(sal_uInt8 grpfIhdt)
Definition: ww8scan.cxx:7594
short m_nIdxOffset
Definition: ww8scan.hxx:1864
bool GetTextPos(sal_uInt8 grpfIhdt, sal_uInt8 nWhich, WW8_CP &rStart, WW8_CP &rLen)
Definition: ww8scan.cxx:7535
WW8PLCF(SvStream &rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct, WW8_CP nStartPos=-1)
Definition: ww8scan.cxx:2264
std::unique_ptr< WW8_CP[]> m_pPLCF_PosArray
Definition: ww8scan.hxx:297
WW8_CP Where() const
Definition: ww8scan.cxx:2518
void advance()
Definition: ww8scan.hxx:330
void ReadPLCF(SvStream &rSt, WW8_FC nFilePos, sal_uInt32 nPLCF)
Definition: ww8scan.cxx:2307
void GeneratePLCF(SvStream &rSt, sal_Int32 nPN, sal_Int32 ncpN)
Definition: ww8scan.cxx:2385
sal_Int32 m_nIMax
Definition: ww8scan.hxx:299
void MakeFailedPLCF()
Definition: ww8scan.cxx:2348
int m_nStru
Definition: ww8scan.hxx:301
bool Get(WW8_CP &rStart, WW8_CP &rEnd, void *&rpValue) const
Definition: ww8scan.cxx:2505
void SetIdx(sal_Int32 nI)
Definition: ww8scan.hxx:325
void TruncToSortedRange()
Definition: ww8scan.cxx:2380
sal_Int32 m_nIdx
Definition: ww8scan.hxx:300
bool SeekPos(WW8_CP nPos)
Definition: ww8scan.cxx:2469
sal_uInt8 * m_pPLCF_Contents
Definition: ww8scan.hxx:298
tools::Long m_nIdx
Definition: ww8scan.hxx:364
void SetIdx(tools::Long nI)
Definition: ww8scan.hxx:372
bool SeekPos(tools::Long nPos)
Definition: ww8scan.cxx:2567
tools::Long GetIMax() const
Definition: ww8scan.hxx:373
void advance()
Definition: ww8scan.hxx:377
WW8PLCFpcd_Iter(const WW8PLCFpcd_Iter &)=delete
sal_Int32 Where() const
Definition: ww8scan.cxx:2613
WW8PLCFpcd & m_rPLCF
Definition: ww8scan.hxx:363
bool Get(WW8_CP &rStart, WW8_CP &rEnd, void *&rpValue) const
Definition: ww8scan.cxx:2600
tools::Long GetIdx() const
Definition: ww8scan.hxx:371
std::unique_ptr< WW8_CP[]> m_pPLCF_PosArray
Definition: ww8scan.hxx:344
sal_Int32 m_nIMax
Definition: ww8scan.hxx:346
sal_uInt8 * m_pPLCF_Contents
Definition: ww8scan.hxx:345
sal_uInt32 m_nStru
Definition: ww8scan.hxx:347
void TruncToSortedRange()
Definition: ww8scan.cxx:2375
WW8PLCFpcd(const WW8PLCFpcd &)=delete
among others for fields, that is, the same number of attr as positions, if Ctor-Param bNoEnd = false
Definition: ww8scan.hxx:221
bool Get(WW8_CP &rStart, void *&rpValue) const
Definition: ww8scan.cxx:2244
sal_uInt8 * m_pPLCF_Contents
pointer to content-array-part of Pos-array
Definition: ww8scan.hxx:224
bool GetData(tools::Long nIdx, WW8_CP &rPos, void *&rpValue) const
Definition: ww8scan.cxx:2249
std::unique_ptr< sal_Int32[]> m_pPLCF_PosArray
pointer to Pos-array and to the whole structure
Definition: ww8scan.hxx:223
bool SeekPosExact(tools::Long nPos)
Definition: ww8scan.cxx:2213
bool SeekPos(tools::Long nPos)
Definition: ww8scan.cxx:2178
WW8PLCFspecial(const WW8PLCFspecial &)=delete
tools::Long m_nIdx
marker where we currently are
Definition: ww8scan.hxx:226
void advance()
Definition: ww8scan.hxx:254
void SetIdx(tools::Long nI)
Definition: ww8scan.hxx:236
tools::Long m_nIMax
number of elements
Definition: ww8scan.hxx:225
tools::Long GetIdx() const
Definition: ww8scan.hxx:235
sal_uInt32 m_nStru
Definition: ww8scan.hxx:227
Handles the import of PlcfAtnBkf and PlcfAtnBkl: start / end position of annotation marks.
Definition: ww8scan.hxx:790
virtual void SetIdx2(sal_uInt32 nIdx) override
Definition: ww8scan.cxx:4584
bool getIsEnd() const
Definition: ww8scan.cxx:4666
std::unique_ptr< WW8PLCFspecial > m_pBook[2]
Start and end positions.
Definition: ww8scan.hxx:793
WW8PLCFx_AtnBook(const WW8PLCFx_AtnBook &)=delete
virtual WW8_CP Where() override
Definition: ww8scan.cxx:4605
sal_Int32 m_nIMax
Number of annotation marks.
Definition: ww8scan.hxx:795
virtual sal_uInt32 GetIdx2() const override
Definition: ww8scan.cxx:4576
virtual ~WW8PLCFx_AtnBook() override
Definition: ww8scan.cxx:4561
virtual sal_uInt32 GetIdx() const override
Definition: ww8scan.cxx:4565
virtual void advance() override
Definition: ww8scan.cxx:4626
virtual bool SeekPos(WW8_CP nCpPos) override
Definition: ww8scan.cxx:4593
tools::Long getHandle() const
Handle is the unique ID of an annotation mark.
Definition: ww8scan.cxx:4650
virtual void SetIdx(sal_uInt32 nI) override
Definition: ww8scan.cxx:4570
virtual tools::Long GetNoSprms(WW8_CP &rStart, WW8_CP &rEnd, sal_Int32 &rLen) override
Definition: ww8scan.cxx:4610
Iterator for Booknotes.
Definition: ww8scan.hxx:751
void MapName(OUString &rName)
Definition: ww8scan.cxx:4517
tools::Long GetHandle() const
Definition: ww8scan.cxx:4446
std::vector< eBookStatus > m_aStatus
Definition: ww8scan.hxx:755
sal_uInt16 m_nIsEnd
Definition: ww8scan.hxx:757
virtual WW8_CP Where() override
Definition: ww8scan.cxx:4352
void SetStatus(sal_uInt16 nIndex, eBookStatus eStat)
Definition: ww8scan.cxx:4430
virtual void advance() override
Definition: ww8scan.cxx:4386
virtual void SetIdx(sal_uInt32 nI) override
Definition: ww8scan.cxx:4320
std::vector< OUString > m_aBookNames
Definition: ww8scan.hxx:754
eBookStatus GetStatus() const
Definition: ww8scan.cxx:4438
OUString GetUniqueBookmarkName(const OUString &rSuggestedName)
Definition: ww8scan.cxx:4496
WW8PLCFx_Book(const WW8PLCFx_Book &)=delete
virtual sal_uInt32 GetIdx() const override
Definition: ww8scan.cxx:4315
virtual tools::Long GetNoSprms(WW8_CP &rStart, WW8_CP &rEnd, sal_Int32 &rLen) override
Definition: ww8scan.cxx:4357
tools::Long GetIMax() const
Definition: ww8scan.hxx:766
OUString GetBookmark(tools::Long nStart, tools::Long nEnd, sal_uInt16 &nIndex)
Definition: ww8scan.cxx:4462
virtual bool SeekPos(WW8_CP nCpPos) override
Definition: ww8scan.cxx:4340
sal_Int32 m_nBookmarkId
Definition: ww8scan.hxx:758
tools::Long GetLen() const
Definition: ww8scan.cxx:4410
tools::Long m_nIMax
Definition: ww8scan.hxx:756
virtual void SetIdx2(sal_uInt32 nIdx) override
Definition: ww8scan.cxx:4331
const OUString * GetName() const
Definition: ww8scan.cxx:4534
virtual ~WW8PLCFx_Book() override
Definition: ww8scan.cxx:4311
virtual sal_uInt32 GetIdx2() const override
Definition: ww8scan.cxx:4326
std::unique_ptr< WW8PLCFspecial > m_pBook[2]
Definition: ww8scan.hxx:753
iterator for Piece Table Exceptions of Fkps works on CPs (high-level)
Definition: ww8scan.hxx:634
std::unique_ptr< WW8PLCFx_PCD > m_pPcd
Definition: ww8scan.hxx:637
WW8PLCFpcd_Iter * m_pPieceIter
Definition: ww8scan.hxx:638
WW8PLCFx_Cp_FKP(const WW8PLCFx_Cp_FKP &)=delete
virtual WW8_CP Where() override
Definition: ww8scan.cxx:3405
virtual void Restore(const WW8PLCFxSave1 &rSave) override
Definition: ww8scan.cxx:5655
WW8_CP m_nAttrStart
Definition: ww8scan.hxx:639
virtual sal_uInt32 GetIdx2() const override
Definition: ww8scan.cxx:5633
virtual void advance() override
Definition: ww8scan.cxx:3688
void ResetAttrStartEnd()
Definition: ww8scan.cxx:3379
virtual void Save(WW8PLCFxSave1 &rSave) const override
Definition: ww8scan.cxx:5644
const WW8ScannerBase & m_rSBase
Definition: ww8scan.hxx:636
virtual bool SeekPos(WW8_CP nCpPos) override
Definition: ww8scan.cxx:3391
WW8_CP m_nAttrEnd
Definition: ww8scan.hxx:639
virtual ~WW8PLCFx_Cp_FKP() override
Definition: ww8scan.cxx:3375
virtual void GetSprms(WW8PLCFxDesc *p) override
Definition: ww8scan.cxx:3413
sal_uInt32 GetPCDIdx() const
Definition: ww8scan.cxx:3386
virtual void SetIdx2(sal_uInt32 nIdx) override
Definition: ww8scan.cxx:5638
Iterator for fields.
Definition: ww8scan.hxx:726
virtual void GetSprms(WW8PLCFxDesc *p) override
Definition: ww8scan.cxx:4089
bool GetPara(tools::Long nIdx, WW8FieldDesc &rF)
Definition: ww8scan.cxx:4136
virtual WW8_CP Where() override
Definition: ww8scan.cxx:4053
virtual ~WW8PLCFx_FLD() override
Definition: ww8scan.cxx:4033
bool StartPosIsFieldStart()
Definition: ww8scan.cxx:4058
virtual void advance() override
Definition: ww8scan.cxx:4128
virtual bool SeekPos(WW8_CP nCpPos) override
Definition: ww8scan.cxx:4048
bool EndPosIsFieldEnd(WW8_CP &)
Definition: ww8scan.cxx:4065
virtual sal_uInt32 GetIdx() const override
Definition: ww8scan.cxx:4037
WW8PLCFx_FLD(const WW8PLCFx_FLD &)=delete
virtual void SetIdx(sal_uInt32 nIdx) override
Definition: ww8scan.cxx:4042
const WW8Fib & m_rFib
Definition: ww8scan.hxx:729
std::unique_ptr< WW8PLCFspecial > m_pPLCF
Definition: ww8scan.hxx:728
Handles the import of PlcfBkfFactoid and PlcfBklFactoid: start / end position of factoids.
Definition: ww8scan.hxx:820
virtual ~WW8PLCFx_FactoidBook() override
Definition: ww8scan.cxx:4690
bool getIsEnd() const
Definition: ww8scan.cxx:4795
virtual void SetIdx2(sal_uInt32 nIdx) override
Definition: ww8scan.cxx:4713
virtual sal_uInt32 GetIdx() const override
Definition: ww8scan.cxx:4694
virtual void SetIdx(sal_uInt32 nI) override
Definition: ww8scan.cxx:4699
virtual bool SeekPos(WW8_CP nCpPos) override
Definition: ww8scan.cxx:4722
tools::Long getHandle() const
Handle is the unique ID of a factoid mark.
Definition: ww8scan.cxx:4779
sal_Int32 m_nIMax
Number of factoid marks.
Definition: ww8scan.hxx:825
virtual sal_uInt32 GetIdx2() const override
Definition: ww8scan.cxx:4705
virtual WW8_CP Where() override
Definition: ww8scan.cxx:4734
WW8PLCFx_FactoidBook(const WW8PLCFx_FactoidBook &)=delete
std::unique_ptr< WW8PLCFspecial > m_pBook[2]
Start and end positions.
Definition: ww8scan.hxx:823
virtual void advance() override
Definition: ww8scan.cxx:4755
virtual tools::Long GetNoSprms(WW8_CP &rStart, WW8_CP &rEnd, sal_Int32 &rLen) override
Definition: ww8scan.cxx:4739
Entry & operator=(const Entry &rEntry)
Definition: ww8scan.cxx:2879
sal_uInt16 GetIstd() const
Definition: ww8scan.hxx:559
WW8Fkp(const WW8Fib &rFib, SvStream *pFKPStrm, SvStream *pDataStrm, tools::Long _nFilePos, tools::Long nItemSiz, ePLCFT ePl, WW8_FC nStartFc)
Definition: ww8scan.cxx:2656
bool IsMustRemainCache() const
Definition: ww8scan.hxx:579
WW8_FC Where() const
Definition: ww8scan.hxx:549
sal_uInt8 GetIdx() const
Definition: ww8scan.hxx:546
sal_uInt8 * Get(WW8_FC &rStart, WW8_FC &rEnd, sal_Int32 &rLen) const
Definition: ww8scan.cxx:2948
void FillEntry(Entry &rEntry, std::size_t nDataOffset, sal_uInt16 nLen)
Definition: ww8scan.cxx:2637
void SetIdx(sal_uInt8 nI)
Definition: ww8scan.cxx:2966
const wwSprmParser & GetSprmParser() const
Definition: ww8scan.hxx:576
tools::Long m_nItemSize
Definition: ww8scan.hxx:526
tools::Long GetFilePos() const
Definition: ww8scan.hxx:545
tools::Long m_nFilePos
Definition: ww8scan.hxx:529
sal_uInt8 * GetLenAndIStdAndSprms(sal_Int32 &rLen) const
Definition: ww8scan.cxx:2974
bool SeekPos(WW8_FC nFc)
Definition: ww8scan.cxx:2916
void Reset(WW8_FC nPos)
Definition: ww8scan.cxx:2909
std::vector< Entry > maEntries
Definition: ww8scan.hxx:524
sal_uInt8 maRawData[512]
Definition: ww8scan.hxx:523
SprmResult HasSprm(sal_uInt16 nId, bool bFindFirst=true)
Definition: ww8scan.cxx:2980
wwSprmParser maSprmParser
Definition: ww8scan.hxx:535
Iterator for Piece Table Exceptions of Fkps works only with FCs, not with CPs ! ( Low-Level )
Definition: ww8scan.hxx:500
virtual sal_uInt16 GetIstd() const override
Definition: ww8scan.cxx:3259
virtual WW8_FC Where() override
Definition: ww8scan.cxx:3217
WW8PLCFx_Fc_FKP(const WW8PLCFx_Fc_FKP &)=delete
virtual bool SeekPos(WW8_FC nFcPos) override
Definition: ww8scan.cxx:3194
virtual ~WW8PLCFx_Fc_FKP() override
Definition: ww8scan.cxx:3160
SvStream * m_pFKPStrm
Definition: ww8scan.hxx:584
sal_uInt8 * GetSprmsAndPos(WW8_FC &rStart, WW8_FC &rEnd, sal_Int32 &rLen)
Definition: ww8scan.cxx:3229
WW8Fkp * m_pFkp
Definition: ww8scan.hxx:588
SprmResult HasSprm(sal_uInt16 nId, bool bFindFirst=true)
Definition: ww8scan.cxx:3280
SvStream * m_pDataStrm
Definition: ww8scan.hxx:585
std::deque< std::unique_ptr< WW8Fkp > > maFkpCache
Definition: ww8scan.hxx:603
virtual void advance() override
Definition: ww8scan.cxx:3246
std::unique_ptr< WW8PLCF > m_pPLCF
Definition: ww8scan.hxx:586
std::unique_ptr< WW8PLCFx_PCDAttrs > m_pPCDAttrs
Definition: ww8scan.hxx:613
virtual sal_uInt32 GetIdx() const override
Definition: ww8scan.cxx:3167
virtual void SetIdx(sal_uInt32 nIdx) override
Definition: ww8scan.cxx:3175
ePLCFT m_ePLCF
Definition: ww8scan.hxx:612
void GetPCDSprms(WW8PLCFxDesc &rDesc)
Definition: ww8scan.cxx:3264
WW8PLCFx_PCDAttrs(const WW8PLCFx_PCDAttrs &)=delete
virtual bool SeekPos(WW8_CP nCpPos) override
Definition: ww8scan.cxx:969
virtual WW8_CP Where() override
Definition: ww8scan.cxx:978
WW8PLCFx_PCD * m_pPcd
Definition: ww8scan.hxx:438
virtual sal_uInt32 GetIdx() const override
Definition: ww8scan.cxx:960
virtual void advance() override
Definition: ww8scan.cxx:974
SVBT32 m_aShortSprm
Definition: ww8scan.hxx:440
std::vector< std::unique_ptr< sal_uInt8[]> > const & mrGrpprls
Definition: ww8scan.hxx:439
virtual void SetIdx(sal_uInt32 nI) override
Definition: ww8scan.cxx:965
virtual void GetSprms(WW8PLCFxDesc *p) override
Definition: ww8scan.cxx:983
WW8PLCFpcd_Iter * m_pPcdI
Definition: ww8scan.hxx:437
WW8_CP GetClipStart() const
Definition: ww8scan.hxx:486
static sal_Int32 TransformPieceAddress(tools::Long nfc, bool &bIsUnicodeAddress)
Definition: ww8scan.hxx:488
virtual void SetIdx(sal_uInt32 nI) override
Definition: ww8scan.cxx:1161
virtual WW8_CP Where() override
Definition: ww8scan.cxx:1172
virtual void advance() override
Definition: ww8scan.cxx:1190
virtual sal_uInt32 GetIdx() const override
Definition: ww8scan.cxx:1156
virtual ~WW8PLCFx_PCD() override
Definition: ww8scan.cxx:1147
std::unique_ptr< WW8PLCFpcd_Iter > m_pPcdI
Definition: ww8scan.hxx:462
static void CurrentPieceFc2Cp(WW8_CP &rStartPos, WW8_CP &rEndPos, const WW8ScannerBase *pSBase)
Definition: ww8scan.cxx:1250
bool m_bVer67
Definition: ww8scan.hxx:463
sal_uInt32 GetIMax() const
Definition: ww8scan.cxx:1151
virtual bool SeekPos(WW8_CP nCpPos) override
Definition: ww8scan.cxx:1167
virtual tools::Long GetNoSprms(WW8_CP &rStart, WW8_CP &, sal_Int32 &rLen) override
Definition: ww8scan.cxx:1177
void SetClipStart(WW8_CP nIn)
Definition: ww8scan.hxx:485
WW8_CP CurrentPieceStartFc2Cp(WW8_FC nStartPos)
Definition: ww8scan.cxx:1261
WW8PLCFx_PCD(const WW8PLCFx_PCD &)=delete
WW8_FC CurrentPieceStartCp2Fc(WW8_CP nCp)
Definition: ww8scan.cxx:1197
Iterator for Piece Table Exceptions of Sepx.
Definition: ww8scan.hxx:664
bool Find4Sprms(sal_uInt16 nId1, sal_uInt16 nId2, sal_uInt16 nId3, sal_uInt16 nId4, SprmResult &r1, SprmResult &r2, SprmResult &r3, SprmResult &r4) const
Definition: ww8scan.cxx:3821
SprmResult HasSprm(sal_uInt16 nId) const
Definition: ww8scan.cxx:3804
virtual void GetSprms(WW8PLCFxDesc *p) override
Definition: ww8scan.cxx:3745
virtual WW8_CP Where() override
Definition: ww8scan.cxx:3740
std::unique_ptr< WW8PLCF > m_pPLCF
Definition: ww8scan.hxx:668
wwSprmParser maSprmParser
Definition: ww8scan.hxx:666
virtual void SetIdx(sal_uInt32 nIdx) override
Definition: ww8scan.cxx:3730
std::unique_ptr< sal_uInt8[]> m_pSprms
Definition: ww8scan.hxx:669
WW8PLCFx_SEPX(const WW8PLCFx_SEPX &)=delete
sal_uInt16 m_nArrMax
Definition: ww8scan.hxx:670
virtual ~WW8PLCFx_SEPX() override
Definition: ww8scan.cxx:3721
sal_uInt16 m_nSprmSiz
Definition: ww8scan.hxx:671
SvStream * m_pStrm
Definition: ww8scan.hxx:667
virtual bool SeekPos(WW8_CP nCpPos) override
Definition: ww8scan.cxx:3735
virtual sal_uInt32 GetIdx() const override
Definition: ww8scan.cxx:3725
virtual void advance() override
Definition: ww8scan.cxx:3798
iterator for footnotes/endnotes and comments
Definition: ww8scan.hxx:696
virtual WW8_CP Where() override
Definition: ww8scan.cxx:3926
std::unique_ptr< WW8PLCF > m_pRef
Definition: ww8scan.hxx:698
virtual bool SeekPos(WW8_CP nCpPos) override
Definition: ww8scan.cxx:3921
std::unique_ptr< WW8PLCF > m_pText
Definition: ww8scan.hxx:699
virtual void advance() override
Definition: ww8scan.cxx:3981
virtual ~WW8PLCFx_SubDoc() override
Definition: ww8scan.cxx:3897
virtual sal_uInt32 GetIdx() const override
Definition: ww8scan.cxx:3903
virtual void SetIdx(sal_uInt32 nIdx) override
Definition: ww8scan.cxx:3911
virtual void GetSprms(WW8PLCFxDesc *p) override
Definition: ww8scan.cxx:3931
WW8PLCFx_SubDoc(const WW8PLCFx_SubDoc &)=delete
virtual void SetIdx2(sal_uInt32 nIdx)
Definition: ww8scan.cxx:3043
virtual sal_uInt32 GetIdx() const =0
void SetStartFc(WW8_FC nFc)
Definition: ww8scan.hxx:428
virtual void Restore(const WW8PLCFxSave1 &rSave)
Definition: ww8scan.cxx:5626
WW8_FC GetStartFc() const
Definition: ww8scan.hxx:429
virtual sal_uInt32 GetIdx2() const
Definition: ww8scan.cxx:3038
virtual void SetIdx(sal_uInt32 nIdx)=0
ww::WordVersion GetFIBVersion() const
Definition: ww8scan.cxx:3015
virtual void Save(WW8PLCFxSave1 &rSave) const
Definition: ww8scan.cxx:5618
virtual void GetSprms(WW8PLCFxDesc *p)
Definition: ww8scan.cxx:3020
void SetDirty(bool bIn)
Definition: ww8scan.hxx:430
bool IsSprm() const
Definition: ww8scan.hxx:413
bool GetDirty() const
Definition: ww8scan.hxx:431
const WW8Fib & GetFIB() const
Definition: ww8scan.hxx:427
const WW8Fib & mrFib
Definition: ww8scan.hxx:396
virtual tools::Long GetNoSprms(WW8_CP &rStart, WW8_CP &, sal_Int32 &rLen)
Definition: ww8scan.cxx:3029
virtual bool SeekPos(WW8_CP nCpPos)=0
virtual sal_uInt16 GetIstd() const
Definition: ww8scan.hxx:423
std::unique_ptr< WW8PLCFx_PCD > m_pPLCFx_PCD
Definition: ww8scan.hxx:1069
std::unique_ptr< WW8PLCFx_SubDoc > m_pFootnotePLCF
Definition: ww8scan.hxx:1042
std::unique_ptr< WW8PLCFx_Book > m_pBook
Definition: ww8scan.hxx:1062
WW8Fib * m_pWw8Fib
Definition: ww8scan.hxx:1038
std::unique_ptr< WW8PLCFx_FLD > m_pFieldEdnPLCF
Definition: ww8scan.hxx:1050
std::unique_ptr< WW8PLCFspecial > m_pHdFtFdoa
Definition: ww8scan.hxx:1053
std::unique_ptr< WW8PLCFx_SEPX > m_pSepPLCF
Definition: ww8scan.hxx:1041
std::unique_ptr< WW8PLCFspecial > m_pSubdocs
Definition: ww8scan.hxx:1059
std::unique_ptr< WW8PLCFx_FLD > m_pFieldAndPLCF
Definition: ww8scan.hxx:1051
std::unique_ptr< WW8PLCFx_FLD > m_pFieldFootnotePLCF
Definition: ww8scan.hxx:1049
std::unique_ptr< WW8PLCFx_SubDoc > m_pEdnPLCF
Definition: ww8scan.hxx:1043
std::vector< std::unique_ptr< sal_uInt8[]> > m_aPieceGrpprls
Definition: ww8scan.hxx:1071
std::unique_ptr< WW8PLCFx_FLD > m_pFieldTxbxPLCF
Definition: ww8scan.hxx:1047
WW8ScannerBase(const WW8ScannerBase &)=delete
std::unique_ptr< WW8PLCFx_FactoidBook > m_pFactoidBook
Smart tag bookmarks.
Definition: ww8scan.hxx:1065
std::unique_ptr< WW8PLCFpcd > OpenPieceTable(SvStream *pStr, const WW8Fib *pWwF)
Definition: ww8scan.cxx:1678
std::unique_ptr< WW8PLCFx_FLD > m_pFieldPLCF
Definition: ww8scan.hxx:1045
std::unique_ptr< sal_uInt8[]> m_pExtendedAtrds
Definition: ww8scan.hxx:1061
std::unique_ptr< WW8PLCFx_PCDAttrs > m_pPLCFx_PCDAttrs
Definition: ww8scan.hxx:1070
std::unique_ptr< WW8PLCFx_Cp_FKP > m_pPapPLCF
Definition: ww8scan.hxx:1040
std::unique_ptr< WW8PLCFx_SubDoc > m_pAndPLCF
Definition: ww8scan.hxx:1044
std::unique_ptr< WW8PLCFspecial > m_pMagicTables
Definition: ww8scan.hxx:1058
std::unique_ptr< WW8PLCFspecial > m_pMainTxbxBkd
Definition: ww8scan.hxx:1055
std::unique_ptr< WW8PLCFx_FLD > m_pFieldHdFtPLCF
Definition: ww8scan.hxx:1046
std::unique_ptr< WW8PLCFspecial > m_pMainFdoa
Definition: ww8scan.hxx:1052
std::unique_ptr< WW8PLCFspecial > m_pMainTxbx
Definition: ww8scan.hxx:1054
std::unique_ptr< WW8PLCFspecial > m_pHdFtTxbx
Definition: ww8scan.hxx:1056
std::unique_ptr< WW8PLCFspecial > m_pHdFtTxbxBkd
Definition: ww8scan.hxx:1057
std::unique_ptr< WW8PLCFpcd_Iter > m_pPieceIter
Definition: ww8scan.hxx:1068
WW8_CP WW8Fc2Cp(WW8_FC nFcPos) const
Definition: ww8scan.cxx:1444
std::unique_ptr< WW8PLCFx_Cp_FKP > m_pChpPLCF
Definition: ww8scan.hxx:1039
std::unique_ptr< WW8PLCFpcd > m_pPiecePLCF
Definition: ww8scan.hxx:1067
std::unique_ptr< WW8PLCFx_AtnBook > m_pAtnBook
Definition: ww8scan.hxx:1063
std::unique_ptr< WW8PLCFx_FLD > m_pFieldTxbxHdFtPLCF
Definition: ww8scan.hxx:1048
WW8_FC WW8Cp2Fc(WW8_CP nCpPos, bool *pIsUnicode=nullptr, WW8_CP *pNextPieceCp=nullptr, bool *pTestFlag=nullptr) const
Definition: ww8scan.cxx:1566
sal_Int32 WW8ReadString(SvStream &rStrm, OUString &rStr, WW8_CP nCurrentStartCp, tools::Long nTotalLen, rtl_TextEncoding eEnc) const
Definition: ww8scan.cxx:2089
void Read(SvStream &rStream, WW8_FC fcFactoidData, sal_uInt32 lcbFactoidData)
Definition: ww8scan.cxx:6853
std::vector< MSOPropertyBag > m_aPropBags
Definition: ww8struc.hxx:1153
void Write(WW8Export &rExport)
Definition: ww8scan.cxx:6871
MSOPropertyBagStore m_aPropBagStore
Definition: ww8struc.hxx:1152
simple Iterator for SPRMs
Definition: ww8scan.hxx:263
void UpdateMyMembers()
Definition: ww8scan.cxx:902
const sal_uInt8 * m_pCurrentParams
Definition: ww8scan.hxx:268
const sal_uInt8 * GetSprms() const
Definition: ww8scan.hxx:282
const wwSprmParser & mrSprmParser
Definition: ww8scan.hxx:265
sal_Int32 GetRemLen() const
Definition: ww8scan.hxx:286
const sal_uInt8 * GetCurrentParams() const
Definition: ww8scan.hxx:284
sal_uInt16 m_nCurrentId
Definition: ww8scan.hxx:269
sal_Int32 m_nCurrentSize
Definition: ww8scan.hxx:270
void SetSprms(const sal_uInt8 *pSprms_, sal_Int32 nLen_)
Definition: ww8scan.cxx:882
SprmResult FindSprm(sal_uInt16 nId, bool bFindFirst, const sal_uInt8 *pNextByteMatch=nullptr)
Definition: ww8scan.cxx:924
const sal_uInt8 * m_pSprms
Definition: ww8scan.hxx:267
sal_uInt16 GetCurrentId() const
Definition: ww8scan.hxx:285
sal_Int32 m_nRemLen
Definition: ww8scan.hxx:272
void advance()
Definition: ww8scan.cxx:889
WW8SprmIter(const sal_uInt8 *pSprms_, sal_Int32 nLen_, const wwSprmParser &rSprmParser)
Definition: ww8scan.cxx:875
sal_uInt16 m_nVerBuiltInNamesWhenSaved
Definition: ww8scan.hxx:1559
std::unique_ptr< WW8_STD > Read1STDFixed(sal_uInt16 &rSkip)
Definition: ww8scan.cxx:6972
std::unique_ptr< WW8_STD > Read1Style(sal_uInt16 &rSkip, OUString *pString)
Definition: ww8scan.cxx:7053
sal_uInt16 m_ftcFE
Definition: ww8scan.hxx:1563
sal_uInt16 m_istdMaxFixedWhenSaved
Definition: ww8scan.hxx:1558
sal_uInt16 m_ftcBi
Definition: ww8scan.hxx:1567
sal_uInt16 m_ftcAsci
Definition: ww8scan.hxx:1561
sal_uInt16 m_cstd
Definition: ww8scan.hxx:1553
sal_uInt16 m_ftcOther
Definition: ww8scan.hxx:1565
WW8Fib & m_rFib
Definition: ww8scan.hxx:1550
WW8Style(const WW8Style &)
sal_uInt16 m_fStdStylenamesWritten
Definition: ww8scan.hxx:1555
SvStream & m_rStream
Definition: ww8scan.hxx:1551
sal_uInt16 m_cbSTDBaseInFile
Definition: ww8scan.hxx:1554
sal_uInt16 m_stiMaxWhenSaved
Definition: ww8scan.hxx:1557
wwSprmParser knows how to take a sequence of bytes and split it up into sprms and their arguments
Definition: ww8scan.hxx:114
sal_uInt16 GetSprmId(const sal_uInt8 *pSp) const
Return the SPRM id at the beginning of this byte sequence.
Definition: ww8scan.cxx:8459
static const wwSprmSearcher * GetWW8SprmSearcher()
Definition: ww8scan.cxx:442
sal_uInt8 mnDelta
Definition: ww8scan.hxx:117
wwSprmParser(const WW8Fib &rFib)
Definition: ww8scan.cxx:782
static const wwSprmSearcher * GetWW2SprmSearcher()
Definition: ww8scan.cxx:86
ww::WordVersion meVersion
Definition: ww8scan.hxx:116
const wwSprmSearcher * mpKnownSprms
Definition: ww8scan.hxx:118
ww::WordVersion GetFIBVersion() const
Definition: ww8scan.hxx:152
sal_Int32 DistanceToData(sal_uInt16 nId) const
Get known len of a sprms head, the bytes of the sprm id + any bytes reserved to hold a variable lengt...
Definition: ww8scan.cxx:8492
int MinSprmLen() const
The minimum acceptable sprm len possible for this type of parser.
Definition: ww8scan.hxx:146
static const wwSprmSearcher * GetWW6SprmSearcher(const WW8Fib &rFib)
Definition: ww8scan.cxx:237
sal_uInt16 GetSprmTailLen(sal_uInt16 nId, const sal_uInt8 *pSprm, sal_Int32 nRemLen) const
Get len of a sprms data area, ignoring the bytes of the sprm id and ignoring any len bytes.
Definition: ww8scan.cxx:8392
SprmInfo GetSprmInfo(sal_uInt16 nId) const
Definition: ww8scan.cxx:797
SprmResult findSprmData(sal_uInt16 nId, sal_uInt8 *pSprms, sal_Int32 nLen) const
Returns the offset to data of the first sprm of id nId, 0.
Definition: ww8scan.cxx:8497
sal_Int32 GetSprmSize(sal_uInt16 nId, const sal_uInt8 *pSprm, sal_Int32 nRemLen) const
Definition: ww8scan.cxx:8482
sal_uInt8 SprmDataOfs(sal_uInt16 nId) const
Definition: ww8scan.cxx:8487
SprmInfo const * search(sal_uInt16 id) const
Definition: ww8scan.hxx:78
void patchCJKVariant()
Definition: ww8scan.cxx:427
Any value
int nCount
float u
float x
#define ERRCODE_NONE
void const * base
sal_Int32 nIndex
void * p
sal_Int64 n
#define LANGUAGE_CHINESE_TRADITIONAL
#define LANGUAGE_CHINESE_SIMPLIFIED
#define LANGUAGE_JAPANESE
#define LANGUAGE_KOREAN
#define LANGUAGE_CHINESE_SIMPLIFIED_LEGACY
sal_uInt16 nPos
const long LONG_MAX
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
#define SAL_N_ELEMENTS(arr)
aBuf
std::unique_ptr< sal_Int32[]> pData
SVXCORE_DLLPUBLIC MSO_SPT Get(const OUString &)
static void Write(std::u16string_view aString, SvStream &rStream)
Definition: ww8scan.cxx:6713
static OUString Read(SvStream &rStream)
Definition: ww8scan.cxx:6697
const sal_uInt16 sprmPFWidowControl
Definition: sprmids.hxx:130
const sal_uInt16 sprmPDxaFromText
Definition: sprmids.hxx:128
const sal_uInt16 sprmCHpsPosAdj
Definition: sprmids.hxx:164
const sal_uInt16 sprmCFOutline
Definition: sprmids.hxx:150
const sal_uInt16 sprmCHpsNew50
Definition: sprmids.hxx:167
const sal_uInt16 sprmPDyaLine
Definition: sprmids.hxx:99
const sal_uInt16 sprmPFLocked
Definition: sprmids.hxx:129
const sal_uInt16 sprmTSetBrc10
Definition: sprmids.hxx:237
const sal_uInt16 sprmCFStrike
Definition: sprmids.hxx:149
const sal_uInt16 sprmPBrcLeft10
Definition: sprmids.hxx:110
const sal_uInt16 sprmPChgTabsPapx
Definition: sprmids.hxx:94
const sal_uInt16 sprmPFKeep
Definition: sprmids.hxx:86
const sal_uInt16 sprmPShd
Definition: sprmids.hxx:126
const sal_uInt16 sprmSDyaHdrBottom
Definition: sprmids.hxx:205
const sal_uInt16 sprmCFSmallCaps
Definition: sprmids.hxx:152
const sal_uInt16 sprmCIss
Definition: sprmids.hxx:166
const sal_uInt16 sprmPBrcTop10
Definition: sprmids.hxx:109
const sal_uInt16 sprmPBrcLeft
Definition: sprmids.hxx:118
const sal_uInt16 sprmPChgTabs
Definition: sprmids.hxx:102
const sal_uInt16 sprmSNLnnMod
Definition: sprmids.hxx:202
const sal_uInt16 sprmTSetBrc
Definition: sprmids.hxx:231
const sal_uInt16 sprmPicBrcBottom
Definition: sprmids.hxx:179
const sal_uInt16 sprmTDxaCol
Definition: sprmids.hxx:234
const sal_uInt16 sprmPDyaBefore
Definition: sprmids.hxx:100
const sal_uInt16 sprmSDmBinOther
Definition: sprmids.hxx:189
const sal_uInt16 sprmTDxaLeft
Definition: sprmids.hxx:221
const sal_uInt16 sprmSYaPage
Definition: sprmids.hxx:213
const sal_uInt16 sprmPFromText10
Definition: sprmids.hxx:115
const sal_uInt16 sprmCSizePos
Definition: sprmids.hxx:157
const sal_uInt16 sprmCHps
Definition: sprmids.hxx:161
const sal_uInt16 sprmCIbstRMark
Definition: sprmids.hxx:136
const sal_uInt16 sprmPWHeightAbs
Definition: sprmids.hxx:124
const sal_uInt16 sprmCHpsKern
Definition: sprmids.hxx:169
const sal_uInt16 sprmSDxaColumns
Definition: sprmids.hxx:193
const sal_uInt16 sprmPFNoLineNumb
Definition: sprmids.hxx:93
const sal_uInt16 sprmSDxaLeft
Definition: sprmids.hxx:214
const sal_uInt16 sprmPPageBreakBefore
Definition: sprmids.hxx:88
const sal_uInt16 sprmPicBrcLeft
Definition: sprmids.hxx:178
const sal_uInt16 sprmSLnnMin
Definition: sprmids.hxx:208
const sal_uInt16 sprmSDxaLnn
Definition: sprmids.hxx:203
const sal_uInt16 sprmPTtp
Definition: sprmids.hxx:104
const sal_uInt16 sprmSFPgnRestart
Definition: sprmids.hxx:198
const sal_uInt16 sprmSDxaColWidth
Definition: sprmids.hxx:184
const sal_uInt16 sprmPBrcRight10
Definition: sprmids.hxx:112
const sal_uInt16 sprmSFTitlePage
Definition: sprmids.hxx:191
const sal_uInt16 sprmCFData
Definition: sprmids.hxx:138
const sal_uInt16 sprmSDxaRight
Definition: sprmids.hxx:215
const sal_uInt16 sprmTSetShd
Definition: sprmids.hxx:238
const sal_uInt16 sprmCFRMark
Definition: sprmids.hxx:133
const sal_uInt16 sprmTDyaRowHeight
Definition: sprmids.hxx:227
const sal_uInt16 sprmPPc
Definition: sprmids.hxx:108
const sal_uInt16 sprmCFBold
Definition: sprmids.hxx:147
const sal_uInt16 sprmTSplit
Definition: sprmids.hxx:236
const sal_uInt16 sprmPBrcl
Definition: sprmids.hxx:89
const sal_uInt16 sprmSDxaPgn
Definition: sprmids.hxx:197
const sal_uInt16 sprmPDyaAfter
Definition: sprmids.hxx:101
const sal_uInt16 sprmCCondHyhen
Definition: sprmids.hxx:172
const sal_uInt16 sprmCPicLocation
Definition: sprmids.hxx:135
const sal_uInt16 sprmCDttmRMark
Definition: sprmids.hxx:137
const sal_uInt16 sprmPIstdPermute
Definition: sprmids.hxx:82
const sal_uInt16 sprmSNfcPgn
Definition: sprmids.hxx:195
const sal_uInt16 sprmPFInTable
Definition: sprmids.hxx:103
const sal_uInt16 sprmPDxaLeft1
Definition: sprmids.hxx:98
const sal_uInt16 sprmCHpsPos
Definition: sprmids.hxx:163
const sal_uInt16 sprmPicBrcTop
Definition: sprmids.hxx:177
const sal_uInt16 sprmSDMPaperReq
Definition: sprmids.hxx:219
const sal_uInt16 sprmPBrcBetween
Definition: sprmids.hxx:121
const sal_uInt16 sprmPIncLv1
Definition: sprmids.hxx:83
const sal_uInt16 sprmSScnsPgn
Definition: sprmids.hxx:181
const sal_uInt16 sprmPDyaAbs
Definition: sprmids.hxx:106
const sal_uInt16 sprmCFCaps
Definition: sprmids.hxx:153
const sal_uInt16 sprmPBrcBottom10
Definition: sprmids.hxx:111
const sal_uInt16 sprmPFSideBySide
Definition: sprmids.hxx:85
const sal_uInt16 sprmPRuler
Definition: sprmids.hxx:131
const sal_uInt16 sprmSDyaHdrTop
Definition: sprmids.hxx:204
const sal_uInt16 sprmSDzaGutter
Definition: sprmids.hxx:218
const sal_uInt16 sprmPicBrcl
Definition: sprmids.hxx:175
const sal_uInt16 sprmPNLvlAnm
Definition: sprmids.hxx:92
const sal_uInt16 sprmSFAutoPgn
Definition: sprmids.hxx:194
const sal_uInt16 sprmCFFldVanish
Definition: sprmids.hxx:134
const sal_uInt16 sprmTTableHeader
Definition: sprmids.hxx:224
const sal_uInt16 sprmSVjc
Definition: sprmids.hxx:207
const sal_uInt16 sprmPBrcTop
Definition: sprmids.hxx:117
const sal_uInt16 sprmPDcs
Definition: sprmids.hxx:125
const sal_uInt16 sprmCFOle2
Definition: sprmids.hxx:142
const sal_uInt16 sprmSFEvenlySpaced
Definition: sprmids.hxx:186
const sal_uInt16 sprmSiHeadingPgn
Definition: sprmids.hxx:182
const sal_uInt16 sprmCIstdPermute
Definition: sprmids.hxx:144
const sal_uInt16 sprmTTableBorders
Definition: sprmids.hxx:225
const sal_uInt16 sprmCLid
Definition: sprmids.hxx:159
const sal_uInt16 sprmSGprfIhdt
Definition: sprmids.hxx:201
const sal_uInt16 sprmSBCustomize
Definition: sprmids.hxx:211
const sal_uInt16 sprmPBrcRight
Definition: sprmids.hxx:120
const sal_uInt16 sprmPBrcp
Definition: sprmids.hxx:90
const sal_uInt16 sprmPDyaFromText
Definition: sprmids.hxx:127
const sal_uInt16 sprmPBrcBar
Definition: sprmids.hxx:122
const sal_uInt16 sprmCIstd
Definition: sprmids.hxx:143
const sal_uInt16 sprmCPlain
Definition: sprmids.hxx:146
const sal_uInt16 sprmTDelete
Definition: sprmids.hxx:233
const sal_uInt16 sprmSOlstAnm
Definition: sprmids.hxx:183
const sal_uInt16 sprmCMajority50
Definition: sprmids.hxx:170
const sal_uInt16 sprmPJc
Definition: sprmids.hxx:84
const sal_uInt16 sprmCHpsInc1
Definition: sprmids.hxx:168
const sal_uInt16 sprmPFNoAutoHyph
Definition: sprmids.hxx:123
const sal_uInt16 sprmPDxaAbs
Definition: sprmids.hxx:105
const sal_uInt16 sprmPDxaWidth
Definition: sprmids.hxx:107
const sal_uInt16 sprmTFCantSplit
Definition: sprmids.hxx:223
const sal_uInt16 sprmCFSpec
Definition: sprmids.hxx:173
const sal_uInt16 sprmPBrcBetween10
Definition: sprmids.hxx:113
const sal_uInt16 sprmCHpsInc
Definition: sprmids.hxx:162
const sal_uInt16 sprmPIstd
Definition: sprmids.hxx:81
const sal_uInt16 sprmSBkc
Definition: sprmids.hxx:190
const sal_uInt16 sprmTJc
Definition: sprmids.hxx:220
const sal_uInt16 sprmTDxaGapHalf
Definition: sprmids.hxx:222
const sal_uInt16 sprmCChse
Definition: sprmids.hxx:140
const sal_uInt16 sprmPBrcBottom
Definition: sprmids.hxx:119
const sal_uInt16 sprmCMajority
Definition: sprmids.hxx:165
const sal_uInt16 sprmSPgnStart
Definition: sprmids.hxx:209
const sal_uInt16 sprmPAnld
Definition: sprmids.hxx:91
const sal_uInt16 sprmCRMReason
Definition: sprmids.hxx:139
const sal_uInt16 sprmCDxaSpace
Definition: sprmids.hxx:158
const sal_uInt16 sprmTInsert
Definition: sprmids.hxx:232
const sal_uInt16 sprmTTlp
Definition: sprmids.hxx:230
const sal_uInt16 sprmSDyaPgn
Definition: sprmids.hxx:196
const sal_uInt16 sprmSDxaColSpacing
Definition: sprmids.hxx:185
const sal_uInt16 sprmPNest
Definition: sprmids.hxx:97
const sal_uInt16 sprmTMerge
Definition: sprmids.hxx:235
const sal_uInt16 sprmSDyaBottom
Definition: sprmids.hxx:217
const sal_uInt16 sprmPFKeepFollow
Definition: sprmids.hxx:87
const sal_uInt16 sprmSFEndnote
Definition: sprmids.hxx:199
const sal_uInt16 sprmCHpsMul
Definition: sprmids.hxx:171
const sal_uInt16 sprmCIco
Definition: sprmids.hxx:160
const sal_uInt16 sprmCDefault
Definition: sprmids.hxx:145
const sal_uInt16 sprmTDefTable
Definition: sprmids.hxx:228
const sal_uInt16 sprmCFVanish
Definition: sprmids.hxx:154
const sal_uInt16 sprmCKul
Definition: sprmids.hxx:156
const sal_uInt16 sprmPBrcBar10
Definition: sprmids.hxx:114
const sal_uInt16 sprmCSymbol
Definition: sprmids.hxx:141
const sal_uInt16 sprmTDefTableShd
Definition: sprmids.hxx:229
const sal_uInt16 sprmPDxaRight
Definition: sprmids.hxx:95
const sal_uInt16 sprmSBOrientation
Definition: sprmids.hxx:210
const sal_uInt16 sprmSCcolumns
Definition: sprmids.hxx:192
const sal_uInt16 sprmSLBetween
Definition: sprmids.hxx:206
const sal_uInt16 sprmSXaPage
Definition: sprmids.hxx:212
const sal_uInt16 sprmCFShadow
Definition: sprmids.hxx:151
const sal_uInt16 sprmSFProtected
Definition: sprmids.hxx:187
const sal_uInt16 sprmPDxaLeft
Definition: sprmids.hxx:96
const sal_uInt16 sprmCFObj
Definition: sprmids.hxx:174
const sal_uInt16 sprmSLnc
Definition: sprmids.hxx:200
const sal_uInt16 sprmPWr
Definition: sprmids.hxx:116
const sal_uInt16 sprmTDefTable10
Definition: sprmids.hxx:226
const sal_uInt16 sprmPicScale
Definition: sprmids.hxx:176
const sal_uInt16 sprmSDyaTop
Definition: sprmids.hxx:216
const sal_uInt16 sprmCFItalic
Definition: sprmids.hxx:148
const sal_uInt16 sprmPicBrcRight
Definition: sprmids.hxx:180
const sal_uInt16 sprmSDmBinFirst
Definition: sprmids.hxx:188
const sal_uInt16 sprmCFtc
Definition: sprmids.hxx:155
const sal_uInt16 sprmCFStrikeRM
Definition: sprmids.hxx:132
const sal_uInt16 LN_CMajority50
Definition: sprmids.hxx:55
const sal_uInt16 LN_PBrcl
Definition: sprmids.hxx:28
const sal_uInt16 LN_CFDiacColor
Definition: sprmids.hxx:57
const sal_uInt16 LN_CHpsPosAdj
Definition: sprmids.hxx:52
const sal_uInt16 LN_CDefault
Definition: sprmids.hxx:47
const sal_uInt16 LN_PDxaFromText10
Definition: sprmids.hxx:36
const sal_uInt16 LN_CLid
Definition: sprmids.hxx:50
const sal_uInt16 LN_TDefTable
Definition: sprmids.hxx:69
const sal_uInt16 LN_PBrcp
Definition: sprmids.hxx:29
const sal_uInt16 LN_PBrcBetween10
Definition: sprmids.hxx:34
const sal_uInt16 LN_THTMLProps
Definition: sprmids.hxx:71
const sal_uInt16 LN_SOlstAnm
Definition: sprmids.hxx:61
const sal_uInt16 LN_CSizePos
Definition: sprmids.hxx:49
const sal_uInt16 LN_CCpg
Definition: sprmids.hxx:58
const sal_uInt16 LN_PBrcTop10
Definition: sprmids.hxx:30
const sal_uInt16 LN_TSetShdOdd80
Definition: sprmids.hxx:74
const sal_uInt16 LN_CObjLocation
Definition: sprmids.hxx:45
const sal_uInt16 LN_TDefTable10
Definition: sprmids.hxx:70
const sal_uInt16 LN_CHpsNew50
Definition: sprmids.hxx:53
const sal_uInt16 LN_CFFtcAsciSymb
Definition: sprmids.hxx:46
const sal_uInt16 LN_PBrcBar10
Definition: sprmids.hxx:35
const sal_uInt16 LN_CHpsInc1
Definition: sprmids.hxx:54
const sal_uInt16 LN_PCrLf
Definition: sprmids.hxx:41
const sal_uInt16 LN_PBrcBottom10
Definition: sprmids.hxx:32
const sal_uInt16 LN_PBrcRight10
Definition: sprmids.hxx:33
const sal_uInt16 LN_PFSideBySide
Definition: sprmids.hxx:27
const sal_uInt16 LN_SDyaPgn
Definition: sprmids.hxx:63
const sal_uInt16 LN_TSetShd80
Definition: sprmids.hxx:73
const sal_uInt16 LN_PicBrcl
Definition: sprmids.hxx:59
const sal_uInt16 LN_PicScale
Definition: sprmids.hxx:60
const sal_uInt16 LN_SGprfIhdt
Definition: sprmids.hxx:65
const sal_uInt16 LN_PHugePapx
Definition: sprmids.hxx:42
const sal_uInt16 LN_PRuler
Definition: sprmids.hxx:37
const sal_uInt16 LN_PISnapBaseLine
Definition: sprmids.hxx:38
const sal_uInt16 LN_SBCustomize
Definition: sprmids.hxx:66
const sal_uInt16 LN_CHpsMul
Definition: sprmids.hxx:56
const sal_uInt16 LN_CIdCharType
Definition: sprmids.hxx:44
const sal_uInt16 LN_CHpsInc
Definition: sprmids.hxx:51
const sal_uInt16 LN_CChs
Definition: sprmids.hxx:43
const sal_uInt16 LN_PAnld
Definition: sprmids.hxx:39
const sal_uInt16 LN_PPropRMark
Definition: sprmids.hxx:40
const sal_uInt16 LN_TDiagLine
Definition: sprmids.hxx:75
const sal_uInt16 LN_CFtcDefault
Definition: sprmids.hxx:48
const sal_uInt16 LN_SFFacingCol
Definition: sprmids.hxx:68
const sal_uInt16 LN_PBrcLeft10
Definition: sprmids.hxx:31
const sal_uInt16 LN_SDxaPgn
Definition: sprmids.hxx:64
const sal_uInt16 LN_SFAutoPgn
Definition: sprmids.hxx:62
const sal_uInt16 LN_TSetBrc10
Definition: sprmids.hxx:72
const sal_uInt16 LN_SPropRMark
Definition: sprmids.hxx:67
constexpr OUStringLiteral aData
Definition: ww8scan.hxx:48
OString strip(const OString &rIn, char c)
int i
void SvStream & rStrm
rtl_TextEncoding getBestTextEncodingFromLocale(const css::lang::Locale &rLocale)
std::enable_if< std::is_signed< T >::value, bool >::type checked_add(T a, T b, T &result)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
T sanitizing_min(T a, T b)
std::enable_if< std::is_signed< T >::value, bool >::type checked_multiply(T a, T b, T &result)
std::enable_if< std::is_signed< T >::value, bool >::type checked_sub(T a, T b, T &result)
long Long
sal_uInt32 RGBToBGR(::Color nColour)
Definition: ww8struc.hxx:1087
WordVersion
Definition: types.hxx:31
@ eWW2
Definition: types.hxx:31
@ eWW1
Definition: types.hxx:31
@ eWW8
Definition: types.hxx:31
@ eWW7
Definition: types.hxx:31
@ eWW6
Definition: types.hxx:31
std::vector< sal_uInt8 > bytes
Definition: types.hxx:29
bool IsEightPlus(WordVersion eVer)
Definition: types.hxx:33
bool IsSevenMinus(WordVersion eVer)
Definition: types.hxx:32
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
sal_Int16 nId
QPRO_FUNC_TYPE nType
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
sal_uInt8 SVBT32[4]
sal_uInt8 SVBT16[2]
sal_uIntPtr sal_uLong
static LanguageType nLang
Definition: srtdlg.cxx:51
TOOLS_DLLPUBLIC OString read_uInt8s_ToOString(SvStream &rStrm, std::size_t nUnits)
OUString read_uInt8_lenPrefixed_uInt8s_ToOUString(SvStream &rStrm, rtl_TextEncoding eEnc)
TOOLS_DLLPUBLIC OUString read_uInt16s_ToOUString(SvStream &rStrm, std::size_t nUnits)
OString read_uInt8_lenPrefixed_uInt8s_ToOString(SvStream &rStrm)
OUString read_uInt8s_ToOUString(SvStream &rStrm, std::size_t nUnits, rtl_TextEncoding eEnc)
TOOLS_DLLPUBLIC bool checkSeek(SvStream &rSt, sal_uInt64 nOffset)
SEPr()
Definition: ww8scan.cxx:8527
unsigned int nLen
Definition: ww8scan.hxx:57
unsigned int nVari
Definition: ww8scan.hxx:58
const sal_uInt8 * pSprm
Definition: ww8scan.hxx:95
sal_Int32 nRemainingData
Definition: ww8scan.hxx:96
Document Properties.
Definition: ww8scan.hxx:1607
bool fNoSpaceRaiseLower
Definition: ww8scan.hxx:1714
bool fShowBreaksInFrames
Definition: ww8scan.hxx:1723
bool fOnlyWinPics
Definition: ww8scan.hxx:1634
bool fCompatibilityOptions_Unknown1_24
Definition: ww8scan.hxx:1737
bool fCompatibilityOptions_Unknown2_17
Definition: ww8scan.hxx:1805
bool fCompatibilityOptions_Unknown2_19
Definition: ww8scan.hxx:1807
bool fPrintFormData
Definition: ww8scan.hxx:1690
bool fRevMarking
Definition: ww8scan.hxx:1640
bool fDfltTrueType
Definition: ww8scan.hxx:1648
bool fLiveRecover
Definition: ww8scan.hxx:1831
sal_Int32 cParas
Definition: ww8scan.hxx:1685
bool fDontUseHTMLAutoSpacing
Definition: ww8scan.hxx:1787
bool fRMPrint
Definition: ww8scan.hxx:1653
bool fCompatibilityOptions_Unknown2_14
Definition: ww8scan.hxx:1800
bool fDispFormFieldSel
Definition: ww8scan.hxx:1651
sal_Int32 cCh
Definition: ww8scan.hxx:1683
bool fCompatibilityOptions_Unknown1_13
Definition: ww8scan.hxx:1725
bool fReverseFolio
Definition: ww8scan.hxx:1836
bool fCompatibilityOptions_Unknown2_20
Definition: ww8scan.hxx:1808
sal_Int16 dywDispPag
Definition: ww8scan.hxx:1782
sal_uInt16 cConsecHypLim
Definition: ww8scan.hxx:1675
bool fCompatibilityOptions_Unknown2_6
Definition: ww8scan.hxx:1790
bool fWCFootnoteEdn
Definition: ww8scan.hxx:1694
sal_uInt16 grfSuppression
Definition: ww8scan.hxx:1623
sal_Int32 dttmRevised
Definition: ww8scan.hxx:1678
sal_uInt16 rncFootnote
Definition: ww8scan.hxx:1629
bool fShadeFormData
Definition: ww8scan.hxx:1692
bool fHaveVersions
Definition: ww8scan.hxx:1768
bool fCompatibilityOptions_Unknown1_25
Definition: ww8scan.hxx:1738
sal_Int32 cWords
Definition: ww8scan.hxx:1682
bool fHtmlDoc
Definition: ww8scan.hxx:1761
bool fWriteReservation
Definition: ww8scan.hxx:1654
bool fLockAtn
Definition: ww8scan.hxx:1645
bool copts_fNoTabForInd
Definition: ww8scan.hxx:1658
bool fCompatibilityOptions_Unknown1_29
Definition: ww8scan.hxx:1742
bool fFactoidXML
Definition: ww8scan.hxx:1833
bool fPMHMainDoc
Definition: ww8scan.hxx:1622
bool fOrigWordTableRules
Definition: ww8scan.hxx:1721
sal_Int32 cChFootnoteEdn
Definition: ww8scan.hxx:1697
sal_uInt32 GetCompatibilityOptions2() const
Definition: ww8scan.cxx:8050
bool fRotateFontW6
Definition: ww8scan.hxx:1705
bool fNoLeading
Definition: ww8scan.hxx:1733
bool fCompatibilityOptions_Unknown2_28
Definition: ww8scan.hxx:1818
bool fCompatibilityOptions_Unknown2_26
Definition: ww8scan.hxx:1816
sal_uInt16 wSpare2
Definition: ww8scan.hxx:1676
sal_uInt16 rncEdn
Definition: ww8scan.hxx:1686
bool fMapPrintTextColor
Definition: ww8scan.hxx:1717
bool fEmbedFactoids
Definition: ww8scan.hxx:1832
sal_uInt16 epc
Definition: ww8scan.hxx:1688
sal_Int16 cPgFootnoteEdn
Definition: ww8scan.hxx:1698
bool fCompatibilityOptions_Unknown2_12
Definition: ww8scan.hxx:1798
bool fTransparentMetafiles
Definition: ww8scan.hxx:1722
sal_Int32 lKeyProtDoc
Definition: ww8scan.hxx:1701
bool fCompatibilityOptions_Unknown1_16
Definition: ww8scan.hxx:1728
bool fExpShRtn
Definition: ww8scan.hxx:1726
bool copts_fMapPrintTextColor
Definition: ww8scan.hxx:1662
ErrCode nDopError
Definition: ww8scan.hxx:1610
bool fBackup
Definition: ww8scan.hxx:1641
bool fCompatibilityOptions_Unknown2_16
Definition: ww8scan.hxx:1804
bool fCompatibilityOptions_Unknown2_22
Definition: ww8scan.hxx:1810
bool fDontBreakWrappedTables
Definition: ww8scan.hxx:1797
sal_Int16 dxaTab
Definition: ww8scan.hxx:1672
bool fSuppressTopSpacingMac5
Definition: ww8scan.hxx:1729
sal_uInt16 wSpare
Definition: ww8scan.hxx:1673
bool fAutoHyphen
Definition: ww8scan.hxx:1637
bool fFolioPrint
Definition: ww8scan.hxx:1835
bool fCompatibilityOptions_Unknown2_25
Definition: ww8scan.hxx:1815
bool fIncludeHeader
Definition: ww8scan.hxx:1764
sal_Int16 nfcEdnRef
Definition: ww8scan.hxx:1780
bool fCompatibilityOptions_Unknown2_32
Definition: ww8scan.hxx:1824
sal_Int32 cParasFootnoteEdn
Definition: ww8scan.hxx:1699
bool fMirrorMargins
Definition: ww8scan.hxx:1646
bool fCompatibilityOptions_Unknown2_27
Definition: ww8scan.hxx:1817
bool fOutlineDirtySave
Definition: ww8scan.hxx:1631
bool iGutterPos
Definition: ww8scan.hxx:1706
bool fFormNoFields
Definition: ww8scan.hxx:1638
bool copts_fOrigWordTableRules
Definition: ww8scan.hxx:1666
sal_uInt16 zkSaved
Definition: ww8scan.hxx:1704
bool fCompatibilityOptions_Unknown2_21
Definition: ww8scan.hxx:1809
bool fReadOnlyRecommended
Definition: ww8scan.hxx:1647
sal_Int32 cChWSFootnoteEdn
Definition: ww8scan.hxx:1773
sal_uInt16 nFootnote
Definition: ww8scan.hxx:1630
sal_Int16 nfcFootnoteRef
Definition: ww8scan.hxx:1779
bool bUseThaiLineBreakingRules
Definition: ww8scan.hxx:1844
bool fCompatibilityOptions_Unknown2_8
Definition: ww8scan.hxx:1792
bool fCompatibilityOptions_Unknown2_24
Definition: ww8scan.hxx:1814
sal_Int16 cPg
Definition: ww8scan.hxx:1684
sal_uInt16 fpc
Definition: ww8scan.hxx:1624
sal_Int32 cChWS
Definition: ww8scan.hxx:1772
bool fSnapBorder
Definition: ww8scan.hxx:1763
bool fSaveFormData
Definition: ww8scan.hxx:1691
sal_Int32 cDBCFootnoteEdn
Definition: ww8scan.hxx:1777
bool fPagHidden
Definition: ww8scan.hxx:1643
void SetCompatibilityOptions(sal_uInt32 a32Bit)
Definition: ww8scan.cxx:7938
WW8Dop()
Definition: ww8scan.cxx:7871
bool fCompatibilityOptions_Unknown2_4
Definition: ww8scan.hxx:1788
bool fFactoidAllDone
Definition: ww8scan.hxx:1834
bool fCompatibilityOptions_Unknown1_26
Definition: ww8scan.hxx:1739
bool fLabelDoc
Definition: ww8scan.hxx:1635
bool fPrintBodyBeforeHdr
Definition: ww8scan.hxx:1732
bool fMinFontSizePag
Definition: ww8scan.hxx:1767
bool fCompatibilityOptions_Unknown2_13
Definition: ww8scan.hxx:1799
sal_Int16 adt
Definition: ww8scan.hxx:1752
bool fHyphCapitals
Definition: ww8scan.hxx:1636
sal_Int32 cLines
Definition: ww8scan.hxx:1695
sal_Int32 dttmLastPrint
Definition: ww8scan.hxx:1679
sal_uInt16 wvkSaved
Definition: ww8scan.hxx:1702
sal_Int32 cWordsFootnoteEnd
Definition: ww8scan.hxx:1696
bool fNoColumnBalance
Definition: ww8scan.hxx:1718
bool copts_fExpShRtn
Definition: ww8scan.hxx:1670
bool fCompatibilityOptions_Unknown1_23
Definition: ww8scan.hxx:1736
bool copts_fConvMailMergeEsc
Definition: ww8scan.hxx:1664
sal_uInt16 nEdn
Definition: ww8scan.hxx:1687
sal_Int32 cDBC
Definition: ww8scan.hxx:1776
bool fAutoVersion
Definition: ww8scan.hxx:1769
bool fExactCWords
Definition: ww8scan.hxx:1642
bool fForcePageSizePag
Definition: ww8scan.hxx:1766
bool copts_fSuppressSpbfAfterPgBrk
Definition: ww8scan.hxx:1660
sal_uInt16 grpfIhdt
Definition: ww8scan.hxx:1627
bool fCompatibilityOptions_Unknown2_10
Definition: ww8scan.hxx:1796
sal_Int32 dttmCreated
Definition: ww8scan.hxx:1677
bool fConvMailMergeEsc
Definition: ww8scan.hxx:1719
bool fSuppressSpbfAfterPageBreak
Definition: ww8scan.hxx:1715
bool fRMView
Definition: ww8scan.hxx:1652
bool fEmbedFonts
Definition: ww8scan.hxx:1656
bool fCompatibilityOptions_Unknown2_23
Definition: ww8scan.hxx:1811
bool fCompatibilityOptions_Unknown1_28
Definition: ww8scan.hxx:1741
bool fWordCompat
Definition: ww8scan.hxx:1830
bool fIncludeFooter
Definition: ww8scan.hxx:1765
bool fSwapBordersFacingPgs
Definition: ww8scan.hxx:1724
bool fCompatibilityOptions_Unknown2_2
Definition: ww8scan.hxx:1786
bool fWidowControl
Definition: ww8scan.hxx:1617
bool fCompatibilityOptions_Unknown2_7
Definition: ww8scan.hxx:1791
bool fUsePrinterMetrics
Definition: ww8scan.hxx:1745
bool fCompatibilityOptions_Unknown1_30
Definition: ww8scan.hxx:1743
sal_Int16 hpsZoomFontPag
Definition: ww8scan.hxx:1781
bool fAcetateShowInsDel
Definition: ww8scan.hxx:1841
sal_Int16 nRevision
Definition: ww8scan.hxx:1680
bool fCompatibilityOptions_Unknown2_9
Definition: ww8scan.hxx:1795
bool fCompatibilityOptions_Unknown2_18
Definition: ww8scan.hxx:1806
bool fCompatibilityOptions_Unknown2_29
Definition: ww8scan.hxx:1819
sal_uInt16 wScaleSaved
Specifies the zoom percentage that was in use when the document was saved.
Definition: ww8scan.hxx:1703
bool copts_fNoSpaceRaiseLower
Definition: ww8scan.hxx:1659
bool fCompatibilityOptions_Unknown1_21
Definition: ww8scan.hxx:1734
bool copts_fNoColumnBalance
Definition: ww8scan.hxx:1663
bool fCompatibilityOptions_Unknown2_30
Definition: ww8scan.hxx:1820
bool fCompatibilityOptions_Unknown1_31
Definition: ww8scan.hxx:1744
bool fLockRev
Definition: ww8scan.hxx:1655
sal_uInt16 iTextLineEnding
Definition: ww8scan.hxx:1837
bool fAcetateShowMarkup
Definition: ww8scan.hxx:1839
bool fSuppressTopSpacing
Definition: ww8scan.hxx:1720
void Write(SvStream &rStrm, WW8Fib &rFib) const
Definition: ww8scan.cxx:8092
bool fCompatibilityOptions_Unknown1_27
Definition: ww8scan.hxx:1740
bool fLinkStyles
Definition: ww8scan.hxx:1639
bool fOnlyMacPics
Definition: ww8scan.hxx:1633
bool copts_fShowBreaksInFrames
Definition: ww8scan.hxx:1668
bool fAcetateShowAtn
Definition: ww8scan.hxx:1840
bool fPagResults
Definition: ww8scan.hxx:1644
bool fCompatibilityOptions_Unknown2_1
Definition: ww8scan.hxx:1785
bool copts_fSuppressTopSpacing
Definition: ww8scan.hxx:1665
bool fNoTabForInd
Definition: ww8scan.hxx:1713
bool fWrapTrailSpaces
Definition: ww8scan.hxx:1716
bool fPagSuppressTopSpacing
Definition: ww8scan.hxx:1649
sal_Int32 grfDocEvents
Definition: ww8scan.hxx:1774
WW8_DOGRID dogrid
Definition: ww8scan.hxx:1757
bool fCompatibilityOptions_Unknown2_31
Definition: ww8scan.hxx:1821
sal_uInt32 GetCompatibilityOptions() const
Definition: ww8scan.cxx:7975
sal_Int32 cLinesFootnoteEdn
Definition: ww8scan.hxx:1700
bool fHideFcc
Definition: ww8scan.hxx:1838
bool fCompatibilityOptions_Unknown2_5
Definition: ww8scan.hxx:1789
bool copts_fSwapBordersFacingPgs
Definition: ww8scan.hxx:1669
bool fFacingPages
Definition: ww8scan.hxx:1615
WW8DopTypography doptypography
Definition: ww8scan.hxx:1756
bool fProtEnabled
Definition: ww8scan.hxx:1650
bool fDoNotEmbedSystemFont
Definition: ww8scan.hxx:1829
bool fCompatibilityOptions_Unknown2_15
Definition: ww8scan.hxx:1801
sal_Int32 tmEdited
Definition: ww8scan.hxx:1681
bool fUseBackGroundInAllmodes
Definition: ww8scan.hxx:1827
void SetCompatibilityOptions2(sal_uInt32 a32Bit)
Definition: ww8scan.cxx:8014
bool fMWSmallCaps
Definition: ww8scan.hxx:1735
bool copts_fWrapTrailSpaces
Definition: ww8scan.hxx:1661
bool fAcetateShowProps
Definition: ww8scan.hxx:1842
bool copts_fTransparentMetafiles
Definition: ww8scan.hxx:1667
bool fCompatibilityOptions_Unknown1_15
Definition: ww8scan.hxx:1727
bool fTruncDxaExpand
Definition: ww8scan.hxx:1731
sal_uInt16 dxaHotZ
Definition: ww8scan.hxx:1674
sal_uInt16 nId
WW-id for fields.
Definition: ww8scan.hxx:197
WW8_CP nLen
total length (to skip over text)
Definition: ww8scan.hxx:192
sal_uInt8 nOpt
WW-Flags ( e.g.: changed by user )
Definition: ww8scan.hxx:198
WW8_CP nSCode
start of instructions code
Definition: ww8scan.hxx:193
bool bCodeNest
instruction used recursively
Definition: ww8scan.hxx:199
WW8_CP nLCode
length
Definition: ww8scan.hxx:194
WW8_CP nLRes
length ( == 0, if no result )
Definition: ww8scan.hxx:196
WW8_CP nSRes
start of result
Definition: ww8scan.hxx:195
bool bResNest
instruction inserted into result
Definition: ww8scan.hxx:200
sal_uInt8 nFlags
Definition: ww8scan.hxx:861
tools::Long nMemLen
Definition: ww8scan.hxx:854
const sal_uInt8 * pMemPos
Definition: ww8scan.hxx:857
sal_uInt16 nSprmId
Definition: ww8scan.hxx:858
tools::Long nCp2OrIdx
Definition: ww8scan.hxx:855
WW8_CP nOrigEndPos
Definition: ww8scan.hxx:890
bool bRealLineEnd
Definition: ww8scan.hxx:905
tools::Long nCpOfs
Definition: ww8scan.hxx:903
WW8_CP nEndPos
Definition: ww8scan.hxx:887
WW8_CP nStartPos
Definition: ww8scan.hxx:886
tools::Long nOrigSprmsLen
Definition: ww8scan.hxx:884
bool bFirstSprm
Definition: ww8scan.hxx:904
sal_Int32 nSprmsLen
Definition: ww8scan.hxx:902
WW8_CP nOrigStartPos
Definition: ww8scan.hxx:889
WW8_CP nCp2OrIdx
Definition: ww8scan.hxx:901
void Save(WW8PLCFxSave1 &rSave) const
Definition: ww8scan.cxx:5667
void ReduceByOffset()
Definition: ww8scan.cxx:4854
void Restore(const WW8PLCFxSave1 &rSave)
Definition: ww8scan.cxx:5691
const sal_uInt8 * pMemPos
Definition: ww8scan.hxx:883
WW8PLCFx * pPLCFx
Definition: ww8scan.hxx:881
WW8_CP nAttrStart
Definition: ww8scan.hxx:211
sal_uInt32 nPLCFxPos2
for PLCF_Cp_Fkp: PieceIter-Pos
Definition: ww8scan.hxx:206
tools::Long nPLCFxMemOfs
Definition: ww8scan.hxx:207
WW8_FC nStartFC
Definition: ww8scan.hxx:210
sal_uInt32 nPLCFxPos
Definition: ww8scan.hxx:205
WW8_CP nStartCp
for cp based iterator like PAP and CHP
Definition: ww8scan.hxx:208
WW8_CP nAttrEnd
Definition: ww8scan.hxx:212
tools::Long nCpOfs
Definition: ww8scan.hxx:209
WW8PLCFxSave1 aS[WW8PLCFMan::MAN_PLCF_COUNT]
Definition: ww8scan.hxx:1023
sal_uInt8 ico() const
Definition: ww8struc.hxx:254
sal_uInt8 brcType() const
Definition: ww8struc.hxx:250
sal_uInt8 dxpLineWidth() const
Definition: ww8struc.hxx:248
bool fShadow() const
Definition: ww8struc.hxx:252
sal_uInt8 dxpSpace() const
Definition: ww8struc.hxx:256
SVBT32 aBits1
Definition: ww8struc.hxx:311
sal_uInt8 brcType() const
Definition: ww8struc.hxx:325
WW8_BRCVer9()=default
sal_uInt8 dptLineWidth() const
Definition: ww8struc.hxx:323
SVBT32 aBits2
Definition: ww8struc.hxx:312
sal_uInt8 dptSpace() const
Definition: ww8struc.hxx:327
short DetermineBorderProperties(short *pSpace=nullptr) const
Definition: ww8scan.cxx:1370
sal_uInt8 dptSpace() const
Definition: ww8struc.hxx:280
bool isNil() const
Definition: ww8struc.hxx:286
sal_uInt8 ico() const
Definition: ww8struc.hxx:278
sal_uInt8 dptLineWidth() const
Definition: ww8struc.hxx:274
WW8_BRC()=default
bool fShadow() const
Definition: ww8struc.hxx:282
sal_uInt8 brcType() const
Definition: ww8struc.hxx:276
bool fFrame() const
Definition: ww8struc.hxx:284
short DetermineBorderProperties(short *pSpace) const
Definition: ww8scan.cxx:1364
base for reading AND working on (will have different subclasses
Definition: ww8struc.hxx:202
This is what we use in the Parser (and Dumper)
Definition: ww8struc.hxx:222
STD - STyle Definition.
Definition: ww8struc.hxx:170
#define ERR_SWG_READ_ERROR
Definition: swerror.h:25
unsigned char sal_uInt8
#define SAL_MAX_UINT16
#define SAL_MAX_INT32
sal_uInt16 sal_Unicode
Word2CHPX ReadWord2Chpx(SvStream &rSt, std::size_t nOffset, sal_uInt8 nSize)
Definition: ww8par2.cxx:4124
std::vector< sal_uInt8 > ChpxToSprms(const Word2CHPX &rChpx)
Definition: ww8par2.cxx:4012
static bool WW8GetFieldPara(WW8PLCFspecial &rPLCF, WW8FieldDesc &rF)
Definition: ww8scan.cxx:1967
static void lcl_checkFontname(OUString &sString)
Definition: ww8scan.cxx:7136
static bool IsExpandableSprm(sal_uInt16 nSpId)
Definition: ww8scan.cxx:2632
const int nSmallestPossibleFib
Definition: ww8scan.cxx:1564
static sal_uInt32 Get_ULong(sal_uInt8 *&p)
Definition: ww8scan.cxx:863
static sal_Int32 Get_Long(sal_uInt8 *&p)
Definition: ww8scan.cxx:870
static sal_uInt16 Get_UShort(sal_uInt8 *&p)
Definition: ww8scan.cxx:851
void WW8ReadSTTBF(bool bVer8, SvStream &rStrm, sal_uInt32 nStart, sal_Int32 nLen, sal_uInt16 nExtraLen, rtl_TextEncoding eCS, std::vector< OUString > &rArray, std::vector< ww::bytes > *pExtraArray, std::vector< OUString > *pValueArray)
reads array of strings (see MS documentation: String Table stored in File) returns NOT the original p...
Definition: ww8scan.cxx:4152
bool checkRead(SvStream &rSt, void *pDest, sal_uInt32 nLength)
Definition: ww8scan.cxx:8544
OUString read_uInt16_BeltAndBracesString(SvStream &rStrm)
Definition: ww8scan.cxx:2082
static constexpr SprmInfoRow InfoRow()
Definition: ww8scan.cxx:437
static bool WW8SkipField(WW8PLCFspecial &rPLCF)
Definition: ww8scan.cxx:1921
OUString read_uInt8_BeltAndBracesString(SvStream &rStrm, rtl_TextEncoding eEnc)
Definition: ww8scan.cxx:2075
static sal_Int16 Get_Short(sal_uInt8 *&p)
Definition: ww8scan.cxx:858
static sal_uInt8 Get_Byte(sal_uInt8 *&p)
Definition: ww8scan.cxx:844
static bool IsReplaceAllSprm(sal_uInt16 nSpId)
Definition: ww8scan.cxx:2627
const sal_uInt16 lLetterWidth
Definition: ww8scan.hxx:1880
eBookStatus
Definition: ww8scan.hxx:747
@ BOOK_NORMAL
Definition: ww8scan.hxx:747
@ MAN_MASK_NEW_SEP
Definition: ww8scan.hxx:867
@ MAN_MASK_NEW_PAP
Definition: ww8scan.hxx:866
ManTypes
Definition: ww8scan.hxx:871
@ MAN_HDFT
Definition: ww8scan.hxx:872
@ MAN_FTN
Definition: ww8scan.hxx:872
@ MAN_EDN
Definition: ww8scan.hxx:872
@ MAN_MAINTEXT
Definition: ww8scan.hxx:872
@ MAN_TXBX
Definition: ww8scan.hxx:873
@ MAN_AND
Definition: ww8scan.hxx:872
@ MAN_TXBX_HDFT
Definition: ww8scan.hxx:873
const sal_uInt16 lLetterHeight
Definition: ww8scan.hxx:1881
ePLCFT
Definition: ww8scan.hxx:385
@ CHP
Definition: ww8scan.hxx:385
@ PAP
Definition: ww8scan.hxx:385
@ PLCF_END
Definition: ww8scan.hxx:385
@ eFTN
Definition: ww8scan.hxx:388
@ eBKN
Definition: ww8scan.hxx:388
@ eEDN
Definition: ww8scan.hxx:388
@ eFLD
Definition: ww8scan.hxx:388
@ eATNBKN
Definition: ww8scan.hxx:388
@ eAND
Definition: ww8scan.hxx:388
@ eFACTOIDBKN
Definition: ww8scan.hxx:388
OUString read_uInt16_PascalString(SvStream &rStrm)
Definition: ww8scan.hxx:162
void Set_UInt32(sal_uInt8 *&p, sal_uInt32 n)
Definition: ww8struc.hxx:53
void Set_UInt8(sal_uInt8 *&p, sal_uInt8 n)
Definition: ww8struc.hxx:41
sal_Int32 WW8_CP
Definition: ww8struc.hxx:153
sal_Int32 WW8_FC
Definition: ww8struc.hxx:152
void Set_UInt16(sal_uInt8 *&p, sal_uInt16 n)
Definition: ww8struc.hxx:47
const WW8_FC WW8_FC_MAX
Definition: ww8struc.hxx:155
const WW8_CP WW8_CP_MAX
Definition: ww8struc.hxx:156
sal_Int32 nLength