Line data Source code
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 "ww8scan.hxx"
21 : #include "ww8par.hxx"
22 :
23 : #include <functional>
24 : #include <algorithm>
25 :
26 : #include <string.h>
27 : #include <i18nlangtag/mslangid.hxx>
28 : #include <filter/msfilter/sprmids.hxx>
29 : #include <rtl/tencinfo.h>
30 : #include <sal/macros.h>
31 :
32 : #ifdef DUMP
33 :
34 : #define ERR_SWG_READ_ERROR 1234
35 : #define OSL_ENSURE( a, b )
36 :
37 : #else // dump
38 : #include <swerror.h>
39 : #include <swtypes.hxx>
40 :
41 : #endif // dump
42 : #include <comphelper/processfactory.hxx>
43 : #include <comphelper/string.hxx>
44 : #include <unotools/localedatawrapper.hxx>
45 : #include <i18nlangtag/lang.h>
46 : #include <editeng/unolingu.hxx>
47 :
48 : #include <vcl/settings.hxx>
49 : #include <vcl/svapp.hxx>
50 :
51 : #include <stdio.h>
52 :
53 : #define ASSERT_RET_ON_FAIL( aCon, aError, aRet ) \
54 : OSL_ENSURE(aCon, aError); \
55 : if (!(aCon)) \
56 : return aRet;
57 :
58 : using namespace ::com::sun::star::lang;
59 :
60 : //-begin
61 : namespace SL
62 : {
63 : # define IMPLCONSTSTRINGARRAY(X) const char a##X[] = "" #X ""
64 : IMPLCONSTSTRINGARRAY(ObjectPool);
65 : IMPLCONSTSTRINGARRAY(1Table);
66 : IMPLCONSTSTRINGARRAY(0Table);
67 : IMPLCONSTSTRINGARRAY(Data);
68 : IMPLCONSTSTRINGARRAY(CheckBox);
69 : IMPLCONSTSTRINGARRAY(ListBox);
70 : IMPLCONSTSTRINGARRAY(TextBox);
71 : IMPLCONSTSTRINGARRAY(TextField);
72 : IMPLCONSTSTRINGARRAY(MSMacroCmds);
73 : }
74 :
75 : namespace
76 : {
77 : /**
78 : winword strings are typically Belt and Braces strings preceeded with a
79 : pascal style count, and ending with a c style 0 terminator. 16bit chars
80 : and count for ww8+ and 8bit chars and count for ww7-. The count and 0
81 : can be checked for integrity to catch errors (e.g. lotus created
82 : documents) where in error 8bit strings are used instead of 16bits
83 : strings for style names.
84 : */
85 960 : bool TestBeltAndBraces(SvStream& rStrm)
86 : {
87 960 : bool bRet = false;
88 960 : sal_uInt32 nOldPos = rStrm.Tell();
89 960 : sal_Unicode nBelt(0);
90 960 : rStrm.ReadUInt16( nBelt );
91 960 : nBelt *= sizeof(sal_Unicode);
92 960 : if (rStrm.good() && (rStrm.remainingSize() >= (nBelt + sizeof(sal_Unicode))))
93 : {
94 960 : rStrm.SeekRel(nBelt);
95 960 : if (rStrm.good())
96 : {
97 960 : sal_Unicode cBraces(0);
98 960 : rStrm.ReadUInt16( cBraces );
99 960 : if (rStrm.good() && cBraces == 0)
100 960 : bRet = true;
101 : }
102 : }
103 960 : rStrm.Seek(nOldPos);
104 960 : return bRet;
105 : }
106 : }
107 :
108 1265518 : inline bool operator==(const SprmInfo &rFirst, const SprmInfo &rSecond)
109 : {
110 1265518 : return (rFirst.nId == rSecond.nId);
111 : }
112 :
113 13 : const wwSprmSearcher *wwSprmParser::GetWW2SprmSearcher()
114 : {
115 : //double lock me
116 : // WW7- Sprms
117 : static const SprmInfo aSprms[] =
118 : {
119 : { 0, 0, L_FIX}, // "Default-sprm", will be skipped
120 : { 2, 1, L_FIX}, // "sprmPIstd", pap.istd (style code)
121 : { 3, 0, L_VAR}, // "sprmPIstdPermute pap.istd permutation
122 : { 4, 1, L_FIX}, // "sprmPIncLv1" pap.istddifference
123 : { 5, 1, L_FIX}, // "sprmPJc" pap.jc (justification)
124 : { 6, 1, L_FIX}, // "sprmPFSideBySide" pap.fSideBySide
125 : { 7, 1, L_FIX}, // "sprmPFKeep" pap.fKeep
126 : { 8, 1, L_FIX}, // "sprmPFKeepFollow " pap.fKeepFollow
127 : { 9, 1, L_FIX}, // "sprmPPageBreakBefore" pap.fPageBreakBefore
128 : { 10, 1, L_FIX}, // "sprmPBrcl" pap.brcl
129 : { 11, 1, L_FIX}, // "sprmPBrcp" pap.brcp
130 : { 12, 1, L_FIX}, // "sprmPNfcSeqNumb" pap.nfcSeqNumb
131 : { 13, 1, L_FIX}, // "sprmPNoSeqNumb" pap.nnSeqNumb
132 : { 14, 1, L_FIX}, // "sprmPFNoLineNumb" pap.fNoLnn
133 : { 15, 0, L_VAR}, // "?sprmPChgTabsPapx" pap.itbdMac, ...
134 : { 16, 2, L_FIX}, // "sprmPDxaRight" pap.dxaRight
135 : { 17, 2, L_FIX}, // "sprmPDxaLeft" pap.dxaLeft
136 : { 18, 2, L_FIX}, // "sprmPNest" pap.dxaLeft
137 : { 19, 2, L_FIX}, // "sprmPDxaLeft1" pap.dxaLeft1
138 : { 20, 2, L_FIX}, // "sprmPDyaLine" pap.lspd an LSPD
139 : { 21, 2, L_FIX}, // "sprmPDyaBefore" pap.dyaBefore
140 : { 22, 2, L_FIX}, // "sprmPDyaAfter" pap.dyaAfter
141 : { 23, 0, L_VAR}, // "?sprmPChgTabs" pap.itbdMac, pap.rgdxaTab, ...
142 : { 24, 1, L_FIX}, // "sprmPFInTable" pap.fInTable
143 : { 25, 1, L_FIX}, // "sprmPTtp" pap.fTtp
144 : { 26, 2, L_FIX}, // "sprmPDxaAbs" pap.dxaAbs
145 : { 27, 2, L_FIX}, // "sprmPDyaAbs" pap.dyaAbs
146 : { 28, 2, L_FIX}, // "sprmPDxaWidth" pap.dxaWidth
147 : { 29, 1, L_FIX}, // "sprmPPc" pap.pcHorz, pap.pcVert
148 : { 30, 2, L_FIX}, // "sprmPBrcTop10" pap.brcTop BRC10
149 : { 31, 2, L_FIX}, // "sprmPBrcLeft10" pap.brcLeft BRC10
150 : { 32, 2, L_FIX}, // "sprmPBrcBottom10" pap.brcBottom BRC10
151 : { 33, 2, L_FIX}, // "sprmPBrcRight10" pap.brcRight BRC10
152 : { 34, 2, L_FIX}, // "sprmPBrcBetween10" pap.brcBetween BRC10
153 : { 35, 2, L_FIX}, // "sprmPBrcBar10" pap.brcBar BRC10
154 : { 36, 2, L_FIX}, // "sprmPFromText10" pap.dxaFromText dxa
155 : { 37, 1, L_FIX}, // "sprmPWr" pap.wr wr
156 : { 38, 2, L_FIX}, // "sprmPBrcTop" pap.brcTop BRC
157 : { 39, 2, L_FIX}, // "sprmPBrcLeft" pap.brcLeft BRC
158 : { 40, 2, L_FIX}, // "sprmPBrcBottom" pap.brcBottom BRC
159 : { 41, 2, L_FIX}, // "sprmPBrcRight" pap.brcRight BRC
160 : { 42, 2, L_FIX}, // "sprmPBrcBetween" pap.brcBetween BRC
161 : { 43, 2, L_FIX}, // "sprmPBrcBar" pap.brcBar BRC word
162 : { 44, 1, L_FIX}, // "sprmPFNoAutoHyph" pap.fNoAutoHyph
163 : { 45, 2, L_FIX}, // "sprmPWHeightAbs" pap.wHeightAbs w
164 : { 46, 2, L_FIX}, // "sprmPDcs" pap.dcs DCS
165 : { 47, 2, L_FIX}, // "sprmPShd" pap.shd SHD
166 : { 48, 2, L_FIX}, // "sprmPDyaFromText" pap.dyaFromText dya
167 : { 49, 2, L_FIX}, // "sprmPDxaFromText" pap.dxaFromText dxa
168 : { 50, 1, L_FIX}, // "sprmPFBiDi" pap.fBiDi 0 or 1 byte
169 : { 51, 1, L_FIX}, // "sprmPFWidowControl" pap.fWidowControl 0 or 1 byte
170 : { 52, 0, L_FIX}, // "?sprmPRuler 52"
171 : { 53, 1, L_FIX}, // "sprmCFStrikeRM" chp.fRMarkDel 1 or 0 bit
172 : { 54, 1, L_FIX}, // "sprmCFRMark" chp.fRMark 1 or 0 bit
173 : { 55, 1, L_FIX}, // "sprmCFFldVanish" chp.fFldVanish 1 or 0 bit
174 : { 57, 0, L_VAR}, // "sprmCDefault" whole CHP
175 : { 58, 0, L_FIX}, // "sprmCPlain" whole CHP
176 : { 60, 1, L_FIX}, // "sprmCFBold" chp.fBold 0,1, 128, or 129
177 : { 61, 1, L_FIX}, // "sprmCFItalic" chp.fItalic 0,1, 128, or 129
178 : { 62, 1, L_FIX}, // "sprmCFStrike" chp.fStrike 0,1, 128, or 129
179 : { 63, 1, L_FIX}, // "sprmCFOutline" chp.fOutline 0,1, 128, or 129
180 : { 64, 1, L_FIX}, // "sprmCFShadow" chp.fShadow 0,1, 128, or 129
181 : { 65, 1, L_FIX}, // "sprmCFSmallCaps" chp.fSmallCaps 0,1, 128, or 129
182 : { 66, 1, L_FIX}, // "sprmCFCaps" chp.fCaps 0,1, 128, or 129
183 : { 67, 1, L_FIX}, // "sprmCFVanish" chp.fVanish 0,1, 128, or 129
184 : { 68, 2, L_FIX}, // "sprmCFtc" chp.ftc ftc word
185 : { 69, 1, L_FIX}, // "sprmCKul" chp.kul kul byte
186 : { 70, 3, L_FIX}, // "sprmCSizePos" chp.hps, chp.hpsPos
187 : { 71, 2, L_FIX}, // "sprmCDxaSpace" chp.dxaSpace dxa
188 : { 72, 2, L_FIX}, // "sprmCLid" chp.lid LID
189 : { 73, 1, L_FIX}, // "sprmCIco" chp.ico ico byte
190 : { 74, 1, L_FIX}, // "sprmCHps" chp.hps hps !word!
191 : { 75, 1, L_FIX}, // "sprmCHpsInc" chp.hps
192 : { 76, 1, L_FIX}, // "sprmCHpsPos" chp.hpsPos hps !word!
193 : { 77, 1, L_FIX}, // "sprmCHpsPosAdj" chp.hpsPos hps
194 : { 78, 0, L_VAR}, // "?sprmCMajority" chp.fBold, chp.fItalic, ...
195 : { 80, 1, L_FIX}, // "sprmCFBoldBi" chp.fBoldBi
196 : { 81, 1, L_FIX}, // "sprmCFItalicBi" chp.fItalicBi
197 : { 82, 2, L_FIX}, // "sprmCFtcBi" chp.ftcBi
198 : { 83, 2, L_FIX}, // "sprmClidBi" chp.lidBi
199 : { 84, 1, L_FIX}, // "sprmCIcoBi" chp.icoBi
200 : { 85, 1, L_FIX}, // "sprmCHpsBi" chp.hpsBi
201 : { 86, 1, L_FIX}, // "sprmCFBiDi" chp.fBiDi
202 : { 87, 1, L_FIX}, // "sprmCFDiacColor" chp.fDiacUSico
203 : { 94, 1, L_FIX}, // "sprmPicBrcl" pic.brcl brcl (see PIC definition)
204 : { 95,12, L_VAR}, // "sprmPicScale" pic.mx, pic.my, pic.dxaCropleft,
205 : { 96, 2, L_FIX}, // "sprmPicBrcTop" pic.brcTop BRC word
206 : { 97, 2, L_FIX}, // "sprmPicBrcLeft" pic.brcLeft BRC word
207 : { 98, 2, L_FIX}, // "sprmPicBrcBottom" pic.brcBottom BRC word
208 : { 99, 2, L_FIX}, // "sprmPicBrcRight" pic.brcRight BRC word
209 : {112, 1, L_FIX}, // "sprmSFRTLGutter", set to one if gutter is on
210 : {114, 1, L_FIX}, // "sprmSFBiDi" ;;;
211 : {115, 2, L_FIX}, // "sprmSDmBinFirst" sep.dmBinFirst word
212 : {116, 2, L_FIX}, // "sprmSDmBinOther" sep.dmBinOther word
213 : {117, 1, L_FIX}, // "sprmSBkc" sep.bkc bkc byte
214 : {118, 1, L_FIX}, // "sprmSFTitlePage" sep.fTitlePage 0 or 1 byte
215 : {119, 2, L_FIX}, // "sprmSCcolumns" sep.ccolM1 # of cols - 1 word
216 : {120, 2, L_FIX}, // "sprmSDxaColumns" sep.dxaColumns dxa word
217 : {121, 1, L_FIX}, // "sprmSFAutoPgn" sep.fAutoPgn obsolete byte
218 : {122, 1, L_FIX}, // "sprmSNfcPgn" sep.nfcPgn nfc byte
219 : {123, 2, L_FIX}, // "sprmSDyaPgn" sep.dyaPgn dya short
220 : {124, 2, L_FIX}, // "sprmSDxaPgn" sep.dxaPgn dya short
221 : {125, 1, L_FIX}, // "sprmSFPgnRestart" sep.fPgnRestart 0 or 1 byte
222 : {126, 1, L_FIX}, // "sprmSFEndnote" sep.fEndnote 0 or 1 byte
223 : {127, 1, L_FIX}, // "sprmSLnc" sep.lnc lnc byte
224 : {128, 1, L_FIX}, // "sprmSGprfIhdt" sep.grpfIhdt grpfihdt
225 : {129, 2, L_FIX}, // "sprmSNLnnMod" sep.nLnnMod non-neg int. word
226 : {130, 2, L_FIX}, // "sprmSDxaLnn" sep.dxaLnn dxa word
227 : {131, 2, L_FIX}, // "sprmSDyaHdrTop" sep.dyaHdrTop dya word
228 : {132, 2, L_FIX}, // "sprmSDyaHdrBottom" sep.dyaHdrBottom dya word
229 : {133, 1, L_FIX}, // "sprmSLBetween" sep.fLBetween 0 or 1 byte
230 : {134, 1, L_FIX}, // "sprmSVjc" sep.vjc vjc byte
231 : {135, 2, L_FIX}, // "sprmSLnnMin" sep.lnnMin lnn word
232 : {136, 2, L_FIX}, // "sprmSPgnStart" sep.pgnStart pgn word
233 : {137, 1, L_FIX}, // "sprmSBOrientation" sep.dmOrientPage dm byte
234 : {138, 1, L_FIX}, // "sprmSFFacingCol" ;;;
235 : {139, 2, L_FIX}, // "sprmSXaPage" sep.xaPage xa word
236 : {140, 2, L_FIX}, // "sprmSYaPage" sep.yaPage ya word
237 : {141, 2, L_FIX}, // "sprmSDxaLeft" sep.dxaLeft dxa word
238 : {142, 2, L_FIX}, // "sprmSDxaRight" sep.dxaRight dxa word
239 : {143, 2, L_FIX}, // "sprmSDyaTop" sep.dyaTop dya word
240 : {144, 2, L_FIX}, // "sprmSDyaBottom" sep.dyaBottom dya word
241 : {145, 2, L_FIX}, // "sprmSDzaGutter" sep.dzaGutter dza word
242 : {146, 2, L_FIX}, // "sprmTJc" tap.jc jc (low order byte is significant)
243 : {147, 2, L_FIX}, // "sprmTDxaLeft" tap.rgdxaCenter dxa word
244 : {148, 2, L_FIX}, // "sprmTDxaGapHalf" tap.dxaGapHalf, tap.rgdxaCenter
245 : {149, 1, L_FIX}, // "sprmTFBiDi" ;;;
246 : {152, 0, L_VAR}, // "sprmTDefTable10" tap.rgdxaCenter, tap.rgtc complex
247 : {153, 2, L_FIX}, // "sprmTDyaRowHeight" tap.dyaRowHeight dya word
248 : {154, 0, L_VAR2},// "sprmTDefTable" tap.rgtc complex
249 : {155, 1, L_VAR}, // "sprmTDefTableShd" tap.rgshd complex
250 : {157, 5, L_FIX}, // "sprmTSetBrc" tap.rgtc[].rgbrc complex 5 bytes
251 : {158, 4, L_FIX}, // "sprmTInsert" tap.rgdxaCenter,tap.rgtc complex
252 : {159, 2, L_FIX}, // "sprmTDelete" tap.rgdxaCenter, tap.rgtc complex
253 : {160, 4, L_FIX}, // "sprmTDxaCol" tap.rgdxaCenter complex
254 : {161, 2, L_FIX}, // "sprmTMerge" tap.fFirstMerged, tap.fMerged complex
255 : {162, 2, L_FIX}, // "sprmTSplit" tap.fFirstMerged, tap.fMerged complex
256 : {163, 5, L_FIX}, // "sprmTSetBrc10" tap.rgtc[].rgbrc complex 5 bytes
257 : {164, 4, L_FIX}, // "sprmTSetShd", tap.rgshd complex 4 bytes
258 : };
259 :
260 13 : static wwSprmSearcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
261 13 : return &aSprmSrch;
262 : };
263 :
264 0 : const wwSprmSearcher *wwSprmParser::GetWW6SprmSearcher()
265 : {
266 : //double lock me
267 : // WW7- Sprms
268 : static const SprmInfo aSprms[] =
269 : {
270 : { 0, 0, L_FIX}, // "Default-sprm", wird uebersprungen
271 : { 2, 2, L_FIX}, // "sprmPIstd", pap.istd (style code)
272 : { 3, 3, L_VAR}, // "sprmPIstdPermute pap.istd permutation
273 : { 4, 1, L_FIX}, // "sprmPIncLv1" pap.istddifference
274 : { 5, 1, L_FIX}, // "sprmPJc" pap.jc (justification)
275 : { 6, 1, L_FIX}, // "sprmPFSideBySide" pap.fSideBySide
276 : { 7, 1, L_FIX}, // "sprmPFKeep" pap.fKeep
277 : { 8, 1, L_FIX}, // "sprmPFKeepFollow " pap.fKeepFollow
278 : { 9, 1, L_FIX}, // "sprmPPageBreakBefore" pap.fPageBreakBefore
279 : { 10, 1, L_FIX}, // "sprmPBrcl" pap.brcl
280 : { 11, 1, L_FIX}, // "sprmPBrcp" pap.brcp
281 : { 12, 0, L_VAR}, // "sprmPAnld" pap.anld (ANLD structure)
282 : { 13, 1, L_FIX}, // "sprmPNLvlAnm" pap.nLvlAnm nn
283 : { 14, 1, L_FIX}, // "sprmPFNoLineNumb" pap.fNoLnn
284 : { 15, 0, L_VAR}, // "?sprmPChgTabsPapx" pap.itbdMac, ...
285 : { 16, 2, L_FIX}, // "sprmPDxaRight" pap.dxaRight
286 : { 17, 2, L_FIX}, // "sprmPDxaLeft" pap.dxaLeft
287 : { 18, 2, L_FIX}, // "sprmPNest" pap.dxaLeft
288 : { 19, 2, L_FIX}, // "sprmPDxaLeft1" pap.dxaLeft1
289 : { 20, 4, L_FIX}, // "sprmPDyaLine" pap.lspd an LSPD
290 : { 21, 2, L_FIX}, // "sprmPDyaBefore" pap.dyaBefore
291 : { 22, 2, L_FIX}, // "sprmPDyaAfter" pap.dyaAfter
292 : { 23, 0, L_VAR}, // "?sprmPChgTabs" pap.itbdMac, pap.rgdxaTab, ...
293 : { 24, 1, L_FIX}, // "sprmPFInTable" pap.fInTable
294 : { 25, 1, L_FIX}, // "sprmPTtp" pap.fTtp
295 : { 26, 2, L_FIX}, // "sprmPDxaAbs" pap.dxaAbs
296 : { 27, 2, L_FIX}, // "sprmPDyaAbs" pap.dyaAbs
297 : { 28, 2, L_FIX}, // "sprmPDxaWidth" pap.dxaWidth
298 : { 29, 1, L_FIX}, // "sprmPPc" pap.pcHorz, pap.pcVert
299 : { 30, 2, L_FIX}, // "sprmPBrcTop10" pap.brcTop BRC10
300 : { 31, 2, L_FIX}, // "sprmPBrcLeft10" pap.brcLeft BRC10
301 : { 32, 2, L_FIX}, // "sprmPBrcBottom10" pap.brcBottom BRC10
302 : { 33, 2, L_FIX}, // "sprmPBrcRight10" pap.brcRight BRC10
303 : { 34, 2, L_FIX}, // "sprmPBrcBetween10" pap.brcBetween BRC10
304 : { 35, 2, L_FIX}, // "sprmPBrcBar10" pap.brcBar BRC10
305 : { 36, 2, L_FIX}, // "sprmPFromText10" pap.dxaFromText dxa
306 : { 37, 1, L_FIX}, // "sprmPWr" pap.wr wr
307 : { 38, 2, L_FIX}, // "sprmPBrcTop" pap.brcTop BRC
308 : { 39, 2, L_FIX}, // "sprmPBrcLeft" pap.brcLeft BRC
309 : { 40, 2, L_FIX}, // "sprmPBrcBottom" pap.brcBottom BRC
310 : { 41, 2, L_FIX}, // "sprmPBrcRight" pap.brcRight BRC
311 : { 42, 2, L_FIX}, // "sprmPBrcBetween" pap.brcBetween BRC
312 : { 43, 2, L_FIX}, // "sprmPBrcBar" pap.brcBar BRC word
313 : { 44, 1, L_FIX}, // "sprmPFNoAutoHyph" pap.fNoAutoHyph
314 : { 45, 2, L_FIX}, // "sprmPWHeightAbs" pap.wHeightAbs w
315 : { 46, 2, L_FIX}, // "sprmPDcs" pap.dcs DCS
316 : { 47, 2, L_FIX}, // "sprmPShd" pap.shd SHD
317 : { 48, 2, L_FIX}, // "sprmPDyaFromText" pap.dyaFromText dya
318 : { 49, 2, L_FIX}, // "sprmPDxaFromText" pap.dxaFromText dxa
319 : { 50, 1, L_FIX}, // "sprmPFLocked" pap.fLocked 0 or 1 byte
320 : { 51, 1, L_FIX}, // "sprmPFWidowControl" pap.fWidowControl 0 or 1 byte
321 : { 52, 0, L_FIX}, // "?sprmPRuler 52"
322 : { 64, 0, L_VAR}, // rtl property ?
323 : { 65, 1, L_FIX}, // "sprmCFStrikeRM" chp.fRMarkDel 1 or 0 bit
324 : { 66, 1, L_FIX}, // "sprmCFRMark" chp.fRMark 1 or 0 bit
325 : { 67, 1, L_FIX}, // "sprmCFFldVanish" chp.fFldVanish 1 or 0 bit
326 : { 68, 0, L_VAR}, // "sprmCPicLocation" chp.fcPic and chp.fSpec
327 : { 69, 2, L_FIX}, // "sprmCIbstRMark" chp.ibstRMark index into sttbRMark
328 : { 70, 4, L_FIX}, // "sprmCDttmRMark" chp.dttm DTTM long
329 : { 71, 1, L_FIX}, // "sprmCFData" chp.fData 1 or 0 bit
330 : { 72, 2, L_FIX}, // "sprmCRMReason" chp.idslRMReason an index to a table
331 : { 73, 3, L_FIX}, // "sprmCChse" chp.fChsDiff and chp.chse
332 : { 74, 0, L_VAR}, // "sprmCSymbol" chp.fSpec, chp.chSym and chp.ftcSym
333 : { 75, 1, L_FIX}, // "sprmCFOle2" chp.fOle2 1 or 0 bit
334 : { 77, 0, L_VAR}, // unknown
335 : { 79, 0, L_VAR}, // unknown
336 : { 80, 2, L_FIX}, // "sprmCIstd" chp.istd istd, see stylesheet definition
337 : { 81, 0, L_VAR}, // "sprmCIstdPermute" chp.istd permutation vector
338 : { 82, 0, L_VAR}, // "sprmCDefault" whole CHP
339 : { 83, 0, L_FIX}, // "sprmCPlain" whole CHP
340 : { 85, 1, L_FIX}, // "sprmCFBold" chp.fBold 0,1, 128, or 129
341 : { 86, 1, L_FIX}, // "sprmCFItalic" chp.fItalic 0,1, 128, or 129
342 : { 87, 1, L_FIX}, // "sprmCFStrike" chp.fStrike 0,1, 128, or 129
343 : { 88, 1, L_FIX}, // "sprmCFOutline" chp.fOutline 0,1, 128, or 129
344 : { 89, 1, L_FIX}, // "sprmCFShadow" chp.fShadow 0,1, 128, or 129
345 : { 90, 1, L_FIX}, // "sprmCFSmallCaps" chp.fSmallCaps 0,1, 128, or 129
346 : { 91, 1, L_FIX}, // "sprmCFCaps" chp.fCaps 0,1, 128, or 129
347 : { 92, 1, L_FIX}, // "sprmCFVanish" chp.fVanish 0,1, 128, or 129
348 : { 93, 2, L_FIX}, // "sprmCFtc" chp.ftc ftc word
349 : { 94, 1, L_FIX}, // "sprmCKul" chp.kul kul byte
350 : { 95, 3, L_FIX}, // "sprmCSizePos" chp.hps, chp.hpsPos
351 : { 96, 2, L_FIX}, // "sprmCDxaSpace" chp.dxaSpace dxa
352 : { 97, 2, L_FIX}, // "sprmCLid" chp.lid LID
353 : { 98, 1, L_FIX}, // "sprmCIco" chp.ico ico byte
354 : { 99, 2, L_FIX}, // "sprmCHps" chp.hps hps !word!
355 : {100, 1, L_FIX}, // "sprmCHpsInc" chp.hps
356 : {101, 2, L_FIX}, // "sprmCHpsPos" chp.hpsPos hps !word!
357 : {102, 1, L_FIX}, // "sprmCHpsPosAdj" chp.hpsPos hps
358 : {103, 0, L_VAR}, // "?sprmCMajority" chp.fBold, chp.fItalic, ...
359 : {104, 1, L_FIX}, // "sprmCIss" chp.iss iss
360 : {105, 0, L_VAR}, // "sprmCHpsNew50" chp.hps hps variable width
361 : {106, 0, L_VAR}, // "sprmCHpsInc1" chp.hps complex
362 : {107, 2, L_FIX}, // "sprmCHpsKern" chp.hpsKern hps
363 : {108, 0, L_VAR}, // "sprmCMajority50" chp.fBold, chp.fItalic, ...
364 : {109, 2, L_FIX}, // "sprmCHpsMul" chp.hps percentage to grow hps
365 : {110, 2, L_FIX}, // "sprmCCondHyhen" chp.ysri ysri
366 : {111, 2, L_FIX}, // rtl bold
367 : {112, 2, L_FIX}, // rtl italic
368 : {113, 0, L_VAR}, // rtl property ?
369 : {115, 0, L_VAR}, // rtl property ?
370 : {116, 0, L_VAR}, // unknown
371 : {117, 1, L_FIX}, // "sprmCFSpec" chp.fSpec 1 or 0 bit
372 : {118, 1, L_FIX}, // "sprmCFObj" chp.fObj 1 or 0 bit
373 : {119, 1, L_FIX}, // "sprmPicBrcl" pic.brcl brcl (see PIC definition)
374 : {120,12, L_VAR}, // "sprmPicScale" pic.mx, pic.my, pic.dxaCropleft,
375 : {121, 2, L_FIX}, // "sprmPicBrcTop" pic.brcTop BRC word
376 : {122, 2, L_FIX}, // "sprmPicBrcLeft" pic.brcLeft BRC word
377 : {123, 2, L_FIX}, // "sprmPicBrcBottom" pic.brcBottom BRC word
378 : {124, 2, L_FIX}, // "sprmPicBrcRight" pic.brcRight BRC word
379 : {131, 1, L_FIX}, // "sprmSScnsPgn" sep.cnsPgn cns byte
380 : {132, 1, L_FIX}, // "sprmSiHeadingPgn" sep.iHeadingPgn
381 : {133, 0, L_VAR}, // "sprmSOlstAnm" sep.olstAnm OLST variable length
382 : {136, 3, L_FIX}, // "sprmSDxaColWidth" sep.rgdxaColWidthSpacing complex
383 : {137, 3, L_FIX}, // "sprmSDxaColSpacing" sep.rgdxaColWidthSpacing
384 : {138, 1, L_FIX}, // "sprmSFEvenlySpaced" sep.fEvenlySpaced 1 or 0
385 : {139, 1, L_FIX}, // "sprmSFProtected" sep.fUnlocked 1 or 0 byte
386 : {140, 2, L_FIX}, // "sprmSDmBinFirst" sep.dmBinFirst word
387 : {141, 2, L_FIX}, // "sprmSDmBinOther" sep.dmBinOther word
388 : {142, 1, L_FIX}, // "sprmSBkc" sep.bkc bkc byte
389 : {143, 1, L_FIX}, // "sprmSFTitlePage" sep.fTitlePage 0 or 1 byte
390 : {144, 2, L_FIX}, // "sprmSCcolumns" sep.ccolM1 # of cols - 1 word
391 : {145, 2, L_FIX}, // "sprmSDxaColumns" sep.dxaColumns dxa word
392 : {146, 1, L_FIX}, // "sprmSFAutoPgn" sep.fAutoPgn obsolete byte
393 : {147, 1, L_FIX}, // "sprmSNfcPgn" sep.nfcPgn nfc byte
394 : {148, 2, L_FIX}, // "sprmSDyaPgn" sep.dyaPgn dya short
395 : {149, 2, L_FIX}, // "sprmSDxaPgn" sep.dxaPgn dya short
396 : {150, 1, L_FIX}, // "sprmSFPgnRestart" sep.fPgnRestart 0 or 1 byte
397 : {151, 1, L_FIX}, // "sprmSFEndnote" sep.fEndnote 0 or 1 byte
398 : {152, 1, L_FIX}, // "sprmSLnc" sep.lnc lnc byte
399 : {153, 1, L_FIX}, // "sprmSGprfIhdt" sep.grpfIhdt grpfihdt
400 : {154, 2, L_FIX}, // "sprmSNLnnMod" sep.nLnnMod non-neg int. word
401 : {155, 2, L_FIX}, // "sprmSDxaLnn" sep.dxaLnn dxa word
402 : {156, 2, L_FIX}, // "sprmSDyaHdrTop" sep.dyaHdrTop dya word
403 : {157, 2, L_FIX}, // "sprmSDyaHdrBottom" sep.dyaHdrBottom dya word
404 : {158, 1, L_FIX}, // "sprmSLBetween" sep.fLBetween 0 or 1 byte
405 : {159, 1, L_FIX}, // "sprmSVjc" sep.vjc vjc byte
406 : {160, 2, L_FIX}, // "sprmSLnnMin" sep.lnnMin lnn word
407 : {161, 2, L_FIX}, // "sprmSPgnStart" sep.pgnStart pgn word
408 : {162, 1, L_FIX}, // "sprmSBOrientation" sep.dmOrientPage dm byte
409 : {163, 0, L_FIX}, // "?SprmSBCustomize 163"
410 : {164, 2, L_FIX}, // "sprmSXaPage" sep.xaPage xa word
411 : {165, 2, L_FIX}, // "sprmSYaPage" sep.yaPage ya word
412 : {166, 2, L_FIX}, // "sprmSDxaLeft" sep.dxaLeft dxa word
413 : {167, 2, L_FIX}, // "sprmSDxaRight" sep.dxaRight dxa word
414 : {168, 2, L_FIX}, // "sprmSDyaTop" sep.dyaTop dya word
415 : {169, 2, L_FIX}, // "sprmSDyaBottom" sep.dyaBottom dya word
416 : {170, 2, L_FIX}, // "sprmSDzaGutter" sep.dzaGutter dza word
417 : {171, 2, L_FIX}, // "sprmSDMPaperReq" sep.dmPaperReq dm word
418 : {179, 0, L_VAR}, // rtl property ?
419 : {181, 0, L_VAR}, // rtl property ?
420 : {182, 2, L_FIX}, // "sprmTJc" tap.jc jc (low order byte is significant)
421 : {183, 2, L_FIX}, // "sprmTDxaLeft" tap.rgdxaCenter dxa word
422 : {184, 2, L_FIX}, // "sprmTDxaGapHalf" tap.dxaGapHalf, tap.rgdxaCenter
423 : {185, 1, L_FIX}, // "sprmTFCantSplit" tap.fCantSplit 1 or 0 byte
424 : {186, 1, L_FIX}, // "sprmTTableHeader" tap.fTableHeader 1 or 0 byte
425 : {187,12, L_FIX}, // "sprmTTableBorders" tap.rgbrcTable complex 12 bytes
426 : {188, 0, L_VAR}, // "sprmTDefTable10" tap.rgdxaCenter, tap.rgtc complex
427 : {189, 2, L_FIX}, // "sprmTDyaRowHeight" tap.dyaRowHeight dya word
428 : {190, 0, L_VAR2},// "sprmTDefTable" tap.rgtc complex
429 : {191, 1, L_VAR}, // "sprmTDefTableShd" tap.rgshd complex
430 : {192, 4, L_FIX}, // "sprmTTlp" tap.tlp TLP 4 bytes
431 : {193, 5, L_FIX}, // "sprmTSetBrc" tap.rgtc[].rgbrc complex 5 bytes
432 : {194, 4, L_FIX}, // "sprmTInsert" tap.rgdxaCenter,tap.rgtc complex
433 : {195, 2, L_FIX}, // "sprmTDelete" tap.rgdxaCenter, tap.rgtc complex
434 : {196, 4, L_FIX}, // "sprmTDxaCol" tap.rgdxaCenter complex
435 : {197, 2, L_FIX}, // "sprmTMerge" tap.fFirstMerged, tap.fMerged complex
436 : {198, 2, L_FIX}, // "sprmTSplit" tap.fFirstMerged, tap.fMerged complex
437 : {199, 5, L_FIX}, // "sprmTSetBrc10" tap.rgtc[].rgbrc complex 5 bytes
438 : {200, 4, L_FIX}, // "sprmTSetShd", tap.rgshd complex 4 bytes
439 : {207, 0, L_VAR} // rtl property ?
440 : };
441 :
442 0 : static wwSprmSearcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
443 0 : return &aSprmSrch;
444 : };
445 :
446 1655 : const wwSprmSearcher *wwSprmParser::GetWW8SprmSearcher()
447 : {
448 : //double lock me
449 : //WW8+ Sprms
450 : static const SprmInfo aSprms[] =
451 : {
452 : { 0, 0, L_FIX}, // "Default-sprm"/ wird uebersprungen
453 : {0x4600, 2, L_FIX}, // "sprmPIstd" pap.istd;istd (style code);short;
454 : {0xC601, 0, L_VAR}, // "sprmPIstdPermute" pap.istd;permutation vector
455 : {0x2602, 1, L_FIX}, // "sprmPIncLvl" pap.istd, pap.lvl;difference
456 : // between istd of base PAP and istd of PAP to be
457 : // produced
458 : {0x2403, 1, L_FIX}, // "sprmPJc" pap.jc;jc (justification);byte;
459 : {0x2404, 1, L_FIX}, // "sprmPFSideBySide" pap.fSideBySide;0 or 1;byte;
460 : {0x2405, 1, L_FIX}, // "sprmPFKeep" pap.fKeep;0 or 1;byte;
461 : {0x2406, 1, L_FIX}, // "sprmPFKeepFollow" pap.fKeepFollow;0 or 1;byte;
462 : {0x2407, 1, L_FIX}, // "sprmPFPageBreakBefore" pap.fPageBreakBefore;
463 : // 0 or 1
464 : {0x2408, 1, L_FIX}, // "sprmPBrcl" pap.brcl;brcl;byte;
465 : {0x2409, 1, L_FIX}, // "sprmPBrcp" pap.brcp;brcp;byte;
466 : {0x260A, 1, L_FIX}, // "sprmPIlvl" pap.ilvl;ilvl;byte;
467 : {0x460B, 2, L_FIX}, // "sprmPIlfo" pap.ilfo;ilfo (list index) ;short;
468 : {0x240C, 1, L_FIX}, // "sprmPFNoLineNumb" pap.fNoLnn;0 or 1;byte;
469 : {0xC60D, 0, L_VAR}, // "sprmPChgTabsPapx" pap.itbdMac, pap.rgdxaTab,
470 : // pap.rgtbd;complex
471 : {0x840E, 2, L_FIX}, // "sprmPDxaRight" pap.dxaRight;dxa;word;
472 : {0x840F, 2, L_FIX}, // "sprmPDxaLeft" pap.dxaLeft;dxa;word;
473 : {0x4610, 2, L_FIX}, // "sprmPNest" pap.dxaLeft;dxa
474 : {0x8411, 2, L_FIX}, // "sprmPDxaLeft1" pap.dxaLeft1;dxa;word;
475 : {0x6412, 4, L_FIX}, // "sprmPDyaLine" pap.lspd;an LSPD, a long word
476 : // structure consisting of a short of dyaLine
477 : // followed by a short of fMultLinespace
478 : {0xA413, 2, L_FIX}, // "sprmPDyaBefore" pap.dyaBefore;dya;word;
479 : {0xA414, 2, L_FIX}, // "sprmPDyaAfter" pap.dyaAfter;dya;word;
480 : {0xC615, 0, L_VAR}, // "sprmPChgTabs" pap.itbdMac, pap.rgdxaTab,
481 : // pap.rgtbd;complex
482 : {0x2416, 1, L_FIX}, // "sprmPFInTable" pap.fInTable;0 or 1;byte;
483 : {0x2417, 1, L_FIX}, // "sprmPFTtp" pap.fTtp;0 or 1;byte;
484 : {0x8418, 2, L_FIX}, // "sprmPDxaAbs" pap.dxaAbs;dxa;word;
485 : {0x8419, 2, L_FIX}, // "sprmPDyaAbs" pap.dyaAbs;dya;word;
486 : {0x841A, 2, L_FIX}, // "sprmPDxaWidth" pap.dxaWidth;dxa;word;
487 : {0x261B, 1, L_FIX}, // "sprmPPc" pap.pcHorz, pap.pcVert;complex
488 : {0x461C, 2, L_FIX}, // "sprmPBrcTop10" pap.brcTop;BRC10;word;
489 : {0x461D, 2, L_FIX}, // "sprmPBrcLeft10" pap.brcLeft;BRC10;word;
490 : {0x461E, 2, L_FIX}, // "sprmPBrcBottom10" pap.brcBottom;BRC10;word;
491 : {0x461F, 2, L_FIX}, // "sprmPBrcRight10" pap.brcRight;BRC10;word;
492 : {0x4620, 2, L_FIX}, // "sprmPBrcBetween10" pap.brcBetween;BRC10;word;
493 : {0x4621, 2, L_FIX}, // "sprmPBrcBar10" pap.brcBar;BRC10;word;
494 : {0x4622, 2, L_FIX}, // "sprmPDxaFromText10" pap.dxaFromText;dxa;word;
495 : {0x2423, 1, L_FIX}, // "sprmPWr" pap.wr;wr
496 : {0x6424, 4, L_FIX}, // "sprmPBrcTop80" pap.brcTop;BRC;long;
497 : {0x6425, 4, L_FIX}, // "sprmPBrcLeft80" pap.brcLeft;BRC;long;
498 : {0x6426, 4, L_FIX}, // "sprmPBrcBottom80" pap.brcBottom;BRC;long;
499 : {0x6427, 4, L_FIX}, // "sprmPBrcRight80" pap.brcRight;BRC;long;
500 : {0x6428, 4, L_FIX}, // "sprmPBrcBetween80" pap.brcBetween;BRC;long;
501 : {0x6629, 4, L_FIX}, // "sprmPBrcBar80" pap.brcBar;BRC;long;
502 : {0x242A, 1, L_FIX}, // "sprmPFNoAutoHyph" pap.fNoAutoHyph;0 or 1;byte;
503 : {0x442B, 2, L_FIX}, // "sprmPWHeightAbs" pap.wHeightAbs;w;word;
504 : {0x442C, 2, L_FIX}, // "sprmPDcs" pap.dcs;DCS;short;
505 : {0x442D, 2, L_FIX}, // "sprmPShd" pap.shd;SHD;word;
506 : {0x842E, 2, L_FIX}, // "sprmPDyaFromText" pap.dyaFromText;dya;word;
507 : {0x842F, 2, L_FIX}, // "sprmPDxaFromText" pap.dxaFromText;dxa;word;
508 : {0x2430, 1, L_FIX}, // "sprmPFLocked" pap.fLocked;0 or 1;byte;
509 : {0x2431, 1, L_FIX}, // "sprmPFWidowControl" pap.fWidowControl;0 or 1
510 : {0xC632, 0, L_VAR}, // "sprmPRuler" ;;variable length;
511 : {0x2433, 1, L_FIX}, // "sprmPFKinsoku" pap.fKinsoku;0 or 1;byte;
512 : {0x2434, 1, L_FIX}, // "sprmPFWordWrap" pap.fWordWrap;0 or 1;byte;
513 : {0x2435, 1, L_FIX}, // "sprmPFOverflowPunct" pap.fOverflowPunct;0 or 1
514 : {0x2436, 1, L_FIX}, // "sprmPFTopLinePunct" pap.fTopLinePunct;0 or 1
515 : {0x2437, 1, L_FIX}, // "sprmPFAutoSpaceDE" pap.fAutoSpaceDE;0 or 1
516 : {0x2438, 1, L_FIX}, // "sprmPFAutoSpaceDN" pap.fAutoSpaceDN;0 or 1
517 : {NS_sprm::LN_PWAlignFont, 2, L_FIX}, // "sprmPWAlignFont" pap.wAlignFont;iFa
518 : {0x443A, 2, L_FIX}, // "sprmPFrameTextFlow" pap.fVertical pap.fBackward
519 : // pap.fRotateFont;complex
520 : {0x243B, 1, L_FIX}, // "sprmPISnapBaseLine" obsolete: not applicable in
521 : // Word97 and later versions;
522 : {0xC63E, 0, L_VAR}, // "sprmPAnld" pap.anld;;variable length;
523 : {0xC63F, 0, L_VAR}, // "sprmPPropRMark" pap.fPropRMark;complex
524 : {0x2640, 1, L_FIX}, // "sprmPOutLvl" pap.lvl;has no effect if pap.istd
525 : // is < 1 or is > 9
526 : {0x2441, 1, L_FIX}, // "sprmPFBiDi" ;;byte;
527 : {0x2443, 1, L_FIX}, // "sprmPFNumRMIns" pap.fNumRMIns;1 or 0;bit;
528 : {0x2444, 1, L_FIX}, // "sprmPCrLf" ;;byte;
529 : {0xC645, 0, L_VAR}, // "sprmPNumRM" pap.numrm;;variable length;
530 : {0x6645, 4, L_FIX}, // "sprmPHugePapx" fc in the data stream to locate
531 : // the huge grpprl
532 : {0x6646, 4, L_FIX}, // "sprmPHugePapx" fc in the data stream to locate
533 : // the huge grpprl
534 : {0x2447, 1, L_FIX}, // "sprmPFUsePgsuSettings" pap.fUsePgsuSettings;
535 : // 1 or 0
536 : {0x2448, 1, L_FIX}, // "sprmPFAdjustRight" pap.fAdjustRight;1 or 0;byte;
537 : {0x0800, 1, L_FIX}, // "sprmCFRMarkDel" chp.fRMarkDel;1 or 0;bit;
538 : {0x0801, 1, L_FIX}, // "sprmCFRMark" chp.fRMark;1 or 0;bit;
539 : {0x0802, 1, L_FIX}, // "sprmCFFldVanish" chp.fFldVanish;1 or 0;bit;
540 : {0x6A03, 4, L_FIX}, // "sprmCPicLocation" chp.fcPic and chp.fSpec;
541 : {0x4804, 2, L_FIX}, // "sprmCIbstRMark" chp.ibstRMark;index into
542 : // sttbRMark
543 : {0x6805, 4, L_FIX}, // "sprmCDttmRMark" chp.dttmRMark;DTTM;long;
544 : {0x0806, 1, L_FIX}, // "sprmCFData" chp.fData;1 or 0;bit;
545 : {0x4807, 2, L_FIX}, // "sprmCIdslRMark" chp.idslRMReason;an index to a
546 : // table of strings defined in Word 6.0
547 : // executables;short;
548 : {0xEA08, 1, L_FIX}, // "sprmCChs" chp.fChsDiff and chp.chse;
549 : {0x6A09, 4, L_FIX}, // "sprmCSymbol" chp.fSpec, chp.xchSym and
550 : // chp.ftcSym
551 : {0x080A, 1, L_FIX}, // "sprmCFOle2" chp.fOle2;1 or 0;bit;
552 : {0x480B, 0, L_FIX}, // "sprmCIdCharType" obsolete: not applicable in
553 : // Word97 and later versions;;;
554 : {0x2A0C, 1, L_FIX}, // "sprmCHighlight" chp.fHighlight,
555 : // chp.icoHighlight;ico (fHighlight is set to 1 iff
556 : // ico is not 0)
557 : {0x680E, 4, L_FIX}, // "sprmCObjLocation" chp.fcObj;FC;long;
558 : {0x2A10, 0, L_FIX}, // "sprmCFFtcAsciSymb" ;;;
559 : {0x4A30, 2, L_FIX}, // "sprmCIstd" chp.istd;istd, see stylesheet def
560 : {0xCA31, 0, L_VAR}, // "sprmCIstdPermute" chp.istd;permutation vector
561 : {0x2A32, 0, L_VAR}, // "sprmCDefault" whole CHP;none;variable length;
562 : {0x2A33, 0, L_FIX}, // "sprmCPlain" whole CHP;none;0;
563 : {0x2A34, 1, L_FIX}, // "sprmCKcd" ;;;
564 : {0x0835, 1, L_FIX}, // "sprmCFBold" chp.fBold;0,1, 128, or 129
565 : {0x0836, 1, L_FIX}, // "sprmCFItalic" chp.fItalic;0,1, 128, or 129
566 : {0x0837, 1, L_FIX}, // "sprmCFStrike" chp.fStrike;0,1, 128, or 129
567 : {0x0838, 1, L_FIX}, // "sprmCFOutline" chp.fOutline;0,1, 128, or 129
568 : {0x0839, 1, L_FIX}, // "sprmCFShadow" chp.fShadow;0,1, 128, or 129
569 : {0x083A, 1, L_FIX}, // "sprmCFSmallCaps" chp.fSmallCaps;0,1, 128, or 129
570 : {0x083B, 1, L_FIX}, // "sprmCFCaps" chp.fCaps;0,1, 128, or 129
571 : {0x083C, 1, L_FIX}, // "sprmCFVanish" chp.fVanish;0,1, 128, or 129
572 : {0x4A3D, 2, L_FIX}, // "sprmCFtcDefault" ;ftc, only used internally
573 : {0x2A3E, 1, L_FIX}, // "sprmCKul" chp.kul;kul;byte;
574 : {0xEA3F, 3, L_FIX}, // "sprmCSizePos" chp.hps, chp.hpsPos;3 bytes;
575 : {0x8840, 2, L_FIX}, // "sprmCDxaSpace" chp.dxaSpace;dxa;word;
576 : {0x4A41, 2, L_FIX}, // "sprmCLid" ;only used internally never stored
577 : {0x2A42, 1, L_FIX}, // "sprmCIco" chp.ico;ico;byte;
578 : {0x4A43, 2, L_FIX}, // "sprmCHps" chp.hps;hps
579 : {0x2A44, 1, L_FIX}, // "sprmCHpsInc" chp.hps;
580 : {0x4845, 2, L_FIX}, // "sprmCHpsPos" chp.hpsPos;hps;short; (doc wrong)
581 : {0x2A46, 1, L_FIX}, // "sprmCHpsPosAdj" chp.hpsPos;hps
582 : {0xCA47, 0, L_VAR}, // "sprmCMajority" chp.fBold, chp.fItalic,
583 : // chp.fSmallCaps, chp.fVanish, chp.fStrike,
584 : // chp.fCaps, chp.rgftc, chp.hps, chp.hpsPos,
585 : // chp.kul, chp.dxaSpace, chp.ico,
586 : // chp.rglid;complex;variable length, length byte
587 : // plus size of following grpprl;
588 : {0x2A48, 1, L_FIX}, // "sprmCIss" chp.iss;iss;byte;
589 : {0xCA49, 0, L_VAR}, // "sprmCHpsNew50" chp.hps;hps;variable width
590 : {0xCA4A, 0, L_VAR}, // "sprmCHpsInc1" chp.hps;complex
591 : {0x484B, 2, L_FIX}, // "sprmCHpsKern" chp.hpsKern;hps;short;
592 : {0xCA4C, 2, L_FIX}, // "sprmCMajority50" chp.fBold, chp.fItalic,
593 : // chp.fSmallCaps, chp.fVanish, chp.fStrike,
594 : // chp.fCaps, chp.ftc, chp.hps, chp.hpsPos, chp.kul,
595 : // chp.dxaSpace, chp.ico,;complex
596 : {0x4A4D, 2, L_FIX}, // "sprmCHpsMul" chp.hps;percentage to grow hps
597 : {0x484E, 2, L_FIX}, // "sprmCYsri" chp.ysri;ysri;short;
598 : {0x4A4F, 2, L_FIX}, // "sprmCRgFtc0" chp.rgftc[0];ftc for ASCII text
599 : {0x4A50, 2, L_FIX}, // "sprmCRgFtc1" chp.rgftc[1];ftc for Far East text
600 : {0x4A51, 2, L_FIX}, // "sprmCRgFtc2" chp.rgftc[2];ftc for non-FE text
601 : {0x4852, 2, L_FIX}, // "sprmCCharScale"
602 : {0x2A53, 1, L_FIX}, // "sprmCFDStrike" chp.fDStrike;;byte;
603 : {0x0854, 1, L_FIX}, // "sprmCFImprint" chp.fImprint;1 or 0;bit;
604 : {0x0855, 1, L_FIX}, // "sprmCFSpec" chp.fSpec ;1 or 0;bit;
605 : {0x0856, 1, L_FIX}, // "sprmCFObj" chp.fObj;1 or 0;bit;
606 : {0xCA57, 0, L_VAR}, // "sprmCPropRMark" chp.fPropRMark,
607 : // chp.ibstPropRMark, chp.dttmPropRMark;Complex
608 : {0x0858, 1, L_FIX}, // "sprmCFEmboss" chp.fEmboss;1 or 0;bit;
609 : {0x2859, 1, L_FIX}, // "sprmCSfxText" chp.sfxtText;text animation;byte;
610 : {0x085A, 1, L_FIX}, // "sprmCFBiDi" ;;;
611 : {0x085B, 1, L_FIX}, // "sprmCFDiacColor" ;;;
612 : {0x085C, 1, L_FIX}, // "sprmCFBoldBi" ;;;
613 : {0x085D, 1, L_FIX}, // "sprmCFItalicBi" ;;;
614 : {0x4A5E, 2, L_FIX},
615 : {0x485F, 2, L_FIX}, // "sprmCLidBi" ;;;
616 : {0x4A60, 1, L_FIX}, // "sprmCIcoBi" ;;;
617 : {0x4A61, 2, L_FIX}, // "sprmCHpsBi" ;;;
618 : {0xCA62, 0, L_VAR}, // "sprmCDispFldRMark" chp.fDispFldRMark,
619 : // chp.ibstDispFldRMark, chp.dttmDispFldRMark ;
620 : {0x4863, 2, L_FIX}, // "sprmCIbstRMarkDel" chp.ibstRMarkDel;index into
621 : // sttbRMark;short;
622 : {NS_sprm::LN_CDttmRMarkDel, 4, L_FIX}, // chp.dttmRMarkDel;DTTM;long;
623 : {0x6865, 4, L_FIX}, // "sprmCBrc80" chp.brc;BRC;long;
624 : {0x4866, 2, L_FIX}, // "sprmCShd80" chp.shd;SHD;short;
625 : {0x4867, 2, L_FIX}, // "sprmCIdslRMarkDel" chp.idslRMReasonDel;an index
626 : // to a table of strings defined in Word 6.0
627 : // executables;short;
628 : {0x0868, 1, L_FIX}, // "sprmCFUsePgsuSettings"
629 : // chp.fUsePgsuSettings;1 or 0
630 : {0x486B, 2, L_FIX}, // "sprmCCpg" ;;word;
631 : {0x486D, 2, L_FIX}, // "sprmCRgLid0_80" chp.rglid[0];LID: for non-FE text
632 : {0x486E, 2, L_FIX}, // "sprmCRgLid1_80" chp.rglid[1];LID: for Far East text
633 : {0x286F, 1, L_FIX}, // "sprmCIdctHint" chp.idctHint;IDCT:
634 : {0x2E00, 1, L_FIX}, // "sprmPicBrcl" pic.brcl;brcl (see PIC definition)
635 : {0xCE01, 0, L_VAR}, // "sprmPicScale" pic.mx, pic.my, pic.dxaCropleft,
636 : // pic.dyaCropTop pic.dxaCropRight,
637 : // pic.dyaCropBottom;Complex
638 : {0x6C02, 4, L_FIX}, // "sprmPicBrcTop80" pic.brcTop;BRC;long;
639 : {0x6C03, 4, L_FIX}, // "sprmPicBrcLeft80" pic.brcLeft;BRC;long;
640 : {0x6C04, 4, L_FIX}, // "sprmPicBrcBottom80" pic.brcBottom;BRC;long;
641 : {0x6C05, 4, L_FIX}, // "sprmPicBrcRight80" pic.brcRight;BRC;long;
642 : {0x3000, 1, L_FIX}, // "sprmScnsPgn" sep.cnsPgn;cns;byte;
643 : {0x3001, 1, L_FIX}, // "sprmSiHeadingPgn" sep.iHeadingPgn;heading number
644 : // level;byte;
645 : {0xD202, 0, L_VAR}, // "sprmSOlstAnm" sep.olstAnm;OLST;variable length;
646 : {0xF203, 3, L_FIX}, // "sprmSDxaColWidth" sep.rgdxaColWidthSpacing;
647 : {0xF204, 3, L_FIX}, // "sprmSDxaColSpacing" sep.rgdxaColWidthSpacing;
648 : // complex
649 : {0x3005, 1, L_FIX}, // "sprmSFEvenlySpaced" sep.fEvenlySpaced;1 or 0
650 : {0x3006, 1, L_FIX}, // "sprmSFProtected" sep.fUnlocked;1 or 0;byte;
651 : {0x5007, 2, L_FIX}, // "sprmSDmBinFirst" sep.dmBinFirst;;word;
652 : {0x5008, 2, L_FIX}, // "sprmSDmBinOther" sep.dmBinOther;;word;
653 : {0x3009, 1, L_FIX}, // "sprmSBkc" sep.bkc;bkc;byte;
654 : {0x300A, 1, L_FIX}, // "sprmSFTitlePage" sep.fTitlePage;0 or 1;byte;
655 : {0x500B, 2, L_FIX}, // "sprmSCcolumns" sep.ccolM1;# of cols - 1;word;
656 : {0x900C, 2, L_FIX}, // "sprmSDxaColumns" sep.dxaColumns;dxa;word;
657 : {0x300D, 1, L_FIX}, // "sprmSFAutoPgn" sep.fAutoPgn;obsolete;byte;
658 : {0x300E, 1, L_FIX}, // "sprmSNfcPgn" sep.nfcPgn;nfc;byte;
659 : {0xB00F, 2, L_FIX}, // "sprmSDyaPgn" sep.dyaPgn;dya;short;
660 : {0xB010, 2, L_FIX}, // "sprmSDxaPgn" sep.dxaPgn;dya;short;
661 : {0x3011, 1, L_FIX}, // "sprmSFPgnRestart" sep.fPgnRestart;0 or 1;byte;
662 : {0x3012, 1, L_FIX}, // "sprmSFEndnote" sep.fEndnote;0 or 1;byte;
663 : {0x3013, 1, L_FIX}, // "sprmSLnc" sep.lnc;lnc;byte;
664 : {0x3014, 1, L_FIX}, // "sprmSGprfIhdt" sep.grpfIhdt;grpfihdt
665 : {0x5015, 2, L_FIX}, // "sprmSNLnnMod" sep.nLnnMod;non-neg int.;word;
666 : {0x9016, 2, L_FIX}, // "sprmSDxaLnn" sep.dxaLnn;dxa;word;
667 : {0xB017, 2, L_FIX}, // "sprmSDyaHdrTop" sep.dyaHdrTop;dya;word;
668 : {0xB018, 2, L_FIX}, // "sprmSDyaHdrBottom" sep.dyaHdrBottom;dya;word;
669 : {0x3019, 1, L_FIX}, // "sprmSLBetween" sep.fLBetween;0 or 1;byte;
670 : {0x301A, 1, L_FIX}, // "sprmSVjc" sep.vjc;vjc;byte;
671 : {0x501B, 2, L_FIX}, // "sprmSLnnMin" sep.lnnMin;lnn;word;
672 : {0x501C, 2, L_FIX}, // "sprmSPgnStart" sep.pgnStart;pgn;word;
673 : {0x301D, 1, L_FIX}, // "sprmSBOrientation" sep.dmOrientPage;dm;byte;
674 : {0x301E, 1, L_FIX}, // "sprmSBCustomize" ;;;
675 : {0xB01F, 2, L_FIX}, // "sprmSXaPage" sep.xaPage;xa;word;
676 : {0xB020, 2, L_FIX}, // "sprmSYaPage" sep.yaPage;ya;word;
677 : {0xB021, 2, L_FIX}, // "sprmSDxaLeft" sep.dxaLeft;dxa;word;
678 : {0xB022, 2, L_FIX}, // "sprmSDxaRight" sep.dxaRight;dxa;word;
679 : {0x9023, 2, L_FIX}, // "sprmSDyaTop" sep.dyaTop;dya;word;
680 : {0x9024, 2, L_FIX}, // "sprmSDyaBottom" sep.dyaBottom;dya;word;
681 : {0xB025, 2, L_FIX}, // "sprmSDzaGutter" sep.dzaGutter;dza;word;
682 : {0x5026, 2, L_FIX}, // "sprmSDmPaperReq" sep.dmPaperReq;dm;word;
683 : {0xD227, 0, L_VAR}, // "sprmSPropRMark" sep.fPropRMark,
684 : // sep.ibstPropRMark, sep.dttmPropRMark ;complex
685 : {0x3228, 1, L_FIX}, // "sprmSFBiDi" ;;;
686 : {0x3229, 1, L_FIX}, // "sprmSFFacingCol" ;;;
687 : {0x322A, 1, L_FIX}, // "sprmSFRTLGutter", set to one if gutter is on
688 : // right
689 : {0x702B, 4, L_FIX}, // "sprmSBrcTop80" sep.brcTop;BRC;long;
690 : {0x702C, 4, L_FIX}, // "sprmSBrcLeft80" sep.brcLeft;BRC;long;
691 : {0x702D, 4, L_FIX}, // "sprmSBrcBottom80" sep.brcBottom;BRC;long;
692 : {0x702E, 4, L_FIX}, // "sprmSBrcRight80" sep.brcRight;BRC;long;
693 : {0x522F, 2, L_FIX}, // "sprmSPgbProp" sep.pgbProp;;word;
694 : {0x7030, 4, L_FIX}, // "sprmSDxtCharSpace" sep.dxtCharSpace;dxt;long;
695 : {0x9031, 2, L_FIX}, // "sprmSDyaLinePitch"
696 : // sep.dyaLinePitch;dya; WRONG:long; RIGHT:short; !
697 : {0x5032, 2, L_FIX}, // "sprmSClm" ;;;
698 : {0x5033, 2, L_FIX}, // "sprmSTextFlow" sep.wTextFlow;complex
699 : {0x5400, 2, L_FIX}, // "sprmTJc90" tap.jc;jc;word (low order byte is
700 : // significant);
701 : {0x9601, 2, L_FIX}, // "sprmTDxaLeft" tap.rgdxaCenter
702 : {0x9602, 2, L_FIX}, // "sprmTDxaGapHalf" tap.dxaGapHalf,
703 : // tap.rgdxaCenter
704 : {0x3403, 1, L_FIX}, // "sprmTFCantSplit" tap.fCantSplit;1 or 0;byte;
705 : {0x3404, 1, L_FIX}, // "sprmTTableHeader" tap.fTableHeader;1 or 0;byte;
706 : {0x3466, 1, L_FIX}, // "sprmTFCantSplit90" tap.fCantSplit90;1 or 0;byte;
707 : {0xD605, 0, L_VAR}, // "sprmTTableBorders80" tap.rgbrcTable;complex
708 : {0xD606, 0, L_VAR}, // "sprmTDefTable10" tap.rgdxaCenter,
709 : // tap.rgtc;complex
710 : {0x9407, 2, L_FIX}, // "sprmTDyaRowHeight" tap.dyaRowHeight;dya;word;
711 : {0xD608, 0, L_VAR}, // "sprmTDefTable" tap.rgtc;complex
712 : {0xD609, 0, L_VAR}, // "sprmTDefTableShd80" tap.rgshd;complex
713 : {0x740A, 4, L_FIX}, // "sprmTTlp" tap.tlp;TLP;4 bytes;
714 : {0x560B, 2, L_FIX}, // "sprmTFBiDi" ;;;
715 : {0x740C, 1, L_FIX}, // "sprmTHTMLProps" ;;;
716 : {0xD620, 0, L_VAR}, // "sprmTSetBrc80" tap.rgtc[].rgbrc;complex
717 : {0x7621, 4, L_FIX}, // "sprmTInsert" tap.rgdxaCenter, tap.rgtc;complex
718 : {0x5622, 2, L_FIX}, // "sprmTDelete" tap.rgdxaCenter, tap.rgtc;complex
719 : {0x7623, 4, L_FIX}, // "sprmTDxaCol" tap.rgdxaCenter;complex
720 : {0x5624, 0, L_VAR}, // "sprmTMerge" tap.fFirstMerged, tap.fMerged;
721 : {0x5625, 0, L_VAR}, // "sprmTSplit" tap.fFirstMerged, tap.fMerged;
722 : {0xD626, 0, L_VAR}, // "sprmTSetBrc10" tap.rgtc[].rgbrc;complex
723 : {0x7627, 0, L_VAR}, // "sprmTSetShd80" tap.rgshd;complex
724 : {0x7628, 0, L_VAR}, // "sprmTSetShdOdd80" tap.rgshd;complex
725 : {0x7629, 4, L_FIX}, // "sprmTTextFlow" tap.rgtc[].fVerticaltap,
726 : // rgtc[].fBackwardtap, rgtc[].fRotateFont;0 or 10
727 : // or 10 or 1;word;
728 : {0xD62A, 1, L_FIX}, // "sprmTDiagLine" ;;;
729 : {0xD62B, 0, L_VAR}, // "sprmTVertMerge" tap.rgtc[].vertMerge
730 : {0xD62C, 0, L_VAR}, // "sprmTVertAlign" tap.rgtc[].vertAlign
731 : {NS_sprm::LN_CFELayout, 0, L_VAR},
732 : {0x6649, 4, L_FIX}, // undocumented
733 : {0xF614, 3, L_FIX}, // undocumented
734 : {0xD612, 0, L_VAR}, // "sprmTDefTableShd"
735 : {0xD613, 0, L_VAR}, // "sprmTTableBorders"
736 : {0xD61A, 0, L_VAR}, // undocumented
737 : {0xD61B, 0, L_VAR}, // undocumented
738 : {0xD61C, 0, L_VAR}, // undocumented
739 : {0xD61D, 0, L_VAR}, // undocumented
740 : {0xD632, 0, L_VAR}, // undocumented
741 : {0xD634, 0, L_VAR}, // undocumented
742 : {0xD238, 0, L_VAR}, // undocumented sep
743 : {0xC64E, 0, L_VAR}, // "sprmPBrcTop"
744 : {0xC64F, 0, L_VAR}, // "sprmPBrcLeft"
745 : {0xC650, 0, L_VAR}, // "sprmPBrcBottom"
746 : {0xC651, 0, L_VAR}, // "sprmPBrcRight"
747 : {0xC652, 0, L_VAR}, // "sprmPBrcBetween"
748 : {0xF661, 3, L_FIX}, // undocumented
749 : {0x4873, 2, L_FIX}, // "sprmCRgLid0" chp.rglid[0];LID: for non-FE text
750 : {0x4874, 2, L_FIX}, // "sprmCRgLid1" chp.rglid[1];LID: for Far East text
751 : {0x6463, 4, L_FIX}, // undocumented
752 : {0x2461, 1, L_FIX}, // undoc, must be asian version of "sprmPJc"
753 : {0x845D, 2, L_FIX}, // undoc, must be asian version of "sprmPDxaRight"
754 : {0x845E, 2, L_FIX}, // undoc, must be asian version of "sprmPDxaLeft"
755 : {0x8460, 2, L_FIX}, // undoc, must be asian version of "sprmPDxaLeft1"
756 : {0x3615, 1, L_FIX}, // undocumented
757 : {0x360D, 1, L_FIX}, // undocumented
758 : {0x703A, 4, L_FIX}, // undocumented, sep, perhaps related to textgrids ?
759 : {0x303B, 1, L_FIX}, // undocumented, sep
760 : {0x244B, 1, L_FIX}, // undocumented, subtable "sprmPFInTable" equiv ?
761 : {0x244C, 1, L_FIX}, // undocumented, subtable "sprmPFTtp" equiv ?
762 : {0x940E, 2, L_FIX}, // undocumented
763 : {0x940F, 2, L_FIX}, // undocumented
764 : {0x9410, 2, L_FIX}, // undocumented
765 : {0x6815, 4, L_FIX}, // undocumented
766 : {0x6816, 4, L_FIX}, // undocumented
767 : {NS_sprm::LN_CCv, 4, L_FIX}, // text colour
768 : {0xC64D, 0, L_VAR}, // undocumented, para back colour
769 : {0x6467, 4, L_FIX}, // undocumented
770 : {0x646B, 4, L_FIX}, // undocumented
771 : {0xF617, 3, L_FIX}, // undocumented
772 : {0xD660, 0, L_VAR}, // undocumented, something to do with colour.
773 : {0xD670, 0, L_VAR}, // undocumented, something to do with colour.
774 : {0xCA71, 0, L_VAR}, // "sprmCShd", text backcolour
775 : {0x303C, 1, L_FIX}, // undocumented, sep
776 : {0x245B, 1, L_FIX}, // undocumented, para autobefore
777 : {0x245C, 1, L_FIX}, // undocumented, para autoafter
778 : // "sprmPFContextualSpacing", don't add space between para of the same style
779 : {0x246D, 1, L_FIX}
780 : };
781 :
782 1655 : static wwSprmSearcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
783 1655 : return &aSprmSrch;
784 : };
785 :
786 1668 : wwSprmParser::wwSprmParser(ww::WordVersion eVersion) : meVersion(eVersion)
787 : {
788 : OSL_ENSURE((meVersion >= ww::eWW2 && meVersion <= ww::eWW8),
789 : "Impossible value for version");
790 :
791 1668 : mnDelta = (ww::IsSevenMinus(meVersion)) ? 0 : 1;
792 :
793 1668 : if (meVersion <= ww::eWW2)
794 13 : mpKnownSprms = GetWW2SprmSearcher();
795 1655 : else if (meVersion < ww::eWW8)
796 0 : mpKnownSprms = GetWW6SprmSearcher();
797 : else
798 1655 : mpKnownSprms = GetWW8SprmSearcher();
799 1668 : }
800 :
801 1356509 : SprmInfo wwSprmParser::GetSprmInfo(sal_uInt16 nId) const
802 : {
803 : // Find sprm
804 1356509 : SprmInfo aSrch={0,0,0};
805 1356509 : aSrch.nId = nId;
806 1356509 : const SprmInfo* pFound = mpKnownSprms->search(aSrch);
807 1356509 : if (pFound == 0)
808 : {
809 : OSL_ENSURE(ww::IsEightPlus(meVersion),
810 : "Unknown ww7- sprm, dangerous, report to development");
811 :
812 90991 : aSrch.nId = 0;
813 90991 : aSrch.nLen = 0;
814 : //All the unknown ww7 sprms appear to be variable (which makes sense)
815 90991 : aSrch.nVari = L_VAR;
816 :
817 90991 : if (ww::IsEightPlus(meVersion)) //We can recover perfectly in this case
818 : {
819 90991 : aSrch.nVari = L_FIX;
820 90991 : switch (nId >> 13)
821 : {
822 : case 0:
823 : case 1:
824 10165 : aSrch.nLen = 1;
825 10165 : break;
826 : case 2:
827 11158 : aSrch.nLen = 2;
828 11158 : break;
829 : case 3:
830 13155 : aSrch.nLen = 4;
831 13155 : break;
832 : case 4:
833 : case 5:
834 2431 : aSrch.nLen = 2;
835 2431 : break;
836 : case 6:
837 45085 : aSrch.nLen = 0;
838 45085 : aSrch.nVari = L_VAR;
839 45085 : break;
840 : case 7:
841 : default:
842 8997 : aSrch.nLen = 3;
843 8997 : break;
844 : }
845 : }
846 :
847 90991 : pFound = &aSrch;
848 : }
849 1356509 : return *pFound;
850 : }
851 :
852 : //-end
853 :
854 438 : inline sal_uInt8 Get_Byte( sal_uInt8 *& p )
855 : {
856 438 : sal_uInt8 n = *p;
857 438 : p += 1;
858 438 : return n;
859 : }
860 :
861 12727 : inline sal_uInt16 Get_UShort( sal_uInt8 *& p )
862 : {
863 12727 : sal_uInt16 n = SVBT16ToShort( *(SVBT16*)p );
864 12727 : p += 2;
865 12727 : return n;
866 : }
867 :
868 11794 : inline short Get_Short( sal_uInt8 *& p )
869 : {
870 11794 : return Get_UShort(p);
871 : }
872 :
873 14444 : inline sal_uLong Get_ULong( sal_uInt8 *& p )
874 : {
875 14444 : sal_uLong n = SVBT32ToUInt32( *(SVBT32*)p );
876 14444 : p += 4;
877 14444 : return n;
878 : }
879 :
880 14372 : inline long Get_Long( sal_uInt8 *& p )
881 : {
882 14372 : return Get_ULong(p);
883 : }
884 :
885 60010 : WW8SprmIter::WW8SprmIter(const sal_uInt8* pSprms_, long nLen_,
886 : const wwSprmParser &rParser)
887 60010 : : mrSprmParser(rParser), pSprms( pSprms_), nRemLen( nLen_)
888 : {
889 60010 : UpdateMyMembers();
890 60010 : }
891 :
892 273 : void WW8SprmIter::SetSprms(const sal_uInt8* pSprms_, long nLen_)
893 : {
894 273 : pSprms = pSprms_;
895 273 : nRemLen = nLen_;
896 273 : UpdateMyMembers();
897 273 : }
898 :
899 324609 : void WW8SprmIter::advance()
900 : {
901 324609 : if (nRemLen > 0 )
902 : {
903 324609 : sal_uInt16 nSize = nAktSize;
904 324609 : if (nSize > nRemLen)
905 0 : nSize = nRemLen;
906 324609 : pSprms += nSize;
907 324609 : nRemLen -= nSize;
908 324609 : UpdateMyMembers();
909 : }
910 324609 : }
911 :
912 384892 : void WW8SprmIter::UpdateMyMembers()
913 : {
914 384892 : bool bValid = (pSprms && nRemLen >= mrSprmParser.MinSprmLen());
915 :
916 384892 : if (bValid)
917 : {
918 339619 : nAktId = mrSprmParser.GetSprmId(pSprms);
919 339619 : nAktSize = mrSprmParser.GetSprmSize(nAktId, pSprms);
920 339619 : pAktParams = pSprms + mrSprmParser.DistanceToData(nAktId);
921 339619 : bValid = nAktSize <= nRemLen;
922 : SAL_WARN_IF(!bValid, "sw.ww8", "sprm longer than remaining bytes, doc or parser is wrong");
923 : }
924 :
925 384892 : if (!bValid)
926 : {
927 45313 : nAktId = 0;
928 45313 : pAktParams = 0;
929 45313 : nAktSize = 0;
930 45313 : nRemLen = 0;
931 : }
932 384892 : }
933 :
934 57014 : const sal_uInt8* WW8SprmIter::FindSprm(sal_uInt16 nId)
935 : {
936 422289 : while (GetSprms())
937 : {
938 323231 : if (GetAktId() == nId)
939 14970 : return GetAktParams(); // SPRM found!
940 308261 : advance();
941 : }
942 :
943 42044 : return 0; // SPRM _not_ found
944 : }
945 :
946 : // temporary test
947 : // WW8PLCFx_PCDAttrs cling to WW8PLCF_Pcd and therefore do not have their own iterators.
948 : // All methods relating to iterators are therefore dummies.
949 213 : WW8PLCFx_PCDAttrs::WW8PLCFx_PCDAttrs(ww::WordVersion eVersion,
950 : WW8PLCFx_PCD* pPLCFx_PCD, const WW8ScannerBase* pBase)
951 213 : : WW8PLCFx(eVersion, true), pPcdI(pPLCFx_PCD->GetPLCFIter()),
952 : pPcd(pPLCFx_PCD), pGrpprls(pBase->pPieceGrpprls),
953 426 : nGrpprls(pBase->nPieceGrpprls)
954 : {
955 213 : }
956 :
957 112 : sal_uLong WW8PLCFx_PCDAttrs::GetIdx() const
958 : {
959 112 : return 0;
960 : }
961 :
962 112 : void WW8PLCFx_PCDAttrs::SetIdx( sal_uLong )
963 : {
964 112 : }
965 :
966 224 : bool WW8PLCFx_PCDAttrs::SeekPos(WW8_CP )
967 : {
968 224 : return true;
969 : }
970 :
971 5296 : void WW8PLCFx_PCDAttrs::advance()
972 : {
973 5296 : }
974 :
975 0 : WW8_CP WW8PLCFx_PCDAttrs::Where()
976 : {
977 0 : return ( pPcd ) ? pPcd->Where() : WW8_CP_MAX;
978 : }
979 :
980 50214 : void WW8PLCFx_PCDAttrs::GetSprms(WW8PLCFxDesc* p)
981 : {
982 : void* pData;
983 :
984 50214 : p->bRealLineEnd = false;
985 50214 : if ( !pPcdI || !pPcdI->Get(p->nStartPos, p->nEndPos, pData) )
986 : {
987 : // PLCF fully processed
988 0 : p->nStartPos = p->nEndPos = WW8_CP_MAX;
989 0 : p->pMemPos = 0;
990 0 : p->nSprmsLen = 0;
991 0 : return;
992 : }
993 :
994 50214 : sal_uInt16 nPrm = SVBT16ToShort( ( (WW8_PCD*)pData )->prm );
995 50214 : if ( nPrm & 1 )
996 : {
997 : // PRM Variant 2
998 0 : sal_uInt16 nSprmIdx = nPrm >> 1;
999 :
1000 0 : if( nSprmIdx >= nGrpprls )
1001 : {
1002 : // Invalid Index
1003 0 : p->nStartPos = p->nEndPos = WW8_CP_MAX;
1004 0 : p->pMemPos = 0;
1005 0 : p->nSprmsLen = 0;
1006 0 : return;
1007 : }
1008 0 : const sal_uInt8* pSprms = pGrpprls[ nSprmIdx ];
1009 :
1010 0 : p->nSprmsLen = SVBT16ToShort( pSprms ); // Length
1011 0 : pSprms += 2;
1012 0 : p->pMemPos = pSprms; // Position
1013 : }
1014 : else
1015 : {
1016 : // SPRM is stored directly into members var
1017 : /*
1018 : These are the attr that are in the piece-table instead of in the text!
1019 : */
1020 :
1021 50214 : if (IsSevenMinus(GetFIBVersion()))
1022 : {
1023 0 : aShortSprm[0] = (sal_uInt8)( ( nPrm & 0xfe) >> 1 );
1024 0 : aShortSprm[1] = (sal_uInt8)( nPrm >> 8 );
1025 0 : p->nSprmsLen = ( nPrm ) ? 2 : 0; // length
1026 :
1027 : // store Postion of internal mini storage in Data Pointer
1028 0 : p->pMemPos = aShortSprm;
1029 : }
1030 : else
1031 : {
1032 50214 : p->pMemPos = 0;
1033 50214 : p->nSprmsLen = 0;
1034 50214 : sal_uInt8 nSprmListIdx = (sal_uInt8)((nPrm & 0xfe) >> 1);
1035 50214 : if( nSprmListIdx )
1036 : {
1037 : // process Sprm Id Matching as explained in MS Documentation
1038 :
1039 : // ''Property Modifier(variant 1) (PRM)''
1040 : // see file: s62f39.htm
1041 :
1042 : // Since isprm is 7 bits, rgsprmPrm can hold 0x80 entries.
1043 : static const sal_uInt16 aSprmId[0x80] =
1044 : {
1045 : // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1046 : 0x0000,0x0000,0x0000,0x0000,
1047 : // sprmPIncLvl, sprmPJc, sprmPFSideBySide, sprmPFKeep
1048 : 0x2402,0x2403,0x2404,0x2405,
1049 : // sprmPFKeepFollow, sprmPFPageBreakBefore, sprmPBrcl,
1050 : // sprmPBrcp
1051 : 0x2406,0x2407,0x2408,0x2409,
1052 : // sprmPIlvl, sprmNoop, sprmPFNoLineNumb, sprmNoop
1053 : 0x260A,0x0000,0x240C,0x0000,
1054 : // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1055 : 0x0000,0x0000,0x0000,0x0000,
1056 : // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1057 : 0x0000,0x0000,0x0000,0x0000,
1058 : // sprmPFInTable, sprmPFTtp, sprmNoop, sprmNoop
1059 : 0x2416,0x2417,0x0000,0x0000,
1060 : // sprmNoop, sprmPPc, sprmNoop, sprmNoop
1061 : 0x0000,0x261B,0x0000,0x0000,
1062 : // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1063 : 0x0000,0x0000,0x0000,0x0000,
1064 : // sprmNoop, sprmPWr, sprmNoop, sprmNoop
1065 : 0x0000,0x2423,0x0000,0x0000,
1066 : // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1067 : 0x0000,0x0000,0x0000,0x0000,
1068 : // sprmPFNoAutoHyph, sprmNoop, sprmNoop, sprmNoop
1069 : 0x242A,0x0000,0x0000,0x0000,
1070 : // sprmNoop, sprmNoop, sprmPFLocked, sprmPFWidowControl
1071 : 0x0000,0x0000,0x2430,0x2431,
1072 : // sprmNoop, sprmPFKinsoku, sprmPFWordWrap,
1073 : // sprmPFOverflowPunct
1074 : 0x0000,0x2433,0x2434,0x2435,
1075 : // sprmPFTopLinePunct, sprmPFAutoSpaceDE,
1076 : // sprmPFAutoSpaceDN, sprmNoop
1077 : 0x2436,0x2437,0x2438,0x0000,
1078 : // sprmNoop, sprmPISnapBaseLine, sprmNoop, sprmNoop
1079 : 0x0000,0x243B,0x000,0x0000,
1080 : // sprmNoop, sprmCFStrikeRM, sprmCFRMark, sprmCFFldVanish
1081 : 0x0000,0x0800,0x0801,0x0802,
1082 : // sprmNoop, sprmNoop, sprmNoop, sprmCFData
1083 : 0x0000,0x0000,0x0000,0x0806,
1084 : // sprmNoop, sprmNoop, sprmNoop, sprmCFOle2
1085 : 0x0000,0x0000,0x0000,0x080A,
1086 : // sprmNoop, sprmCHighlight, sprmCFEmboss, sprmCSfxText
1087 : 0x0000,0x2A0C,0x0858,0x2859,
1088 : // sprmNoop, sprmNoop, sprmNoop, sprmCPlain
1089 : 0x0000,0x0000,0x0000,0x2A33,
1090 : // sprmNoop, sprmCFBold, sprmCFItalic, sprmCFStrike
1091 : 0x0000,0x0835,0x0836,0x0837,
1092 : // sprmCFOutline, sprmCFShadow, sprmCFSmallCaps, sprmCFCaps,
1093 : 0x0838,0x0839,0x083a,0x083b,
1094 : // sprmCFVanish, sprmNoop, sprmCKul, sprmNoop,
1095 : 0x083C,0x0000,0x2A3E,0x0000,
1096 : // sprmNoop, sprmNoop, sprmCIco, sprmNoop,
1097 : 0x0000,0x0000,0x2A42,0x0000,
1098 : // sprmCHpsInc, sprmNoop, sprmCHpsPosAdj, sprmNoop,
1099 : 0x2A44,0x0000,0x2A46,0x0000,
1100 : // sprmCIss, sprmNoop, sprmNoop, sprmNoop,
1101 : 0x2A48,0x0000,0x0000,0x0000,
1102 : // sprmNoop, sprmNoop, sprmNoop, sprmNoop,
1103 : 0x0000,0x0000,0x0000,0x0000,
1104 : // sprmNoop, sprmNoop, sprmNoop, sprmCFDStrike,
1105 : 0x0000,0x0000,0x0000,0x2A53,
1106 : // sprmCFImprint, sprmCFSpec, sprmCFObj, sprmPicBrcl,
1107 : 0x0854,0x0855,0x0856,0x2E00,
1108 : // sprmPOutLvl, sprmPFBiDi, sprmNoop, sprmNoop,
1109 : 0x2640,0x2441,0x0000,0x0000,
1110 : // sprmNoop, sprmNoop, sprmPPnbrRMarkNot
1111 : 0x0000,0x0000,0x0000,0x0000
1112 : };
1113 :
1114 : // find real Sprm Id:
1115 0 : sal_uInt16 nSprmId = aSprmId[ nSprmListIdx ];
1116 :
1117 0 : if( nSprmId )
1118 : {
1119 : // move Sprm Id and Sprm Param to internal mini storage:
1120 0 : aShortSprm[0] = (sal_uInt8)( ( nSprmId & 0x00ff) );
1121 0 : aShortSprm[1] = (sal_uInt8)( ( nSprmId & 0xff00) >> 8 );
1122 0 : aShortSprm[2] = (sal_uInt8)( nPrm >> 8 );
1123 :
1124 : // store Sprm Length in member:
1125 0 : p->nSprmsLen = ( nPrm ) ? 3 : 0;
1126 :
1127 : // store Postion of internal mini storage in Data Pointer
1128 0 : p->pMemPos = aShortSprm;
1129 : }
1130 : }
1131 : }
1132 : }
1133 : }
1134 :
1135 213 : WW8PLCFx_PCD::WW8PLCFx_PCD(ww::WordVersion eVersion, WW8PLCFpcd* pPLCFpcd,
1136 : WW8_CP nStartCp, bool bVer67P)
1137 213 : : WW8PLCFx(eVersion, false), nClipStart(-1)
1138 : {
1139 : // construct own iterator
1140 213 : pPcdI = new WW8PLCFpcd_Iter(*pPLCFpcd, nStartCp);
1141 213 : bVer67= bVer67P;
1142 213 : }
1143 :
1144 639 : WW8PLCFx_PCD::~WW8PLCFx_PCD()
1145 : {
1146 : // pPcd-Dtor which in called from WW8ScannerBase
1147 213 : delete pPcdI;
1148 426 : }
1149 :
1150 0 : sal_uLong WW8PLCFx_PCD::GetIMax() const
1151 : {
1152 0 : return pPcdI ? pPcdI->GetIMax() : 0;
1153 : }
1154 :
1155 2060 : sal_uLong WW8PLCFx_PCD::GetIdx() const
1156 : {
1157 2060 : return pPcdI ? pPcdI->GetIdx() : 0;
1158 : }
1159 :
1160 2057 : void WW8PLCFx_PCD::SetIdx( sal_uLong nIdx )
1161 : {
1162 2057 : if (pPcdI)
1163 2057 : pPcdI->SetIdx( nIdx );
1164 2057 : }
1165 :
1166 30884 : bool WW8PLCFx_PCD::SeekPos(WW8_CP nCpPos)
1167 : {
1168 30884 : return pPcdI ? pPcdI->SeekPos( nCpPos ) : false;
1169 : }
1170 :
1171 0 : WW8_CP WW8PLCFx_PCD::Where()
1172 : {
1173 0 : return pPcdI ? pPcdI->Where() : WW8_CP_MAX;
1174 : }
1175 :
1176 5582 : long WW8PLCFx_PCD::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
1177 : {
1178 : void* pData;
1179 5582 : rLen = 0;
1180 :
1181 5582 : if ( !pPcdI || !pPcdI->Get(rStart, rEnd, pData) )
1182 : {
1183 0 : rStart = rEnd = WW8_CP_MAX;
1184 0 : return -1;
1185 : }
1186 5582 : return pPcdI->GetIdx();
1187 : }
1188 :
1189 5 : void WW8PLCFx_PCD::advance()
1190 : {
1191 : OSL_ENSURE(pPcdI , "missing pPcdI");
1192 5 : if (pPcdI)
1193 5 : pPcdI->advance();
1194 5 : }
1195 :
1196 30606 : WW8_FC WW8PLCFx_PCD::AktPieceStartCp2Fc( WW8_CP nCp )
1197 : {
1198 : WW8_CP nCpStart, nCpEnd;
1199 : void* pData;
1200 :
1201 30606 : if ( !pPcdI->Get(nCpStart, nCpEnd, pData) )
1202 : {
1203 : OSL_ENSURE( !this, "AktPieceStartCp2Fc() with false Cp found (1)" );
1204 0 : return WW8_FC_MAX;
1205 : }
1206 :
1207 : OSL_ENSURE( nCp >= nCpStart && nCp < nCpEnd,
1208 : "AktPieceCp2Fc() with false Cp found (2)" );
1209 :
1210 30606 : if( nCp < nCpStart )
1211 0 : nCp = nCpStart;
1212 30606 : if( nCp >= nCpEnd )
1213 0 : nCp = nCpEnd - 1;
1214 :
1215 30606 : bool bIsUnicode = false;
1216 30606 : WW8_FC nFC = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
1217 30606 : if( !bVer67 )
1218 30606 : nFC = WW8PLCFx_PCD::TransformPieceAddress( nFC, bIsUnicode );
1219 :
1220 30606 : return nFC + (nCp - nCpStart) * (bIsUnicode ? 2 : 1);
1221 : }
1222 :
1223 309 : void WW8PLCFx_PCD::AktPieceFc2Cp( WW8_CP& rStartPos, WW8_CP& rEndPos,
1224 : const WW8ScannerBase *pSBase )
1225 : {
1226 : //No point going anywhere with this
1227 309 : if ((rStartPos == WW8_CP_MAX) && (rEndPos == WW8_CP_MAX))
1228 309 : return;
1229 :
1230 309 : rStartPos = pSBase->WW8Fc2Cp( rStartPos );
1231 309 : rEndPos = pSBase->WW8Fc2Cp( rEndPos );
1232 : }
1233 :
1234 20481 : WW8_CP WW8PLCFx_PCD::AktPieceStartFc2Cp( WW8_FC nStartPos )
1235 : {
1236 : WW8_CP nCpStart, nCpEnd;
1237 : void* pData;
1238 20481 : if ( !pPcdI->Get( nCpStart, nCpEnd, pData ) )
1239 : {
1240 : OSL_ENSURE( !this, "AktPieceStartFc2Cp() - error" );
1241 0 : return WW8_CP_MAX;
1242 : }
1243 20481 : bool bIsUnicode = false;
1244 20481 : sal_Int32 nFcStart = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
1245 20481 : if( !bVer67 )
1246 20481 : nFcStart = WW8PLCFx_PCD::TransformPieceAddress( nFcStart, bIsUnicode );
1247 :
1248 20481 : sal_Int32 nUnicodeFactor = bIsUnicode ? 2 : 1;
1249 :
1250 20481 : if( nStartPos < nFcStart )
1251 53 : nStartPos = nFcStart;
1252 :
1253 20481 : if( nStartPos >= nFcStart + (nCpEnd - nCpStart) * nUnicodeFactor )
1254 0 : nStartPos = nFcStart + (nCpEnd - nCpStart - 1) * nUnicodeFactor;
1255 :
1256 20481 : return nCpStart + (nStartPos - nFcStart) / nUnicodeFactor;
1257 : }
1258 :
1259 : // Helper routines for all
1260 :
1261 : // Convert BRC from WW6 to WW8 format
1262 0 : WW8_BRC::WW8_BRC(const WW8_BRCVer6& brcVer6)
1263 : {
1264 0 : sal_uInt8 _dptLineWidth = brcVer6.dxpLineWidth(),
1265 0 : _brcType = brcVer6.brcType();
1266 :
1267 0 : if (_dptLineWidth > 5) // this signifies dashed(6) or dotted(7) line
1268 : {
1269 0 : _brcType = _dptLineWidth;
1270 0 : _dptLineWidth = 1;
1271 : }
1272 0 : _dptLineWidth *= 6; // convert units from 0.75pt to 1/8pt
1273 :
1274 0 : *this = WW8_BRC(_dptLineWidth, _brcType, brcVer6.ico(), brcVer6.dxpSpace(),
1275 0 : brcVer6.fShadow(), false);
1276 0 : }
1277 :
1278 : // Convert BRC from WW8 to WW6 format
1279 0 : WW8_BRCVer6::WW8_BRCVer6(const WW8_BRC& brcVer8)
1280 : {
1281 0 : sal_uInt8 _brcType = brcVer8.brcType();
1282 0 : sal_uInt8 _dxpLineWidth = std::max(brcVer8.dptLineWidth() / 6, 7);
1283 0 : if (_brcType == 5 || _brcType == 6 )
1284 : {
1285 0 : _dxpLineWidth = _brcType;
1286 0 : _brcType = 1;
1287 : }
1288 0 : else if (_brcType > 3)
1289 : {
1290 0 : _brcType = 1;
1291 : }
1292 0 : *this = WW8_BRCVer6(_dxpLineWidth, _brcType, brcVer8.ico(),
1293 0 : brcVer8.dptSpace(), brcVer8.fShadow());
1294 0 : }
1295 :
1296 : // Convert BRC from WW8 to WW9 format
1297 29795 : WW8_BRCVer9::WW8_BRCVer9(const WW8_BRC& brcVer8)
1298 : {
1299 29795 : if (brcVer8.isNil()) {
1300 249 : UInt32ToSVBT32(0, aBits1);
1301 249 : UInt32ToSVBT32(0xffffffff, aBits2);
1302 : }
1303 : else
1304 : {
1305 29546 : sal_uInt32 _cv = brcVer8.ico() == 0 ? 0xff000000 // "auto" colour
1306 29546 : : wwUtility::RGBToBGR(SwWW8ImplReader::GetCol(brcVer8.ico()));
1307 59092 : *this = WW8_BRCVer9(_cv, brcVer8.dptLineWidth(), brcVer8.brcType(),
1308 88638 : brcVer8.dptSpace(), brcVer8.fShadow(), brcVer8.fFrame());
1309 : }
1310 29795 : }
1311 :
1312 4 : short WW8_BRC::DetermineBorderProperties(short *pSpace) const
1313 : {
1314 4 : WW8_BRCVer9 brcVer9(*this);
1315 4 : return brcVer9.DetermineBorderProperties(pSpace);
1316 : }
1317 :
1318 3072 : short WW8_BRCVer9::DetermineBorderProperties(short *pSpace) const
1319 : {
1320 : /*
1321 : Word does not factor the width of the border into the width/height
1322 : stored in the information for graphic/table/object widths, so we need
1323 : to figure out this extra width here and utilize the returned size in
1324 : our calculations
1325 : */
1326 : short nMSTotalWidth;
1327 :
1328 : //Specification in 8ths of a point, 1 Point = 20 Twips, so by 2.5
1329 3072 : nMSTotalWidth = (short)dptLineWidth() * 20 / 8;
1330 :
1331 : //Figure out the real size of the border according to word
1332 3072 : switch (brcType())
1333 : {
1334 : //Note that codes over 25 are undocumented, and I can't create
1335 : //these 4 here in the wild.
1336 : case 2:
1337 : case 4:
1338 : case 5:
1339 : case 22:
1340 : OSL_FAIL("Can't create these from the menus, please report");
1341 : default:
1342 : case 23: //Only 3pt in the menus, but honours the size setting.
1343 3072 : break;
1344 : case 10:
1345 : /*
1346 : triple line is five times the width of an ordinary line,
1347 : except that the smallest 1/4 point size appears to have
1348 : exactly the same total border width as a 3/4 point size
1349 : ordinary line, i.e. three times the nominal line width. The
1350 : second smallest 1/2 point size appears to have exactly the
1351 : total border width as a 2 1/4 border, i.e 4.5 times the size.
1352 : */
1353 0 : if (nMSTotalWidth == 5)
1354 0 : nMSTotalWidth*=3;
1355 0 : else if (nMSTotalWidth == 10)
1356 0 : nMSTotalWidth = nMSTotalWidth*9/2;
1357 : else
1358 0 : nMSTotalWidth*=5;
1359 0 : break;
1360 : case 20:
1361 : /*
1362 : wave, the dimensions appear to be created by the drawing of
1363 : the wave, so we have only two possibilites in the menus, 3/4
1364 : point is equal to solid 3 point. This calculation seems to
1365 : match well to results.
1366 : */
1367 0 : nMSTotalWidth +=45;
1368 0 : break;
1369 : case 21:
1370 : /*
1371 : double wave, the dimensions appear to be created by the
1372 : drawing of the wave, so we have only one possibilites in the
1373 : menus, that of 3/4 point is equal to solid 3 point. This
1374 : calculation seems to match well to results.
1375 : */
1376 0 : nMSTotalWidth += 45*2;
1377 0 : break;
1378 : }
1379 :
1380 3072 : if (pSpace)
1381 2532 : *pSpace = (short)dptSpace() * 20; // convert from points to twips
1382 3072 : return nMSTotalWidth;
1383 : }
1384 :
1385 : /*
1386 : * WW8Cp2Fc is a good method, a CP always maps to a FC
1387 : * WW8Fc2Cp on the other hand is more dubious, a random FC
1388 : * may not map to a valid CP. Try and avoid WW8Fc2Cp where
1389 : * possible
1390 : */
1391 1682 : WW8_CP WW8ScannerBase::WW8Fc2Cp( WW8_FC nFcPos ) const
1392 : {
1393 1682 : WW8_CP nFallBackCpEnd = WW8_CP_MAX;
1394 1682 : if( nFcPos == WW8_FC_MAX )
1395 0 : return nFallBackCpEnd;
1396 :
1397 : bool bIsUnicode;
1398 1682 : if (pWw8Fib->nVersion >= 8)
1399 1182 : bIsUnicode = false;
1400 : else
1401 500 : bIsUnicode = pWw8Fib->fExtChar ? true : false;
1402 :
1403 1682 : if( pPieceIter ) // Complex File ?
1404 : {
1405 618 : sal_uLong nOldPos = pPieceIter->GetIdx();
1406 :
1407 2174 : for (pPieceIter->SetIdx(0);
1408 938 : pPieceIter->GetIdx() < pPieceIter->GetIMax(); pPieceIter->advance())
1409 : {
1410 : WW8_CP nCpStart, nCpEnd;
1411 : void* pData;
1412 1556 : if( !pPieceIter->Get( nCpStart, nCpEnd, pData ) )
1413 : { // outside PLCFfpcd ?
1414 : OSL_ENSURE( !this, "PLCFpcd-WW8Fc2Cp() went wrong" );
1415 0 : break;
1416 : }
1417 1556 : sal_Int32 nFcStart = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
1418 1556 : if (pWw8Fib->nVersion >= 8)
1419 : {
1420 : nFcStart = WW8PLCFx_PCD::TransformPieceAddress( nFcStart,
1421 1556 : bIsUnicode );
1422 : }
1423 : else
1424 : {
1425 0 : bIsUnicode = pWw8Fib->fExtChar ? true : false;
1426 : }
1427 1556 : sal_Int32 nLen = (nCpEnd - nCpStart) * (bIsUnicode ? 2 : 1);
1428 :
1429 : /*
1430 : If this cp is inside this piece, or its the last piece and we are
1431 : on the very last cp of that piece
1432 : */
1433 1556 : if (nFcPos >= nFcStart)
1434 : {
1435 : // found
1436 : WW8_CP nTempCp =
1437 1556 : nCpStart + ((nFcPos - nFcStart) / (bIsUnicode ? 2 : 1));
1438 1556 : if (nFcPos < nFcStart + nLen)
1439 : {
1440 618 : pPieceIter->SetIdx( nOldPos );
1441 618 : return nTempCp;
1442 : }
1443 938 : else if (nFcPos == nFcStart + nLen)
1444 : {
1445 : //Keep this cp as its on a piece boundary because we might
1446 : //need it if tests fail
1447 0 : nFallBackCpEnd = nTempCp;
1448 : }
1449 : }
1450 : }
1451 : // not found
1452 0 : pPieceIter->SetIdx( nOldPos ); // not found
1453 : /*
1454 : If it was not found, then this is because it has fallen between two
1455 : stools, i.e. either it is the last cp/fc of the last piece, or it is
1456 : the last cp/fc of a disjoint piece.
1457 : */
1458 0 : return nFallBackCpEnd;
1459 : }
1460 :
1461 : // No complex file
1462 1064 : if (!bIsUnicode)
1463 1064 : nFallBackCpEnd = (nFcPos - pWw8Fib->fcMin);
1464 : else
1465 0 : nFallBackCpEnd = (nFcPos - pWw8Fib->fcMin + 1) / 2;
1466 :
1467 1064 : return nFallBackCpEnd;
1468 : }
1469 :
1470 101387 : WW8_FC WW8ScannerBase::WW8Cp2Fc(WW8_CP nCpPos, bool* pIsUnicode,
1471 : WW8_CP* pNextPieceCp, bool* pTestFlag) const
1472 : {
1473 101387 : if( pTestFlag )
1474 113 : *pTestFlag = true;
1475 101387 : if( WW8_CP_MAX == nCpPos )
1476 0 : return WW8_CP_MAX;
1477 :
1478 : bool bIsUnicode;
1479 101387 : if( !pIsUnicode )
1480 682 : pIsUnicode = &bIsUnicode;
1481 :
1482 101387 : if (pWw8Fib->nVersion >= 8)
1483 98396 : *pIsUnicode = false;
1484 : else
1485 2991 : *pIsUnicode = pWw8Fib->fExtChar ? true : false;
1486 :
1487 101387 : if( pPieceIter )
1488 : {
1489 : // Complex File
1490 95156 : if( pNextPieceCp )
1491 111 : *pNextPieceCp = WW8_CP_MAX;
1492 :
1493 95156 : if( !pPieceIter->SeekPos( nCpPos ) )
1494 : {
1495 0 : if( pTestFlag )
1496 0 : *pTestFlag = false;
1497 : else {
1498 : OSL_ENSURE( !this, "Handed over wrong CP to WW8Cp2Fc()" );
1499 : }
1500 0 : return WW8_FC_MAX;
1501 : }
1502 : WW8_CP nCpStart, nCpEnd;
1503 : void* pData;
1504 95156 : if( !pPieceIter->Get( nCpStart, nCpEnd, pData ) )
1505 : {
1506 0 : if( pTestFlag )
1507 0 : *pTestFlag = false;
1508 : else {
1509 : OSL_ENSURE( !this, "PLCFfpcd-Get went wrong" );
1510 : }
1511 0 : return WW8_FC_MAX;
1512 : }
1513 95156 : if( pNextPieceCp )
1514 111 : *pNextPieceCp = nCpEnd;
1515 :
1516 95156 : WW8_FC nRet = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
1517 95156 : if (pWw8Fib->nVersion >= 8)
1518 95156 : nRet = WW8PLCFx_PCD::TransformPieceAddress( nRet, *pIsUnicode );
1519 : else
1520 0 : *pIsUnicode = pWw8Fib->fExtChar ? true : false;
1521 :
1522 95156 : nRet += (nCpPos - nCpStart) * (*pIsUnicode ? 2 : 1);
1523 :
1524 95156 : return nRet;
1525 : }
1526 :
1527 : // No complex file
1528 6231 : return pWw8Fib->fcMin + nCpPos * (*pIsUnicode ? 2 : 1);
1529 : }
1530 :
1531 : // class WW8ScannerBase
1532 73 : WW8PLCFpcd* WW8ScannerBase::OpenPieceTable( SvStream* pStr, const WW8Fib* pWwF )
1533 : {
1534 73 : if ( ((8 > pWw8Fib->nVersion) && !pWwF->fComplex) || !pWwF->lcbClx )
1535 1 : return NULL;
1536 :
1537 72 : WW8_FC nClxPos = pWwF->fcClx;
1538 72 : sal_Int32 nClxLen = pWwF->lcbClx;
1539 72 : sal_Int32 nLeft = nClxLen;
1540 72 : sal_Int16 nGrpprl = 0;
1541 :
1542 72 : if (!checkSeek(*pStr, nClxPos))
1543 0 : return NULL;
1544 :
1545 : while( true ) // Zaehle Zahl der Grpprls
1546 : {
1547 73 : sal_uInt8 clxt(2);
1548 73 : pStr->ReadUChar( clxt );
1549 73 : nLeft--;
1550 73 : if( 2 == clxt ) // PLCFfpcd ?
1551 71 : break; // PLCFfpcd gefunden
1552 2 : if( 1 == clxt ) // clxtGrpprl ?
1553 0 : nGrpprl++;
1554 2 : sal_uInt16 nLen(0);
1555 2 : pStr->ReadUInt16( nLen );
1556 2 : nLeft -= 2 + nLen;
1557 2 : if( nLeft < 0 )
1558 1 : return NULL; // gone wrong
1559 1 : pStr->SeekRel( nLen ); // ueberlies grpprl
1560 : }
1561 :
1562 142 : if (!checkSeek(*pStr, nClxPos))
1563 0 : return NULL;
1564 :
1565 71 : nLeft = nClxLen;
1566 71 : pPieceGrpprls = new sal_uInt8*[nGrpprl + 1];
1567 71 : memset( pPieceGrpprls, 0, ( nGrpprl + 1 ) * sizeof(sal_uInt8 *) );
1568 71 : nPieceGrpprls = nGrpprl;
1569 71 : sal_Int16 nAktGrpprl = 0; // read Grpprls
1570 : while( true )
1571 : {
1572 71 : sal_uInt8 clxt(2);
1573 71 : pStr->ReadUChar( clxt );
1574 71 : nLeft--;
1575 71 : if( 2 == clxt) // PLCFfpcd ?
1576 71 : break; // PLCFfpcd found
1577 0 : sal_uInt16 nLen(0);
1578 0 : pStr->ReadUInt16( nLen );
1579 0 : nLeft -= 2 + nLen;
1580 0 : if( nLeft < 0 )
1581 0 : return NULL; // gone wrong
1582 0 : if( 1 == clxt ) // clxtGrpprl ?
1583 : {
1584 0 : sal_uInt8* p = new sal_uInt8[nLen+2]; // allocate
1585 0 : ShortToSVBT16(nLen, p); // trage Laenge ein
1586 0 : if (!checkRead(*pStr, p+2, nLen)) // read grpprl
1587 : {
1588 0 : delete[] p;
1589 0 : return NULL;
1590 : }
1591 0 : pPieceGrpprls[nAktGrpprl++] = p; // trage in Array ein
1592 : }
1593 : else
1594 0 : pStr->SeekRel( nLen ); // ueberlies nicht-Grpprl
1595 : }
1596 : // lies Piece Table PLCF ein
1597 71 : sal_Int32 nPLCFfLen(0);
1598 71 : if (pWwF->GetFIBVersion() <= ww::eWW2)
1599 : {
1600 0 : sal_Int16 nWordTwoLen(0);
1601 0 : pStr->ReadInt16( nWordTwoLen );
1602 0 : nPLCFfLen = nWordTwoLen;
1603 : }
1604 : else
1605 71 : pStr->ReadInt32( nPLCFfLen );
1606 : OSL_ENSURE( 65536 > nPLCFfLen, "PLCFfpcd above 64 k" );
1607 72 : return new WW8PLCFpcd( pStr, pStr->Tell(), nPLCFfLen, 8 );
1608 : }
1609 :
1610 73 : void WW8ScannerBase::DeletePieceTable()
1611 : {
1612 73 : if( pPieceGrpprls )
1613 : {
1614 71 : for( sal_uInt8** p = pPieceGrpprls; *p; p++ )
1615 0 : delete[] (*p);
1616 71 : delete[] pPieceGrpprls;
1617 71 : pPieceGrpprls = 0;
1618 : }
1619 73 : }
1620 :
1621 73 : WW8ScannerBase::WW8ScannerBase( SvStream* pSt, SvStream* pTblSt,
1622 : SvStream* pDataSt, WW8Fib* pWwFib )
1623 : : pWw8Fib(pWwFib), pMainFdoa(0), pHdFtFdoa(0), pMainTxbx(0),
1624 : pMainTxbxBkd(0), pHdFtTxbx(0), pHdFtTxbxBkd(0), pMagicTables(0),
1625 73 : pSubdocs(0), pExtendedAtrds(0), pPieceGrpprls(0)
1626 : {
1627 73 : pPiecePLCF = OpenPieceTable( pTblSt, pWw8Fib ); // Complex
1628 73 : if( pPiecePLCF )
1629 : {
1630 71 : pPieceIter = new WW8PLCFpcd_Iter( *pPiecePLCF );
1631 : pPLCFx_PCD = new WW8PLCFx_PCD(pWwFib->GetFIBVersion(), pPiecePLCF, 0,
1632 71 : IsSevenMinus(pWw8Fib->GetFIBVersion()));
1633 : pPLCFx_PCDAttrs = new WW8PLCFx_PCDAttrs(pWwFib->GetFIBVersion(),
1634 71 : pPLCFx_PCD, this);
1635 : }
1636 : else
1637 : {
1638 2 : pPieceIter = 0;
1639 2 : pPLCFx_PCD = 0;
1640 2 : pPLCFx_PCDAttrs = 0;
1641 : }
1642 :
1643 : // pChpPLCF and pPapPLCF may NOT be created before pPLCFx_PCD !!
1644 73 : pChpPLCF = new WW8PLCFx_Cp_FKP( pSt, pTblSt, pDataSt, *this, CHP ); // CHPX
1645 73 : pPapPLCF = new WW8PLCFx_Cp_FKP( pSt, pTblSt, pDataSt, *this, PAP ); // PAPX
1646 :
1647 73 : pSepPLCF = new WW8PLCFx_SEPX( pSt, pTblSt, *pWwFib, 0 ); // SEPX
1648 :
1649 : // Footnotes
1650 : pFtnPLCF = new WW8PLCFx_SubDoc( pTblSt, pWwFib->GetFIBVersion(), 0,
1651 : pWwFib->fcPlcffndRef, pWwFib->lcbPlcffndRef, pWwFib->fcPlcffndTxt,
1652 73 : pWwFib->lcbPlcffndTxt, 2 );
1653 : // Endnotes
1654 : pEdnPLCF = new WW8PLCFx_SubDoc( pTblSt, pWwFib->GetFIBVersion(), 0,
1655 : pWwFib->fcPlcfendRef, pWwFib->lcbPlcfendRef, pWwFib->fcPlcfendTxt,
1656 73 : pWwFib->lcbPlcfendTxt, 2 );
1657 : // Comments
1658 : pAndPLCF = new WW8PLCFx_SubDoc( pTblSt, pWwFib->GetFIBVersion(), 0,
1659 : pWwFib->fcPlcfandRef, pWwFib->lcbPlcfandRef, pWwFib->fcPlcfandTxt,
1660 73 : pWwFib->lcbPlcfandTxt, IsSevenMinus(pWwFib->GetFIBVersion()) ? 20 : 30);
1661 :
1662 : // Fields Main Text
1663 73 : pFldPLCF = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_MAINTEXT);
1664 : // Fields Header / Footer
1665 73 : pFldHdFtPLCF= new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_HDFT);
1666 : // Fields Footnote
1667 73 : pFldFtnPLCF = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_FTN);
1668 : // Fields Endnote
1669 73 : pFldEdnPLCF = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_EDN);
1670 : // Fields Comments
1671 73 : pFldAndPLCF = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_AND);
1672 : // Fields in Textboxes in Main Text
1673 73 : pFldTxbxPLCF= new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_TXBX);
1674 : // Fields in Textboxes in Header / Footer
1675 73 : pFldTxbxHdFtPLCF = new WW8PLCFx_FLD(pTblSt,*pWwFib,MAN_TXBX_HDFT);
1676 :
1677 : // Note: 6 stands for "6 OR 7", 7 stands for "ONLY 7"
1678 73 : switch( pWw8Fib->nVersion )
1679 : {
1680 : case 6:
1681 : case 7:
1682 1 : if( pWwFib->fcPlcfdoaMom && pWwFib->lcbPlcfdoaMom )
1683 : {
1684 : pMainFdoa = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfdoaMom,
1685 0 : pWwFib->lcbPlcfdoaMom, 6 );
1686 : }
1687 1 : if( pWwFib->fcPlcfdoaHdr && pWwFib->lcbPlcfdoaHdr )
1688 : {
1689 : pHdFtFdoa = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfdoaHdr,
1690 0 : pWwFib->lcbPlcfdoaHdr, 6 );
1691 : }
1692 1 : break;
1693 : case 8:
1694 72 : if( pWwFib->fcPlcfspaMom && pWwFib->lcbPlcfspaMom )
1695 : {
1696 : pMainFdoa = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfspaMom,
1697 20 : pWwFib->lcbPlcfspaMom, 26 );
1698 : }
1699 72 : if( pWwFib->fcPlcfspaHdr && pWwFib->lcbPlcfspaHdr )
1700 : {
1701 : pHdFtFdoa = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfspaHdr,
1702 4 : pWwFib->lcbPlcfspaHdr, 26 );
1703 : }
1704 : // PLCF for TextBox break-descriptors in the main text
1705 72 : if( pWwFib->fcPlcftxbxBkd && pWwFib->lcbPlcftxbxBkd )
1706 : {
1707 : pMainTxbxBkd = new WW8PLCFspecial( pTblSt,
1708 16 : pWwFib->fcPlcftxbxBkd, pWwFib->lcbPlcftxbxBkd, 0);
1709 : }
1710 : // PLCF for TextBox break-descriptors in Header/Footer range
1711 72 : if( pWwFib->fcPlcfHdrtxbxBkd && pWwFib->lcbPlcfHdrtxbxBkd )
1712 : {
1713 : pHdFtTxbxBkd = new WW8PLCFspecial( pTblSt,
1714 1 : pWwFib->fcPlcfHdrtxbxBkd, pWwFib->lcbPlcfHdrtxbxBkd, 0);
1715 : }
1716 : // Sub table cp positions
1717 72 : if (pWwFib->fcPlcfTch && pWwFib->lcbPlcfTch)
1718 : {
1719 : pMagicTables = new WW8PLCFspecial( pTblSt,
1720 59 : pWwFib->fcPlcfTch, pWwFib->lcbPlcfTch, 4);
1721 : }
1722 : // Sub document cp positions
1723 72 : if (pWwFib->fcPlcfwkb && pWwFib->lcbPlcfwkb)
1724 : {
1725 : pSubdocs = new WW8PLCFspecial( pTblSt,
1726 1 : pWwFib->fcPlcfwkb, pWwFib->lcbPlcfwkb, 12);
1727 : }
1728 : // Extended ATRD
1729 72 : if (pWwFib->fcAtrdExtra && pWwFib->lcbAtrdExtra)
1730 : {
1731 7 : sal_Size nOldPos = pTblSt->Tell();
1732 7 : if (checkSeek(*pTblSt, pWwFib->fcAtrdExtra) && (pTblSt->remainingSize() >= pWwFib->lcbAtrdExtra))
1733 : {
1734 6 : pExtendedAtrds = new sal_uInt8[pWwFib->lcbAtrdExtra];
1735 6 : pWwFib->lcbAtrdExtra = pTblSt->Read(pExtendedAtrds, pWwFib->lcbAtrdExtra);
1736 : }
1737 : else
1738 1 : pWwFib->lcbAtrdExtra = 0;
1739 7 : pTblSt->Seek(nOldPos);
1740 : }
1741 :
1742 72 : break;
1743 : default:
1744 : OSL_ENSURE( !this, "Es wurde vergessen, nVersion zu kodieren!" );
1745 0 : break;
1746 : }
1747 :
1748 : // PLCF for TextBox stories in main text
1749 73 : sal_uInt32 nLenTxBxS = (8 > pWw8Fib->nVersion) ? 0 : 22;
1750 73 : if( pWwFib->fcPlcftxbxTxt && pWwFib->lcbPlcftxbxTxt )
1751 : {
1752 : pMainTxbx = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcftxbxTxt,
1753 16 : pWwFib->lcbPlcftxbxTxt, nLenTxBxS );
1754 : }
1755 :
1756 : // PLCF for TextBox stories in Header/Footer range
1757 73 : if( pWwFib->fcPlcfHdrtxbxTxt && pWwFib->lcbPlcfHdrtxbxTxt )
1758 : {
1759 : pHdFtTxbx = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfHdrtxbxTxt,
1760 1 : pWwFib->lcbPlcfHdrtxbxTxt, nLenTxBxS );
1761 : }
1762 :
1763 73 : pBook = new WW8PLCFx_Book(pTblSt, *pWwFib);
1764 73 : }
1765 :
1766 73 : WW8ScannerBase::~WW8ScannerBase()
1767 : {
1768 73 : DeletePieceTable();
1769 73 : delete pPLCFx_PCDAttrs;
1770 73 : delete pPLCFx_PCD;
1771 73 : delete pPieceIter;
1772 73 : delete pPiecePLCF;
1773 73 : delete pBook;
1774 73 : delete pFldEdnPLCF;
1775 73 : delete pFldFtnPLCF;
1776 73 : delete pFldAndPLCF;
1777 73 : delete pFldHdFtPLCF;
1778 73 : delete pFldPLCF;
1779 73 : delete pFldTxbxPLCF;
1780 73 : delete pFldTxbxHdFtPLCF;
1781 73 : delete pEdnPLCF;
1782 73 : delete pFtnPLCF;
1783 73 : delete pAndPLCF;
1784 73 : delete pSepPLCF;
1785 73 : delete pPapPLCF;
1786 73 : delete pChpPLCF;
1787 : // vergessene Schaeflein
1788 73 : delete pMainFdoa;
1789 73 : delete pHdFtFdoa;
1790 73 : delete pMainTxbx;
1791 73 : delete pMainTxbxBkd;
1792 73 : delete pHdFtTxbx;
1793 73 : delete pHdFtTxbxBkd;
1794 73 : delete pMagicTables;
1795 73 : delete pSubdocs;
1796 73 : delete [] pExtendedAtrds;
1797 73 : }
1798 :
1799 : // Fields
1800 :
1801 0 : static bool WW8SkipField(WW8PLCFspecial& rPLCF)
1802 : {
1803 : void* pData;
1804 : WW8_CP nP;
1805 :
1806 0 : if (!rPLCF.Get(nP, pData)) // End of PLCFspecial?
1807 0 : return false;
1808 :
1809 0 : rPLCF.advance();
1810 :
1811 0 : if((((sal_uInt8*)pData)[0] & 0x1f ) != 0x13 ) // No beginning?
1812 0 : return true; // Do not terminate on error
1813 :
1814 0 : if( !rPLCF.Get( nP, pData ) )
1815 0 : return false;
1816 :
1817 0 : while((((sal_uInt8*)pData)[0] & 0x1f ) == 0x13 )
1818 : {
1819 : // still new (nested) beginnings ?
1820 0 : WW8SkipField( rPLCF ); // nested Field in description
1821 0 : if( !rPLCF.Get( nP, pData ) )
1822 0 : return false;
1823 : }
1824 :
1825 0 : if((((sal_uInt8*)pData)[0] & 0x1f ) == 0x14 )
1826 : {
1827 :
1828 : // Field Separator ?
1829 0 : rPLCF.advance();
1830 :
1831 0 : if( !rPLCF.Get( nP, pData ) )
1832 0 : return false;
1833 :
1834 0 : while ((((sal_uInt8*)pData)[0] & 0x1f ) == 0x13)
1835 : {
1836 : // still new (nested) beginnings?
1837 0 : WW8SkipField( rPLCF ); // nested Field in Results
1838 0 : if( !rPLCF.Get( nP, pData ) )
1839 0 : return false;
1840 : }
1841 : }
1842 0 : rPLCF.advance();
1843 :
1844 0 : return true;
1845 : }
1846 :
1847 26 : static bool WW8GetFieldPara(WW8PLCFspecial& rPLCF, WW8FieldDesc& rF)
1848 : {
1849 : void* pData;
1850 26 : sal_uLong nOldIdx = rPLCF.GetIdx();
1851 :
1852 26 : rF.nLen = rF.nId = rF.nOpt = rF.bCodeNest = rF.bResNest = false;
1853 :
1854 26 : if( !rPLCF.Get( rF.nSCode, pData ) ) // end of PLCFspecial?
1855 0 : goto Err;
1856 :
1857 26 : rPLCF.advance();
1858 :
1859 26 : if((((sal_uInt8*)pData)[0] & 0x1f ) != 0x13 ) // No beginning?
1860 0 : goto Err;
1861 :
1862 26 : rF.nId = ((sal_uInt8*)pData)[1];
1863 :
1864 26 : if( !rPLCF.Get( rF.nLCode, pData ) )
1865 0 : goto Err;
1866 :
1867 26 : rF.nSRes = rF.nLCode; // Default
1868 26 : rF.nSCode++; // without markers
1869 26 : rF.nLCode -= rF.nSCode; // Pos -> length
1870 :
1871 52 : while((((sal_uInt8*)pData)[0] & 0x1f ) == 0x13 )
1872 : {
1873 : // still new (nested) beginnings ?
1874 0 : WW8SkipField( rPLCF ); // nested Field in description
1875 0 : rF.bCodeNest = true;
1876 0 : if( !rPLCF.Get( rF.nSRes, pData ) )
1877 0 : goto Err;
1878 : }
1879 :
1880 26 : if ((((sal_uInt8*)pData)[0] & 0x1f ) == 0x14 ) // Field Separator?
1881 : {
1882 26 : rPLCF.advance();
1883 :
1884 26 : if( !rPLCF.Get( rF.nLRes, pData ) )
1885 0 : goto Err;
1886 :
1887 52 : while((((sal_uInt8*)pData)[0] & 0x1f ) == 0x13 )
1888 : {
1889 : // still new (nested) beginnings ?
1890 0 : WW8SkipField( rPLCF ); // nested Field in results
1891 0 : rF.bResNest = true;
1892 0 : if( !rPLCF.Get( rF.nLRes, pData ) )
1893 0 : goto Err;
1894 : }
1895 26 : rF.nLen = rF.nLRes - rF.nSCode + 2; // nLRes is still the final position
1896 26 : rF.nLRes -= rF.nSRes; // now: nLRes = length
1897 26 : rF.nSRes++; // Endpos encluding Markers
1898 26 : rF.nLRes--;
1899 : }else{
1900 0 : rF.nLRes = 0; // no result found
1901 0 : rF.nLen = rF.nSRes - rF.nSCode + 2; // total length
1902 : }
1903 :
1904 26 : rPLCF.advance();
1905 26 : if((((sal_uInt8*)pData)[0] & 0x1f ) == 0x15 )
1906 : {
1907 : // Field end ?
1908 : // INDEX-Fld has set Bit7?
1909 26 : rF.nOpt = ((sal_uInt8*)pData)[1]; // yes -> copy flags
1910 : }else{
1911 0 : rF.nId = 0; // no -> Field invalid
1912 : }
1913 :
1914 26 : rPLCF.SetIdx( nOldIdx );
1915 26 : return true;
1916 : Err:
1917 0 : rPLCF.SetIdx( nOldIdx );
1918 0 : return false;
1919 : }
1920 :
1921 0 : OUString read_uInt8_BeltAndBracesString(SvStream& rStrm, rtl_TextEncoding eEnc)
1922 : {
1923 0 : OUString aRet = read_uInt8_lenPrefixed_uInt8s_ToOUString(rStrm, eEnc);
1924 0 : rStrm.SeekRel(sizeof(sal_uInt8)); // skip null-byte at end
1925 0 : return aRet;
1926 : }
1927 :
1928 967 : OUString read_uInt16_BeltAndBracesString(SvStream& rStrm)
1929 : {
1930 967 : OUString aRet = read_uInt16_PascalString(rStrm);
1931 967 : rStrm.SeekRel(sizeof(sal_Unicode)); // skip null-byte at end
1932 967 : return aRet;
1933 : }
1934 :
1935 112 : sal_Int32 WW8ScannerBase::WW8ReadString( SvStream& rStrm, OUString& rStr,
1936 : WW8_CP nAktStartCp, long nTotalLen, rtl_TextEncoding eEnc ) const
1937 : {
1938 : // Read in plain text, which can extend over several pieces
1939 112 : rStr = OUString();
1940 :
1941 112 : long nTotalRead = 0;
1942 112 : WW8_CP nBehindTextCp = nAktStartCp + nTotalLen;
1943 112 : WW8_CP nNextPieceCp = nBehindTextCp; // Initialization, important for Ver6
1944 113 : do
1945 : {
1946 : bool bIsUnicode, bPosOk;
1947 113 : WW8_FC fcAct = WW8Cp2Fc(nAktStartCp,&bIsUnicode,&nNextPieceCp,&bPosOk);
1948 :
1949 : // Probably aimed beyond file end, doesn't matter!
1950 113 : if( !bPosOk )
1951 0 : break;
1952 :
1953 113 : rStrm.Seek( fcAct );
1954 :
1955 113 : long nLen = ( (nNextPieceCp < nBehindTextCp) ? nNextPieceCp
1956 113 : : nBehindTextCp ) - nAktStartCp;
1957 :
1958 113 : if( 0 >= nLen )
1959 0 : break;
1960 :
1961 113 : if( nLen > USHRT_MAX - 1 )
1962 0 : nLen = USHRT_MAX - 1;
1963 :
1964 226 : rStr += bIsUnicode
1965 : ? read_uInt16s_ToOUString(rStrm, nLen)
1966 113 : : read_uInt8s_ToOUString(rStrm, nLen, eEnc);
1967 :
1968 113 : nTotalRead += nLen;
1969 113 : nAktStartCp += nLen;
1970 113 : if ( nTotalRead != rStr.getLength() )
1971 0 : break;
1972 : }
1973 : while( nTotalRead < nTotalLen );
1974 :
1975 112 : return rStr.getLength();
1976 : }
1977 :
1978 163 : WW8PLCFspecial::WW8PLCFspecial(SvStream* pSt, sal_uInt32 nFilePos,
1979 : sal_uInt32 nPLCF, sal_uInt32 nStruct)
1980 163 : : nIdx(0), nStru(nStruct)
1981 : {
1982 163 : const sal_uInt32 nValidMin=4;
1983 :
1984 163 : sal_Size nOldPos = pSt->Tell();
1985 :
1986 163 : bool bValid = checkSeek(*pSt, nFilePos);
1987 163 : sal_Size nRemainingSize = pSt->remainingSize();
1988 163 : if( !(nRemainingSize >= nValidMin && nPLCF >= nValidMin ))
1989 0 : bValid = false;
1990 163 : nPLCF = bValid ? std::min(nRemainingSize, static_cast<sal_Size>(nPLCF)) : nValidMin;
1991 :
1992 : // Pointer to Pos- and Struct-array
1993 163 : pPLCF_PosArray = new sal_Int32[ ( nPLCF + 3 ) / 4 ];
1994 163 : pPLCF_PosArray[0] = 0;
1995 :
1996 163 : nPLCF = bValid ? pSt->Read(pPLCF_PosArray, nPLCF) : nValidMin;
1997 :
1998 163 : nPLCF = std::max(nPLCF, nValidMin);
1999 :
2000 163 : nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
2001 : #ifdef OSL_BIGENDIAN
2002 : for( nIdx = 0; nIdx <= nIMax; nIdx++ )
2003 : pPLCF_PosArray[nIdx] = OSL_SWAPDWORD( pPLCF_PosArray[nIdx] );
2004 : nIdx = 0;
2005 : #endif // OSL_BIGENDIAN
2006 163 : if( nStruct ) // Pointer to content array
2007 135 : pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
2008 : else
2009 28 : pPLCF_Contents = 0; // no content
2010 :
2011 163 : pSt->Seek(nOldPos);
2012 163 : }
2013 :
2014 : // WW8PLCFspecial::SeekPos() sets WW8PLCFspecial to position nPos, while also the entry is used
2015 : // that begins before nPos and ends after nPos.
2016 : // Suitable for normal attributes. However, the beginning of the attribute is not corrected onto
2017 : // the position nPos.
2018 165 : bool WW8PLCFspecial::SeekPos(long nP)
2019 : {
2020 165 : if( nP < pPLCF_PosArray[0] )
2021 : {
2022 0 : nIdx = 0;
2023 0 : return false; // Not found: nP less than smallest entry
2024 : }
2025 :
2026 : // Search from beginning?
2027 165 : if( (1 > nIdx) || (nP < pPLCF_PosArray[ nIdx-1 ]) )
2028 83 : nIdx = 1;
2029 :
2030 165 : long nI = nIdx ? nIdx : 1;
2031 165 : long nEnd = nIMax;
2032 :
2033 165 : for(int n = (1==nIdx ? 1 : 2); n; --n )
2034 : {
2035 1352 : for( ; nI <=nEnd; ++nI)
2036 : { // search with an index that is incremented by 1
2037 1352 : if( nP < pPLCF_PosArray[nI] )
2038 : { // found position
2039 165 : nIdx = nI - 1; // nI - 1 is the correct index
2040 165 : return true; // done
2041 : }
2042 : }
2043 0 : nI = 1;
2044 0 : nEnd = nIdx-1;
2045 : }
2046 0 : nIdx = nIMax; // not found, greater than all entries
2047 0 : return false;
2048 : }
2049 :
2050 : // WW8PLCFspecial::SeekPosExact() like SeekPos(), but it is ensured that no attribute is cut,
2051 : // i.e. the next given attribute begins at or after nPos.
2052 : // Is used for fields and bookmarks.
2053 232 : bool WW8PLCFspecial::SeekPosExact(long nP)
2054 : {
2055 232 : if( nP < pPLCF_PosArray[0] )
2056 : {
2057 4 : nIdx = 0;
2058 4 : return false; // Not found: nP less than smallest entry
2059 : }
2060 : // Search from beginning?
2061 228 : if( nP <=pPLCF_PosArray[nIdx] )
2062 92 : nIdx = 0;
2063 :
2064 228 : long nI = nIdx ? nIdx-1 : 0;
2065 228 : long nEnd = nIMax;
2066 :
2067 322 : for(int n = (0==nIdx ? 1 : 2); n; --n )
2068 : {
2069 1586 : for( ; nI < nEnd; ++nI)
2070 : {
2071 1492 : if( nP <=pPLCF_PosArray[nI] )
2072 : { // found position
2073 152 : nIdx = nI; // nI is the correct index
2074 152 : return true; // done
2075 : }
2076 : }
2077 94 : nI = 0;
2078 94 : nEnd = nIdx;
2079 : }
2080 76 : nIdx = nIMax; // Not found, greater than all entries
2081 76 : return false;
2082 : }
2083 :
2084 1033 : bool WW8PLCFspecial::Get(WW8_CP& rPos, void*& rpValue) const
2085 : {
2086 1033 : return GetData( nIdx, rPos, rpValue );
2087 : }
2088 :
2089 1045 : bool WW8PLCFspecial::GetData(long nInIdx, WW8_CP& rPos, void*& rpValue) const
2090 : {
2091 1045 : if ( nInIdx >= nIMax )
2092 : {
2093 69 : rPos = WW8_CP_MAX;
2094 69 : return false;
2095 : }
2096 976 : rPos = pPLCF_PosArray[nInIdx];
2097 976 : rpValue = pPLCF_Contents ? (void*)&pPLCF_Contents[nInIdx * nStru] : 0;
2098 976 : return true;
2099 : }
2100 :
2101 : // WW8PLCF e.g. for SEPX
2102 : // Ctor for *others* than Fkps
2103 : // With nStartPos < 0, the first element of PLCFs will be taken
2104 119 : WW8PLCF::WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
2105 119 : WW8_CP nStartPos) : pPLCF_PosArray(0), nIdx(0), nStru(nStruct)
2106 : {
2107 : OSL_ENSURE( nPLCF, "WW8PLCF: nPLCF is zero!" );
2108 :
2109 119 : nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
2110 :
2111 119 : ReadPLCF(rSt, nFilePos, nPLCF);
2112 :
2113 119 : if( nStartPos >= 0 )
2114 87 : SeekPos( nStartPos );
2115 119 : }
2116 :
2117 : // Ctor *only* for Fkps
2118 : // The last 2 parameters are needed for PLCF.Chpx and PLCF.Papx.
2119 : // If ncpN != 0, then an incomple PLCF will be completed. This is always required for WW6 with
2120 : // lack of resources and for WordPad (W95).
2121 : // With nStartPos < 0, the first element of the PLCFs is taken.
2122 146 : WW8PLCF::WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
2123 : WW8_CP nStartPos, sal_Int32 nPN, sal_Int32 ncpN): pPLCF_PosArray(0), nIdx(0),
2124 146 : nStru(nStruct)
2125 : {
2126 146 : nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
2127 :
2128 146 : if( nIMax >= ncpN )
2129 144 : ReadPLCF(rSt, nFilePos, nPLCF);
2130 : else
2131 2 : GeneratePLCF(rSt, nPN, ncpN);
2132 :
2133 146 : if( nStartPos >= 0 )
2134 146 : SeekPos( nStartPos );
2135 146 : }
2136 :
2137 263 : void WW8PLCF::ReadPLCF(SvStream& rSt, WW8_FC nFilePos, sal_uInt32 nPLCF)
2138 : {
2139 263 : sal_Size nOldPos = rSt.Tell();
2140 263 : bool bValid = checkSeek(rSt, nFilePos) && (rSt.remainingSize() >= nPLCF);
2141 :
2142 263 : if (bValid)
2143 : {
2144 : // Pointer to Pos-array
2145 263 : pPLCF_PosArray = new WW8_CP[ ( nPLCF + 3 ) / 4 ];
2146 263 : bValid = checkRead(rSt, pPLCF_PosArray, nPLCF);
2147 : }
2148 :
2149 263 : if (bValid)
2150 : {
2151 : #ifdef OSL_BIGENDIAN
2152 : for( nIdx = 0; nIdx <= nIMax; nIdx++ )
2153 : pPLCF_PosArray[nIdx] = OSL_SWAPDWORD( pPLCF_PosArray[nIdx] );
2154 : nIdx = 0;
2155 : #endif // OSL_BIGENDIAN
2156 : // Pointer to content array
2157 263 : pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
2158 : }
2159 :
2160 : OSL_ENSURE(bValid, "Document has corrupt PLCF, ignoring it");
2161 :
2162 263 : if (!bValid)
2163 0 : MakeFailedPLCF();
2164 :
2165 263 : rSt.Seek(nOldPos);
2166 263 : }
2167 :
2168 2 : void WW8PLCF::MakeFailedPLCF()
2169 : {
2170 2 : nIMax = 0;
2171 2 : delete[] pPLCF_PosArray;
2172 2 : pPLCF_PosArray = new sal_Int32[2];
2173 2 : pPLCF_PosArray[0] = pPLCF_PosArray[1] = WW8_CP_MAX;
2174 2 : pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
2175 2 : }
2176 :
2177 2 : void WW8PLCF::GeneratePLCF(SvStream& rSt, sal_Int32 nPN, sal_Int32 ncpN)
2178 : {
2179 : OSL_ENSURE( nIMax < ncpN, "Pcl.Fkp: Why is PLCF too big?" );
2180 :
2181 2 : bool failure = false;
2182 2 : nIMax = ncpN;
2183 :
2184 2 : if ((nIMax < 1) || (nIMax > (WW8_CP_MAX - 4)/6) || ((nPN + ncpN) > USHRT_MAX))
2185 2 : failure = true;
2186 :
2187 2 : if (!failure)
2188 : {
2189 0 : size_t nSiz = 6 * nIMax + 4;
2190 0 : size_t nElems = ( nSiz + 3 ) / 4;
2191 0 : pPLCF_PosArray = new sal_Int32[ nElems ]; // Pointer to Pos-array
2192 :
2193 0 : for (sal_Int32 i = 0; i < ncpN && !failure; ++i)
2194 : {
2195 0 : failure = true;
2196 : // construct FC entries
2197 : // first FC entry of each Fkp
2198 0 : if (checkSeek(rSt, ( nPN + i ) << 9 ))
2199 0 : continue;
2200 0 : WW8_CP nFc(0);
2201 0 : rSt.ReadInt32( nFc );
2202 0 : pPLCF_PosArray[i] = nFc;
2203 0 : failure = rSt.GetError();
2204 : }
2205 : }
2206 :
2207 2 : if (!failure)
2208 : {
2209 : do
2210 : {
2211 0 : failure = true;
2212 :
2213 0 : sal_Size nLastFkpPos = nPN + nIMax - 1;
2214 0 : nLastFkpPos = nLastFkpPos << 9;
2215 : // Anz. Fkp-Eintraege des letzten Fkp
2216 0 : if (!checkSeek(rSt, nLastFkpPos + 511))
2217 0 : break;
2218 :
2219 0 : sal_uInt8 nb(0);
2220 0 : rSt.ReadUChar( nb );
2221 : // letzer FC-Eintrag des letzten Fkp
2222 0 : if (!checkSeek(rSt, nLastFkpPos + nb * 4))
2223 0 : break;
2224 :
2225 0 : WW8_CP nFc(0);
2226 0 : rSt.ReadInt32( nFc );
2227 0 : pPLCF_PosArray[nIMax] = nFc; // end of the last Fkp
2228 :
2229 0 : failure = rSt.GetError();
2230 : } while(false);
2231 : }
2232 :
2233 2 : if (!failure)
2234 : {
2235 : // Pointer to content array
2236 0 : pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
2237 0 : sal_uInt8* p = pPLCF_Contents;
2238 :
2239 0 : for (sal_Int32 i = 0; i < ncpN; ++i) // construct PNs
2240 : {
2241 0 : ShortToSVBT16(static_cast<sal_uInt16>(nPN + i), p);
2242 0 : p+=2;
2243 : }
2244 : }
2245 :
2246 : OSL_ENSURE( !failure, "Document has corrupt PLCF, ignoring it" );
2247 :
2248 2 : if (failure)
2249 2 : MakeFailedPLCF();
2250 2 : }
2251 :
2252 31633 : bool WW8PLCF::SeekPos(WW8_CP nPos)
2253 : {
2254 31633 : WW8_CP nP = nPos;
2255 :
2256 31633 : if( nP < pPLCF_PosArray[0] )
2257 : {
2258 11 : nIdx = 0;
2259 : // not found: nPos less than smallest entry
2260 11 : return false;
2261 : }
2262 :
2263 : // Search from beginning?
2264 31622 : if( (1 > nIdx) || (nP < pPLCF_PosArray[ nIdx-1 ]) )
2265 4141 : nIdx = 1;
2266 :
2267 31622 : sal_Int32 nI = nIdx ? nIdx : 1;
2268 31622 : sal_Int32 nEnd = nIMax;
2269 :
2270 31627 : for(int n = (1==nIdx ? 1 : 2); n; --n )
2271 : {
2272 68918 : for( ; nI <=nEnd; ++nI) // search with an index that is incremented by 1
2273 : {
2274 68913 : if( nP < pPLCF_PosArray[nI] ) // found position
2275 : {
2276 31617 : nIdx = nI - 1; // nI - 1 is the correct index
2277 31617 : return true; // done
2278 : }
2279 : }
2280 5 : nI = 1;
2281 5 : nEnd = nIdx-1;
2282 : }
2283 :
2284 5 : nIdx = nIMax; // not found, greater than all entries
2285 5 : return false;
2286 : }
2287 :
2288 37266 : bool WW8PLCF::Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const
2289 : {
2290 37266 : if ( nIdx >= nIMax )
2291 : {
2292 44 : rStart = rEnd = WW8_CP_MAX;
2293 44 : return false;
2294 : }
2295 37222 : rStart = pPLCF_PosArray[ nIdx ];
2296 37222 : rEnd = pPLCF_PosArray[ nIdx + 1 ];
2297 37222 : rpValue = (void*)&pPLCF_Contents[nIdx * nStru];
2298 37222 : return true;
2299 : }
2300 :
2301 0 : WW8_CP WW8PLCF::Where() const
2302 : {
2303 0 : if ( nIdx >= nIMax )
2304 0 : return WW8_CP_MAX;
2305 :
2306 0 : return pPLCF_PosArray[nIdx];
2307 : }
2308 :
2309 71 : WW8PLCFpcd::WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos,
2310 : sal_uInt32 nPLCF, sal_uInt32 nStruct)
2311 71 : : nStru( nStruct )
2312 : {
2313 71 : const sal_uInt32 nValidMin=4;
2314 :
2315 71 : sal_Size nOldPos = pSt->Tell();
2316 :
2317 71 : bool bValid = checkSeek(*pSt, nFilePos);
2318 71 : sal_Size nRemainingSize = pSt->remainingSize();
2319 71 : if( !(nRemainingSize >= nValidMin && nPLCF >= nValidMin ))
2320 0 : bValid = false;
2321 71 : nPLCF = bValid ? std::min(nRemainingSize, static_cast<sal_Size>(nPLCF)) : nValidMin;
2322 :
2323 71 : pPLCF_PosArray = new sal_Int32[ ( nPLCF + 3 ) / 4 ]; // Pointer to Pos-array
2324 71 : pPLCF_PosArray[0] = 0;
2325 :
2326 71 : nPLCF = bValid ? pSt->Read(pPLCF_PosArray, nPLCF) : nValidMin;
2327 71 : nPLCF = std::max(nPLCF, nValidMin);
2328 :
2329 71 : nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
2330 : #ifdef OSL_BIGENDIAN
2331 : for( long nI = 0; nI <= nIMax; nI++ )
2332 : pPLCF_PosArray[nI] = OSL_SWAPDWORD( pPLCF_PosArray[nI] );
2333 : #endif // OSL_BIGENDIAN
2334 :
2335 : // Pointer to content array
2336 71 : pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
2337 :
2338 71 : pSt->Seek( nOldPos );
2339 71 : }
2340 :
2341 : // If nStartPos < 0, the first element of PLCFs will be taken
2342 284 : WW8PLCFpcd_Iter::WW8PLCFpcd_Iter( WW8PLCFpcd& rPLCFpcd, long nStartPos )
2343 284 : :rPLCF( rPLCFpcd ), nIdx( 0 )
2344 : {
2345 284 : if( nStartPos >= 0 )
2346 213 : SeekPos( nStartPos );
2347 284 : }
2348 :
2349 187030 : bool WW8PLCFpcd_Iter::SeekPos(long nPos)
2350 : {
2351 187030 : long nP = nPos;
2352 :
2353 187030 : if( nP < rPLCF.pPLCF_PosArray[0] )
2354 : {
2355 0 : nIdx = 0;
2356 0 : return false; // not found: nPos less than smallest entry
2357 : }
2358 : // Search from beginning?
2359 187030 : if( (1 > nIdx) || (nP < rPLCF.pPLCF_PosArray[ nIdx-1 ]) )
2360 130404 : nIdx = 1;
2361 :
2362 187030 : long nI = nIdx ? nIdx : 1;
2363 187030 : long nEnd = rPLCF.nIMax;
2364 :
2365 187158 : for(int n = (1==nIdx ? 1 : 2); n; --n )
2366 : {
2367 243902 : for( ; nI <=nEnd; ++nI)
2368 : { // search with an index that is incremented by 1
2369 243774 : if( nP < rPLCF.pPLCF_PosArray[nI] )
2370 : { // found position
2371 186904 : nIdx = nI - 1; // nI - 1 is the correct index
2372 186904 : return true; // done
2373 : }
2374 : }
2375 128 : nI = 1;
2376 128 : nEnd = nIdx-1;
2377 : }
2378 126 : nIdx = rPLCF.nIMax; // not found, greater than all entries
2379 126 : return false;
2380 : }
2381 :
2382 233733 : bool WW8PLCFpcd_Iter::Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const
2383 : {
2384 233733 : if( nIdx >= rPLCF.nIMax )
2385 : {
2386 0 : rStart = rEnd = WW8_CP_MAX;
2387 0 : return false;
2388 : }
2389 233733 : rStart = rPLCF.pPLCF_PosArray[nIdx];
2390 233733 : rEnd = rPLCF.pPLCF_PosArray[nIdx + 1];
2391 233733 : rpValue = (void*)&rPLCF.pPLCF_Contents[nIdx * rPLCF.nStru];
2392 233733 : return true;
2393 : }
2394 :
2395 0 : sal_Int32 WW8PLCFpcd_Iter::Where() const
2396 : {
2397 0 : if ( nIdx >= rPLCF.nIMax )
2398 0 : return SAL_MAX_INT32;
2399 :
2400 0 : return rPLCF.pPLCF_PosArray[nIdx];
2401 : }
2402 :
2403 39192 : bool WW8PLCFx_Fc_FKP::WW8Fkp::Entry::operator<
2404 : (const WW8PLCFx_Fc_FKP::WW8Fkp::Entry& rSecond) const
2405 : {
2406 39192 : return (mnFC < rSecond.mnFC);
2407 : }
2408 :
2409 7609 : bool IsReplaceAllSprm(sal_uInt16 nSpId)
2410 : {
2411 7609 : return (0x6645 == nSpId || 0x6646 == nSpId);
2412 : }
2413 :
2414 7609 : bool IsExpandableSprm(sal_uInt16 nSpId)
2415 : {
2416 7609 : return 0x646B == nSpId;
2417 : }
2418 :
2419 9375 : void WW8PLCFx_Fc_FKP::WW8Fkp::FillEntry(WW8PLCFx_Fc_FKP::WW8Fkp::Entry &rEntry,
2420 : sal_Size nDataOffset, sal_uInt16 nLen)
2421 : {
2422 9375 : bool bValidPos = (nDataOffset < sizeof(maRawData));
2423 :
2424 : OSL_ENSURE(bValidPos, "sprm sequence offset is out of range, ignoring");
2425 :
2426 9375 : if (!bValidPos)
2427 : {
2428 0 : rEntry.mnLen = 0;
2429 9375 : return;
2430 : }
2431 :
2432 9375 : sal_uInt16 nAvailableData = sizeof(maRawData)-nDataOffset;
2433 : OSL_ENSURE(nLen <= nAvailableData, "srpm sequence len is out of range, clipping");
2434 9375 : rEntry.mnLen = std::min(nLen, nAvailableData);
2435 9375 : rEntry.mpData = maRawData + nDataOffset;
2436 : }
2437 :
2438 1013 : WW8PLCFx_Fc_FKP::WW8Fkp::WW8Fkp(ww::WordVersion eVersion, SvStream* pSt,
2439 : SvStream* pDataSt, long _nFilePos, long nItemSiz, ePLCFT ePl,
2440 : WW8_FC nStartFc)
2441 : : nItemSize(nItemSiz), nFilePos(_nFilePos), mnIdx(0), ePLCF(ePl),
2442 1013 : maSprmParser(eVersion)
2443 : {
2444 1013 : memset(maRawData, 0, 512);
2445 :
2446 1013 : sal_Size nOldPos = pSt->Tell();
2447 :
2448 1013 : bool bCouldSeek = checkSeek(*pSt, nFilePos);
2449 1013 : bool bCouldRead = bCouldSeek ? checkRead(*pSt, maRawData, 512) : false;
2450 :
2451 1013 : mnIMax = bCouldRead ? maRawData[511] : 0;
2452 :
2453 1013 : sal_uInt8 *pStart = maRawData;
2454 : // Offset-Location in maRawData
2455 1013 : const size_t nRawDataStart = (mnIMax + 1) * 4;
2456 :
2457 25854 : for (mnIdx = 0; mnIdx < mnIMax; ++mnIdx)
2458 : {
2459 11914 : const size_t nRawDataOffset = nRawDataStart + mnIdx * nItemSize;
2460 :
2461 : //clip to available data, corrupt fkp
2462 11914 : if (nRawDataOffset >= 511)
2463 : {
2464 0 : mnIMax = mnIdx;
2465 0 : break;
2466 : }
2467 :
2468 11914 : unsigned int nOfs = maRawData[nRawDataOffset] * 2;
2469 :
2470 : //clip to available data, corrupt fkp
2471 11914 : if (nOfs >= 511)
2472 : {
2473 0 : mnIMax = mnIdx;
2474 0 : break;
2475 : }
2476 :
2477 11914 : Entry aEntry(Get_Long(pStart));
2478 :
2479 11914 : if (nOfs)
2480 : {
2481 11493 : switch (ePLCF)
2482 : {
2483 : case CHP:
2484 : {
2485 3884 : aEntry.mnLen = maRawData[nOfs];
2486 :
2487 : //len byte
2488 3884 : sal_Size nDataOffset = nOfs + 1;
2489 :
2490 3884 : FillEntry(aEntry, nDataOffset, aEntry.mnLen);
2491 :
2492 3884 : if (aEntry.mnLen && eVersion == ww::eWW2)
2493 : {
2494 87 : Word2CHPX aChpx = ReadWord2Chpx(*pSt, nFilePos + nOfs + 1, static_cast< sal_uInt8 >(aEntry.mnLen));
2495 87 : std::vector<sal_uInt8> aSprms = ChpxToSprms(aChpx);
2496 87 : aEntry.mnLen = static_cast< sal_uInt16 >(aSprms.size());
2497 87 : if (aEntry.mnLen)
2498 : {
2499 87 : aEntry.mpData = new sal_uInt8[aEntry.mnLen];
2500 87 : memcpy(aEntry.mpData, &(aSprms[0]), aEntry.mnLen);
2501 87 : aEntry.mbMustDelete = true;
2502 87 : }
2503 : }
2504 3884 : break;
2505 : }
2506 : case PAP:
2507 : {
2508 7609 : sal_uInt8 nDelta = 0;
2509 :
2510 7609 : aEntry.mnLen = maRawData[nOfs];
2511 7609 : if (IsEightPlus(eVersion) && !aEntry.mnLen)
2512 : {
2513 4879 : aEntry.mnLen = maRawData[nOfs+1];
2514 4879 : nDelta++;
2515 : }
2516 7609 : aEntry.mnLen *= 2;
2517 :
2518 : //stylecode, std/istd
2519 7609 : if (eVersion == ww::eWW2)
2520 : {
2521 62 : if (aEntry.mnLen >= 1)
2522 : {
2523 62 : aEntry.mnIStd = *(maRawData+nOfs+1+nDelta);
2524 62 : aEntry.mnLen--; //style code
2525 62 : if (aEntry.mnLen >= 6)
2526 : {
2527 62 : aEntry.mnLen-=6; //PHE
2528 : //skipi stc, len byte + 6 byte PHE
2529 62 : unsigned int nOffset = nOfs + 8;
2530 62 : if (nOffset >= 511) //Bad offset
2531 0 : aEntry.mnLen=0;
2532 62 : if (aEntry.mnLen) //start is ok
2533 : {
2534 62 : if (nOffset + aEntry.mnLen > 512) //Bad end, clip
2535 0 : aEntry.mnLen = 512 - nOffset;
2536 62 : aEntry.mpData = maRawData + nOffset;
2537 : }
2538 : }
2539 : else
2540 0 : aEntry.mnLen=0; //Too short
2541 : }
2542 : }
2543 : else
2544 : {
2545 7547 : if (aEntry.mnLen >= 2)
2546 : {
2547 : //len byte + optional extra len byte
2548 7547 : sal_Size nDataOffset = nOfs + 1 + nDelta;
2549 7547 : aEntry.mnIStd = nDataOffset <= sizeof(maRawData)-sizeof(aEntry.mnIStd) ?
2550 7547 : SVBT16ToShort(maRawData+nDataOffset) : 0;
2551 7547 : aEntry.mnLen-=2; //istd
2552 7547 : if (aEntry.mnLen)
2553 : {
2554 : //additional istd
2555 5491 : nDataOffset += sizeof(aEntry.mnIStd);
2556 :
2557 5491 : FillEntry(aEntry, nDataOffset, aEntry.mnLen);
2558 : }
2559 : }
2560 : else
2561 0 : aEntry.mnLen=0; //Too short, ignore
2562 : }
2563 :
2564 7609 : sal_uInt16 nSpId = aEntry.mnLen ? maSprmParser.GetSprmId(aEntry.mpData) : 0;
2565 :
2566 : /*
2567 : If we replace then we throw away the old data, if we
2568 : are expanding, then we tack the old data onto the end
2569 : of the new data
2570 : */
2571 7609 : bool bExpand = IsExpandableSprm(nSpId);
2572 7609 : if (IsReplaceAllSprm(nSpId) || bExpand)
2573 : {
2574 438 : sal_uInt32 nCurr = pDataSt->Tell();
2575 438 : sal_uInt32 nPos = SVBT32ToUInt32(aEntry.mpData + 2);
2576 438 : if (checkSeek(*pDataSt, nPos))
2577 : {
2578 438 : sal_uInt16 nOrigLen = bExpand ? aEntry.mnLen : 0;
2579 438 : sal_uInt8 *pOrigData = bExpand ? aEntry.mpData : 0;
2580 :
2581 438 : pDataSt->ReadUInt16( aEntry.mnLen );
2582 : aEntry.mpData =
2583 438 : new sal_uInt8[aEntry.mnLen + nOrigLen];
2584 438 : aEntry.mbMustDelete = true;
2585 : aEntry.mnLen =
2586 438 : pDataSt->Read(aEntry.mpData, aEntry.mnLen);
2587 :
2588 438 : pDataSt->Seek( nCurr );
2589 :
2590 438 : if (pOrigData)
2591 : {
2592 404 : memcpy(aEntry.mpData + aEntry.mnLen,
2593 808 : pOrigData, nOrigLen);
2594 404 : aEntry.mnLen = aEntry.mnLen + nOrigLen;
2595 : }
2596 : }
2597 : }
2598 : }
2599 7609 : break;
2600 : default:
2601 : OSL_FAIL("sweet god, what have you done!");
2602 0 : break;
2603 : }
2604 : }
2605 :
2606 11914 : maEntries.push_back(aEntry);
2607 :
2608 : #ifdef DEBUGSPRMREADER
2609 : {
2610 : sal_Int32 nLen;
2611 : sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen );
2612 :
2613 : WW8SprmIter aIter(pSprms, nLen, maSprmParser);
2614 : while (aIter.GetSprms())
2615 : {
2616 : fprintf(stderr, "id is %x\n", aIter.GetAktId());
2617 : aIter.advance();
2618 : }
2619 : }
2620 : #endif
2621 11914 : }
2622 :
2623 : //one more FC than grrpl entries
2624 1013 : maEntries.push_back(Entry(Get_Long(pStart)));
2625 :
2626 : //we expect them sorted, but it appears possible for them to arive unsorted
2627 1013 : std::sort(maEntries.begin(), maEntries.end());
2628 :
2629 1013 : mnIdx = 0;
2630 :
2631 1013 : if (nStartFc >= 0)
2632 994 : SeekPos(nStartFc);
2633 :
2634 1013 : pSt->Seek(nOldPos);
2635 1013 : }
2636 :
2637 41011 : WW8PLCFx_Fc_FKP::WW8Fkp::Entry::Entry(const Entry &rEntry)
2638 : : mnFC(rEntry.mnFC), mnLen(rEntry.mnLen), mnIStd(rEntry.mnIStd),
2639 41011 : mbMustDelete(rEntry.mbMustDelete)
2640 : {
2641 41011 : if (mbMustDelete)
2642 : {
2643 1662 : mpData = new sal_uInt8[mnLen];
2644 1662 : memcpy(mpData, rEntry.mpData, mnLen);
2645 : }
2646 : else
2647 39349 : mpData = rEntry.mpData;
2648 41011 : }
2649 :
2650 : WW8PLCFx_Fc_FKP::WW8Fkp::Entry&
2651 20119 : WW8PLCFx_Fc_FKP::WW8Fkp::Entry::operator=(const Entry &rEntry)
2652 : {
2653 20119 : if (this == &rEntry)
2654 0 : return *this;
2655 :
2656 20119 : if (mbMustDelete)
2657 232 : delete[] mpData;
2658 :
2659 20119 : mnFC = rEntry.mnFC;
2660 20119 : mnLen = rEntry.mnLen;
2661 20119 : mnIStd = rEntry.mnIStd;
2662 20119 : mbMustDelete = rEntry.mbMustDelete;
2663 :
2664 20119 : if (mbMustDelete)
2665 : {
2666 232 : mpData = new sal_uInt8[mnLen];
2667 232 : memcpy(mpData, rEntry.mpData, mnLen);
2668 : }
2669 : else
2670 19887 : mpData = rEntry.mpData;
2671 20119 : return *this;
2672 : }
2673 :
2674 53938 : WW8PLCFx_Fc_FKP::WW8Fkp::Entry::~Entry()
2675 : {
2676 53938 : if (mbMustDelete)
2677 2187 : delete[] mpData;
2678 53938 : }
2679 :
2680 4863 : void WW8PLCFx_Fc_FKP::WW8Fkp::Reset(WW8_FC nFc)
2681 : {
2682 4863 : SetIdx(0);
2683 4863 : if (nFc >= 0)
2684 4170 : SeekPos(nFc);
2685 4863 : }
2686 :
2687 31944 : bool WW8PLCFx_Fc_FKP::WW8Fkp::SeekPos(WW8_FC nFc)
2688 : {
2689 31944 : if (nFc < maEntries[0].mnFC)
2690 : {
2691 0 : mnIdx = 0;
2692 0 : return false; // not found: nPos less than smallest entry
2693 : }
2694 :
2695 : // Search from beginning?
2696 31944 : if ((1 > mnIdx) || (nFc < maEntries[mnIdx-1].mnFC))
2697 7789 : mnIdx = 1;
2698 :
2699 31944 : sal_uInt8 nI = mnIdx ? mnIdx : 1;
2700 31944 : sal_uInt8 nEnd = mnIMax;
2701 :
2702 32784 : for(sal_uInt8 n = (1==mnIdx ? 1 : 2); n; --n )
2703 : {
2704 106795 : for( ; nI <=nEnd; ++nI)
2705 : { // search with an index that is incremented by 1
2706 105955 : if (nFc < maEntries[nI].mnFC)
2707 : { // found position
2708 31166 : mnIdx = nI - 1; // nI - 1 is the correct index
2709 31166 : return true; // done
2710 : }
2711 : }
2712 840 : nI = 1;
2713 840 : nEnd = mnIdx-1;
2714 : }
2715 778 : mnIdx = mnIMax; // not found, greater than all entries
2716 778 : return false;
2717 : }
2718 :
2719 30974 : sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::Get(WW8_FC& rStart, WW8_FC& rEnd, sal_Int32& rLen)
2720 : const
2721 : {
2722 30974 : rLen = 0;
2723 :
2724 30974 : if (mnIdx >= mnIMax)
2725 : {
2726 114 : rStart = WW8_FC_MAX;
2727 114 : return 0;
2728 : }
2729 :
2730 30860 : rStart = maEntries[mnIdx].mnFC;
2731 30860 : rEnd = maEntries[mnIdx + 1].mnFC;
2732 :
2733 30860 : sal_uInt8* pSprms = GetLenAndIStdAndSprms( rLen );
2734 30860 : return pSprms;
2735 : }
2736 :
2737 6563 : bool WW8PLCFx_Fc_FKP::WW8Fkp::SetIdx(sal_uInt8 nI)
2738 : {
2739 6563 : if (nI < mnIMax)
2740 : {
2741 6302 : mnIdx = nI;
2742 6302 : return true;
2743 : }
2744 261 : return false;
2745 : }
2746 :
2747 84947 : sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::GetLenAndIStdAndSprms(sal_Int32& rLen) const
2748 : {
2749 84947 : rLen = maEntries[mnIdx].mnLen;
2750 84947 : return maEntries[mnIdx].mpData;
2751 : }
2752 :
2753 54117 : const sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm( sal_uInt16 nId )
2754 : {
2755 54117 : if (mnIdx >= mnIMax)
2756 30 : return 0;
2757 :
2758 : sal_Int32 nLen;
2759 54087 : sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen );
2760 :
2761 54087 : WW8SprmIter aIter(pSprms, nLen, maSprmParser);
2762 54087 : return aIter.FindSprm(nId);
2763 : }
2764 :
2765 0 : bool WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm(sal_uInt16 nId,
2766 : std::vector<const sal_uInt8 *> &rResult)
2767 : {
2768 0 : if (mnIdx >= mnIMax)
2769 0 : return false;
2770 :
2771 : sal_Int32 nLen;
2772 0 : sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen );
2773 :
2774 0 : WW8SprmIter aIter(pSprms, nLen, maSprmParser);
2775 :
2776 0 : while(aIter.GetSprms())
2777 : {
2778 0 : if (aIter.GetAktId() == nId)
2779 0 : rResult.push_back(aIter.GetAktParams());
2780 0 : aIter.advance();
2781 : };
2782 0 : return !rResult.empty();
2783 : }
2784 :
2785 0 : void WW8PLCFx::GetSprms( WW8PLCFxDesc* p )
2786 : {
2787 : OSL_ENSURE( !this, "Called wrong GetSprms" );
2788 0 : p->nStartPos = p->nEndPos = WW8_CP_MAX;
2789 0 : p->pMemPos = 0;
2790 0 : p->nSprmsLen = 0;
2791 0 : p->bRealLineEnd = false;
2792 0 : return;
2793 : }
2794 :
2795 0 : long WW8PLCFx::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
2796 : {
2797 : OSL_ENSURE( !this, "Called wrong GetNoSprms" );
2798 0 : rStart = rEnd = WW8_CP_MAX;
2799 0 : rLen = 0;
2800 0 : return 0;
2801 : }
2802 :
2803 : // ...Idx2: Default: ignore
2804 784 : sal_uLong WW8PLCFx::GetIdx2() const
2805 : {
2806 784 : return 0;
2807 : }
2808 :
2809 784 : void WW8PLCFx::SetIdx2(sal_uLong )
2810 : {
2811 784 : }
2812 :
2813 : class SamePos :
2814 : public std::unary_function<const WW8PLCFx_Fc_FKP::WW8Fkp *, bool>
2815 : {
2816 : private:
2817 : long mnPo;
2818 : public:
2819 5513 : SamePos(long nPo) : mnPo(nPo) {}
2820 20075 : bool operator()(const WW8PLCFx_Fc_FKP::WW8Fkp *pFkp)
2821 20075 : {return mnPo == pFkp->GetFilePos();}
2822 : };
2823 :
2824 5876 : bool WW8PLCFx_Fc_FKP::NewFkp()
2825 : {
2826 : WW8_CP nPLCFStart, nPLCFEnd;
2827 : void* pPage;
2828 :
2829 : static const int WW8FkpSizeTabVer2[ PLCF_END ] =
2830 : {
2831 : 1, 1, 0 /*, 0, 0, 0*/
2832 : };
2833 : static const int WW8FkpSizeTabVer6[ PLCF_END ] =
2834 : {
2835 : 1, 7, 0 /*, 0, 0, 0*/
2836 : };
2837 : static const int WW8FkpSizeTabVer8[ PLCF_END ] =
2838 : {
2839 : 1, 13, 0 /*, 0, 0, 0*/
2840 : };
2841 : const int* pFkpSizeTab;
2842 :
2843 5876 : switch (GetFIBVersion())
2844 : {
2845 : case ww::eWW2:
2846 6 : pFkpSizeTab = WW8FkpSizeTabVer2;
2847 6 : break;
2848 : case ww::eWW6:
2849 : case ww::eWW7:
2850 0 : pFkpSizeTab = WW8FkpSizeTabVer6;
2851 0 : break;
2852 : case ww::eWW8:
2853 5870 : pFkpSizeTab = WW8FkpSizeTabVer8;
2854 5870 : break;
2855 : default:
2856 : // program error!
2857 : OSL_ENSURE( !this, "Someone forgot to encode nVersion!" );
2858 0 : return false;
2859 : }
2860 :
2861 5876 : if (!pPLCF->Get( nPLCFStart, nPLCFEnd, pPage ))
2862 : {
2863 0 : pFkp = 0;
2864 0 : return false; // PLCF completely processed
2865 : }
2866 5876 : pPLCF->advance();
2867 5876 : long nPo = SVBT16ToShort( (sal_uInt8 *)pPage );
2868 5876 : nPo <<= 9; // shift as LONG
2869 :
2870 5876 : long nAktFkpFilePos = pFkp ? pFkp->GetFilePos() : -1;
2871 5876 : if (nAktFkpFilePos == nPo)
2872 363 : pFkp->Reset(GetStartFc());
2873 : else
2874 : {
2875 : myiter aIter =
2876 5513 : std::find_if(maFkpCache.begin(), maFkpCache.end(), SamePos(nPo));
2877 5513 : if (aIter != maFkpCache.end())
2878 : {
2879 4500 : pFkp = *aIter;
2880 4500 : pFkp->Reset(GetStartFc());
2881 : }
2882 3039 : else if (0 != (pFkp = new WW8Fkp(GetFIBVersion(), pFKPStrm, pDataStrm, nPo,
2883 2026 : pFkpSizeTab[ ePLCF ], ePLCF, GetStartFc())))
2884 : {
2885 1013 : maFkpCache.push_back(pFkp);
2886 :
2887 1013 : if (maFkpCache.size() > eMaxCache)
2888 : {
2889 750 : delete maFkpCache.front();
2890 750 : maFkpCache.pop_front();
2891 : }
2892 : }
2893 : }
2894 :
2895 5876 : SetStartFc( -1 ); // only the first time
2896 5876 : return true;
2897 : }
2898 :
2899 146 : WW8PLCFx_Fc_FKP::WW8PLCFx_Fc_FKP(SvStream* pSt, SvStream* pTblSt,
2900 : SvStream* pDataSt, const WW8Fib& rFib, ePLCFT ePl, WW8_FC nStartFcL)
2901 : : WW8PLCFx(rFib.GetFIBVersion(), true), pFKPStrm(pSt), pDataStrm(pDataSt),
2902 146 : pFkp(0), ePLCF(ePl), pPCDAttrs(0)
2903 : {
2904 146 : SetStartFc(nStartFcL);
2905 146 : long nLenStruct = (8 > rFib.nVersion) ? 2 : 4;
2906 146 : if (ePl == CHP)
2907 : {
2908 : pPLCF = new WW8PLCF(*pTblSt, rFib.fcPlcfbteChpx, rFib.lcbPlcfbteChpx,
2909 73 : nLenStruct, GetStartFc(), rFib.pnChpFirst, rFib.cpnBteChp);
2910 : }
2911 : else
2912 : {
2913 : pPLCF = new WW8PLCF(*pTblSt, rFib.fcPlcfbtePapx, rFib.lcbPlcfbtePapx,
2914 73 : nLenStruct, GetStartFc(), rFib.pnPapFirst, rFib.cpnBtePap);
2915 : }
2916 146 : }
2917 :
2918 292 : WW8PLCFx_Fc_FKP::~WW8PLCFx_Fc_FKP()
2919 : {
2920 146 : myiter aEnd = maFkpCache.end();
2921 409 : for (myiter aIter = maFkpCache.begin(); aIter != aEnd; ++aIter)
2922 263 : delete *aIter;
2923 146 : delete pPLCF;
2924 146 : delete pPCDAttrs;
2925 146 : }
2926 :
2927 1948 : sal_uLong WW8PLCFx_Fc_FKP::GetIdx() const
2928 : {
2929 1948 : sal_uLong u = pPLCF->GetIdx() << 8;
2930 1948 : if (pFkp)
2931 1948 : u |= pFkp->GetIdx();
2932 1948 : return u;
2933 : }
2934 :
2935 1945 : void WW8PLCFx_Fc_FKP::SetIdx( sal_uLong nIdx )
2936 : {
2937 1945 : if( !( nIdx & 0xffffff00L ) )
2938 : {
2939 245 : pPLCF->SetIdx( nIdx >> 8 );
2940 245 : pFkp = 0;
2941 : }
2942 : else
2943 : { // there was a Fkp
2944 : // Set PLCF one position back to retrieve the address of the Fkp
2945 1700 : pPLCF->SetIdx( ( nIdx >> 8 ) - 1 );
2946 1700 : if (NewFkp()) // read Fkp again
2947 : {
2948 1700 : sal_uInt8 nFkpIdx = static_cast<sal_uInt8>(nIdx & 0xff);
2949 1700 : pFkp->SetIdx(nFkpIdx); // set Fkp-Pos again
2950 : }
2951 : }
2952 1945 : }
2953 :
2954 31142 : bool WW8PLCFx_Fc_FKP::SeekPos(WW8_FC nFcPos)
2955 : {
2956 : // StartPos for next Where()
2957 31142 : SetStartFc( nFcPos );
2958 :
2959 : // find StartPos for next pPLCF->Get()
2960 31142 : bool bRet = pPLCF->SeekPos(nFcPos);
2961 :
2962 : // make FKP invalid?
2963 : WW8_CP nPLCFStart, nPLCFEnd;
2964 : void* pPage;
2965 31142 : if( pFkp && pPLCF->Get( nPLCFStart, nPLCFEnd, pPage ) )
2966 : {
2967 30567 : long nPo = SVBT16ToShort( (sal_uInt8 *)pPage );
2968 30567 : nPo <<= 9; // shift as LONG
2969 30567 : if (nPo != pFkp->GetFilePos())
2970 3787 : pFkp = 0;
2971 : else
2972 26780 : pFkp->SeekPos( nFcPos );
2973 : }
2974 31142 : return bRet;
2975 : }
2976 :
2977 20481 : WW8_FC WW8PLCFx_Fc_FKP::Where()
2978 : {
2979 20481 : if( !pFkp )
2980 : {
2981 0 : if( !NewFkp() )
2982 0 : return WW8_FC_MAX;
2983 : }
2984 20481 : WW8_FC nP = pFkp ? pFkp->Where() : WW8_FC_MAX;
2985 20481 : if( nP != WW8_FC_MAX )
2986 20481 : return nP;
2987 :
2988 0 : pFkp = 0; // FKP finished -> get new
2989 0 : return Where(); // easiest way: do it recursively
2990 : }
2991 :
2992 30974 : sal_uInt8* WW8PLCFx_Fc_FKP::GetSprmsAndPos(WW8_FC& rStart, WW8_FC& rEnd, sal_Int32& rLen)
2993 : {
2994 30974 : rLen = 0; // Default
2995 30974 : rStart = rEnd = WW8_FC_MAX;
2996 :
2997 30974 : if( !pFkp ) // Fkp not there ?
2998 : {
2999 4176 : if( !NewFkp() )
3000 0 : return 0;
3001 : }
3002 :
3003 30974 : sal_uInt8* pPos = pFkp ? pFkp->Get( rStart, rEnd, rLen ) : NULL;
3004 30974 : if( rStart == WW8_FC_MAX ) //Not found
3005 114 : return 0;
3006 30860 : return pPos;
3007 : }
3008 :
3009 0 : void WW8PLCFx_Fc_FKP::advance()
3010 : {
3011 0 : if( !pFkp )
3012 : {
3013 0 : if( !NewFkp() )
3014 0 : return;
3015 : }
3016 :
3017 0 : if (!pFkp)
3018 0 : return;
3019 :
3020 0 : pFkp->advance();
3021 0 : if( pFkp->Where() == WW8_FC_MAX )
3022 0 : (void)NewFkp();
3023 : }
3024 :
3025 8121 : sal_uInt16 WW8PLCFx_Fc_FKP::GetIstd() const
3026 : {
3027 8121 : return pFkp ? pFkp->GetIstd() : 0xFFFF;
3028 : }
3029 :
3030 40425 : void WW8PLCFx_Fc_FKP::GetPCDSprms( WW8PLCFxDesc& rDesc )
3031 : {
3032 40425 : rDesc.pMemPos = 0;
3033 40425 : rDesc.nSprmsLen = 0;
3034 40425 : if( pPCDAttrs )
3035 : {
3036 39112 : if( !pFkp )
3037 : {
3038 : OSL_FAIL("+Problem: GetPCDSprms: NewFkp necessary (not possible!)" );
3039 0 : if( !NewFkp() )
3040 40425 : return;
3041 : }
3042 39112 : pPCDAttrs->GetSprms(&rDesc);
3043 : }
3044 : }
3045 :
3046 54117 : const sal_uInt8* WW8PLCFx_Fc_FKP::HasSprm( sal_uInt16 nId )
3047 : {
3048 : // const would be nicer, but for that, NewFkp() would need to be replaced or eliminated
3049 54117 : if( !pFkp )
3050 : {
3051 : OSL_FAIL( "+Motz: HasSprm: NewFkp needed ( no const possible )" );
3052 : // happens in BugDoc 31722
3053 0 : if( !NewFkp() )
3054 0 : return 0;
3055 : }
3056 :
3057 54117 : if (!pFkp)
3058 0 : return 0;
3059 :
3060 54117 : const sal_uInt8* pRes = pFkp->HasSprm( nId );
3061 :
3062 54117 : if( !pRes )
3063 : {
3064 40152 : WW8PLCFxDesc aDesc;
3065 40152 : GetPCDSprms( aDesc );
3066 :
3067 40152 : if (aDesc.pMemPos)
3068 : {
3069 : WW8SprmIter aIter(aDesc.pMemPos, aDesc.nSprmsLen,
3070 0 : pFkp->GetSprmParser());
3071 0 : pRes = aIter.FindSprm(nId);
3072 : }
3073 : }
3074 :
3075 54117 : return pRes;
3076 : }
3077 :
3078 0 : bool WW8PLCFx_Fc_FKP::HasSprm(sal_uInt16 nId, std::vector<const sal_uInt8 *> &rResult)
3079 : {
3080 : // const would be nicer, but for that, NewFkp() would need to be replaced or eliminated
3081 0 : if (!pFkp)
3082 : {
3083 : OSL_FAIL( "+Motz: HasSprm: NewFkp needed ( no const possible )" );
3084 : // happens in BugDoc 31722
3085 0 : if( !NewFkp() )
3086 0 : return false;
3087 : }
3088 :
3089 0 : if (!pFkp)
3090 0 : return false;
3091 :
3092 0 : pFkp->HasSprm(nId, rResult);
3093 :
3094 0 : WW8PLCFxDesc aDesc;
3095 0 : GetPCDSprms( aDesc );
3096 :
3097 0 : if (aDesc.pMemPos)
3098 : {
3099 : WW8SprmIter aIter(aDesc.pMemPos, aDesc.nSprmsLen,
3100 0 : pFkp->GetSprmParser());
3101 0 : while(aIter.GetSprms())
3102 : {
3103 0 : if (aIter.GetAktId() == nId)
3104 0 : rResult.push_back(aIter.GetAktParams());
3105 0 : aIter.advance();
3106 : };
3107 : }
3108 0 : return !rResult.empty();
3109 : }
3110 :
3111 146 : WW8PLCFx_Cp_FKP::WW8PLCFx_Cp_FKP( SvStream* pSt, SvStream* pTblSt,
3112 : SvStream* pDataSt, const WW8ScannerBase& rBase, ePLCFT ePl )
3113 : : WW8PLCFx_Fc_FKP(pSt, pTblSt, pDataSt, *rBase.pWw8Fib, ePl,
3114 : rBase.WW8Cp2Fc(0)), rSBase(rBase), nAttrStart(-1), nAttrEnd(-1),
3115 : bLineEnd(false),
3116 146 : bComplex( (7 < rBase.pWw8Fib->nVersion) || rBase.pWw8Fib->fComplex )
3117 : {
3118 146 : ResetAttrStartEnd();
3119 :
3120 142 : pPcd = rSBase.pPiecePLCF ? new WW8PLCFx_PCD(GetFIBVersion(),
3121 288 : rBase.pPiecePLCF, 0, IsSevenMinus(GetFIBVersion())) : 0;
3122 :
3123 : /*
3124 : Make a copy of the piece attributes for so that the calls to HasSprm on a
3125 : Fc_FKP will be able to take into account the current piece attributes,
3126 : despite the fact that such attributes can only be found through a cp based
3127 : mechanism.
3128 : */
3129 146 : if (pPcd)
3130 : {
3131 : pPCDAttrs = rSBase.pPLCFx_PCDAttrs ? new WW8PLCFx_PCDAttrs(
3132 142 : rSBase.pWw8Fib->GetFIBVersion(), pPcd, &rSBase) : 0;
3133 : }
3134 :
3135 146 : pPieceIter = rSBase.pPieceIter;
3136 146 : }
3137 :
3138 438 : WW8PLCFx_Cp_FKP::~WW8PLCFx_Cp_FKP()
3139 : {
3140 146 : delete pPcd;
3141 292 : }
3142 :
3143 726 : void WW8PLCFx_Cp_FKP::ResetAttrStartEnd()
3144 : {
3145 726 : nAttrStart = -1;
3146 726 : nAttrEnd = -1;
3147 726 : bLineEnd = false;
3148 726 : }
3149 :
3150 0 : sal_uLong WW8PLCFx_Cp_FKP::GetPCDIMax() const
3151 : {
3152 0 : return pPcd ? pPcd->GetIMax() : 0;
3153 : }
3154 :
3155 1948 : sal_uLong WW8PLCFx_Cp_FKP::GetPCDIdx() const
3156 : {
3157 1948 : return pPcd ? pPcd->GetIdx() : 0;
3158 : }
3159 :
3160 1945 : void WW8PLCFx_Cp_FKP::SetPCDIdx( sal_uLong nIdx )
3161 : {
3162 1945 : if( pPcd )
3163 1945 : pPcd->SetIdx( nIdx );
3164 1945 : }
3165 :
3166 31205 : bool WW8PLCFx_Cp_FKP::SeekPos(WW8_CP nCpPos)
3167 : {
3168 31205 : if( pPcd ) // Complex
3169 : {
3170 30669 : if( !pPcd->SeekPos( nCpPos ) ) // set piece
3171 63 : return false;
3172 30606 : if (pPCDAttrs && !pPCDAttrs->GetIter()->SeekPos(nCpPos))
3173 0 : return false;
3174 30606 : return WW8PLCFx_Fc_FKP::SeekPos(pPcd->AktPieceStartCp2Fc(nCpPos));
3175 : }
3176 : // NO piece table !!!
3177 536 : return WW8PLCFx_Fc_FKP::SeekPos( rSBase.WW8Cp2Fc(nCpPos) );
3178 : }
3179 :
3180 20481 : WW8_CP WW8PLCFx_Cp_FKP::Where()
3181 : {
3182 20481 : WW8_FC nFc = WW8PLCFx_Fc_FKP::Where();
3183 20481 : if( pPcd )
3184 20481 : return pPcd->AktPieceStartFc2Cp( nFc ); // identify piece
3185 0 : return rSBase.WW8Fc2Cp( nFc ); // NO piece table !!!
3186 : }
3187 :
3188 31007 : void WW8PLCFx_Cp_FKP::GetSprms(WW8PLCFxDesc* p)
3189 : {
3190 31007 : WW8_CP nOrigCp = p->nStartPos;
3191 :
3192 31007 : if (!GetDirty()) //Normal case
3193 : {
3194 : p->pMemPos = WW8PLCFx_Fc_FKP::GetSprmsAndPos(p->nStartPos, p->nEndPos,
3195 30939 : p->nSprmsLen);
3196 : }
3197 : else
3198 : {
3199 : /*
3200 : For the odd case where we have a location in a fastsaved file which
3201 : does not have an entry in the FKP, perhaps its para end is in the next
3202 : piece, or perhaps the cp just doesn't exist at all in this document.
3203 : AdvSprm doesn't know so it sets the PLCF as dirty and we figure out
3204 : in this method what the situation is
3205 :
3206 : It doesn't exist then the piece iterator will not be able to find it.
3207 : Otherwise our cool fastsave algorithm can be brought to bear on the
3208 : problem.
3209 : */
3210 68 : if( !pPieceIter )
3211 0 : return;
3212 68 : sal_uLong nOldPos = pPieceIter->GetIdx();
3213 68 : bool bOk = pPieceIter->SeekPos(nOrigCp);
3214 68 : pPieceIter->SetIdx( nOldPos );
3215 68 : if (!bOk)
3216 63 : return;
3217 : }
3218 :
3219 30944 : if( pPcd ) // piece table available
3220 : {
3221 : // Init ( no ++ called, yet )
3222 30412 : if( (nAttrStart > nAttrEnd) || (nAttrStart == -1) )
3223 : {
3224 30412 : p->bRealLineEnd = (ePLCF == PAP);
3225 :
3226 30412 : if ( ((ePLCF == PAP ) || (ePLCF == CHP)) && (nOrigCp != WW8_CP_MAX) )
3227 : {
3228 30103 : bool bIsUnicode=false;
3229 : /*
3230 : To find the end of a paragraph for a character in a
3231 : complex format file.
3232 :
3233 : It is necessary to know the piece that contains the
3234 : character and the FC assigned to the character.
3235 : */
3236 :
3237 : //We set the piece iterator to the piece that contains the
3238 : //character, now we have the correct piece for this character
3239 30103 : sal_uLong nOldPos = pPieceIter->GetIdx();
3240 30103 : p->nStartPos = nOrigCp;
3241 30103 : pPieceIter->SeekPos( p->nStartPos);
3242 :
3243 : //This is the FC assigned to the character, but we already
3244 : //have the result of the next stage, so we can skip this step
3245 : //WW8_FC nStartFc = rSBase.WW8Cp2Fc(p->nStartPos, &bIsUnicode);
3246 :
3247 : /*
3248 : Using the FC of the character, first search the FKP that
3249 : describes the character to find the smallest FC in the rgfc
3250 : that is larger than the character FC.
3251 : */
3252 : //But the search has already been done, the next largest FC is
3253 : //p->nEndPos.
3254 30103 : WW8_FC nOldEndPos = p->nEndPos;
3255 :
3256 : /*
3257 : If the FC found in the FKP is less than or equal to the limit
3258 : FC of the piece, the end of the paragraph that contains the
3259 : character is at the FKP FC minus 1.
3260 : */
3261 : WW8_CP nCpStart, nCpEnd;
3262 30103 : void* pData=NULL;
3263 30103 : pPieceIter->Get(nCpStart, nCpEnd, pData);
3264 :
3265 30103 : WW8_FC nLimitFC = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
3266 30103 : WW8_FC nBeginLimitFC = nLimitFC;
3267 30103 : if (IsEightPlus(GetFIBVersion()))
3268 : {
3269 : nBeginLimitFC =
3270 : WW8PLCFx_PCD::TransformPieceAddress(nLimitFC,
3271 30103 : bIsUnicode);
3272 : }
3273 :
3274 : nLimitFC = nBeginLimitFC +
3275 30103 : (nCpEnd - nCpStart) * (bIsUnicode ? 2 : 1);
3276 :
3277 30103 : if (nOldEndPos <= nLimitFC)
3278 : {
3279 59894 : p->nEndPos = nCpEnd -
3280 59894 : (nLimitFC-nOldEndPos) / (bIsUnicode ? 2 : 1);
3281 : }
3282 : else
3283 : {
3284 156 : if (ePLCF == CHP)
3285 7 : p->nEndPos = nCpEnd;
3286 : else
3287 : {
3288 : /*
3289 : If the FKP FC that was found was greater than the FC
3290 : of the end of the piece, scan piece by piece toward
3291 : the end of the document until a piece is found that
3292 : contains a paragraph end mark.
3293 : */
3294 :
3295 : /*
3296 : It's possible to check if a piece contains a paragraph
3297 : mark by using the FC of the beginning of the piece to
3298 : search in the FKPs for the smallest FC in the FKP rgfc
3299 : that is greater than the FC of the beginning of the
3300 : piece. If the FC found is less than or equal to the
3301 : limit FC of the piece, then the character that ends
3302 : the paragraph is the character immediately before the
3303 : FKP fc
3304 : */
3305 :
3306 149 : pPieceIter->advance();
3307 :
3308 298 : for (;pPieceIter->GetIdx() < pPieceIter->GetIMax();
3309 0 : pPieceIter->advance())
3310 : {
3311 35 : if( !pPieceIter->Get( nCpStart, nCpEnd, pData ) )
3312 : {
3313 : OSL_ENSURE( !this, "piece iter broken!" );
3314 35 : break;
3315 : }
3316 35 : bIsUnicode = false;
3317 35 : sal_Int32 nFcStart=SVBT32ToUInt32(((WW8_PCD*)pData)->fc);
3318 :
3319 35 : if (IsEightPlus(GetFIBVersion()))
3320 : {
3321 : nFcStart =
3322 : WW8PLCFx_PCD::TransformPieceAddress(
3323 35 : nFcStart,bIsUnicode );
3324 : }
3325 :
3326 35 : nLimitFC = nFcStart + (nCpEnd - nCpStart) *
3327 35 : (bIsUnicode ? 2 : 1);
3328 :
3329 : //if it doesn't exist, skip it
3330 35 : if (!SeekPos(nCpStart))
3331 0 : continue;
3332 :
3333 : WW8_FC nOne,nSmallest;
3334 : p->pMemPos = WW8PLCFx_Fc_FKP::GetSprmsAndPos(nOne,
3335 35 : nSmallest, p->nSprmsLen);
3336 :
3337 35 : if (nSmallest <= nLimitFC)
3338 : {
3339 35 : WW8_CP nEndPos = nCpEnd -
3340 35 : (nLimitFC-nSmallest) / (bIsUnicode ? 2 : 1);
3341 :
3342 : OSL_ENSURE(nEndPos >= p->nStartPos, "EndPos before StartPos");
3343 :
3344 35 : if (nEndPos >= p->nStartPos)
3345 35 : p->nEndPos = nEndPos;
3346 :
3347 35 : break;
3348 : }
3349 : }
3350 : }
3351 : }
3352 30103 : pPieceIter->SetIdx( nOldPos );
3353 : }
3354 : else
3355 309 : pPcd->AktPieceFc2Cp( p->nStartPos, p->nEndPos,&rSBase );
3356 : }
3357 : else
3358 : {
3359 0 : p->nStartPos = nAttrStart;
3360 0 : p->nEndPos = nAttrEnd;
3361 0 : p->bRealLineEnd = bLineEnd;
3362 : }
3363 : }
3364 : else // NO piece table !!!
3365 : {
3366 532 : p->nStartPos = rSBase.WW8Fc2Cp( p->nStartPos );
3367 532 : p->nEndPos = rSBase.WW8Fc2Cp( p->nEndPos );
3368 532 : p->bRealLineEnd = ePLCF == PAP;
3369 : }
3370 : }
3371 :
3372 0 : void WW8PLCFx_Cp_FKP::advance()
3373 : {
3374 0 : WW8PLCFx_Fc_FKP::advance();
3375 : // !pPcd: emergency break
3376 0 : if ( !bComplex || !pPcd )
3377 0 : return;
3378 :
3379 0 : if( GetPCDIdx() >= GetPCDIMax() ) // End of PLCF
3380 : {
3381 0 : nAttrStart = nAttrEnd = WW8_CP_MAX;
3382 0 : return;
3383 : }
3384 :
3385 : sal_Int32 nFkpLen; // Fkp entry
3386 : // get Fkp entry
3387 0 : WW8PLCFx_Fc_FKP::GetSprmsAndPos(nAttrStart, nAttrEnd, nFkpLen);
3388 :
3389 0 : pPcd->AktPieceFc2Cp( nAttrStart, nAttrEnd, &rSBase );
3390 0 : bLineEnd = (ePLCF == PAP);
3391 : }
3392 :
3393 73 : WW8PLCFx_SEPX::WW8PLCFx_SEPX(SvStream* pSt, SvStream* pTblSt,
3394 : const WW8Fib& rFib, WW8_CP nStartCp)
3395 : : WW8PLCFx(rFib.GetFIBVersion(), true), maSprmParser(rFib.GetFIBVersion()),
3396 73 : pStrm(pSt), nArrMax(256), nSprmSiz(0)
3397 : {
3398 : pPLCF = rFib.lcbPlcfsed
3399 : ? new WW8PLCF(*pTblSt, rFib.fcPlcfsed, rFib.lcbPlcfsed,
3400 146 : GetFIBVersion() <= ww::eWW2 ? 6 : 12, nStartCp)
3401 219 : : 0;
3402 :
3403 73 : pSprms = new sal_uInt8[nArrMax]; // maximum length
3404 73 : }
3405 :
3406 219 : WW8PLCFx_SEPX::~WW8PLCFx_SEPX()
3407 : {
3408 73 : delete pPLCF;
3409 73 : delete[] pSprms;
3410 146 : }
3411 :
3412 112 : sal_uLong WW8PLCFx_SEPX::GetIdx() const
3413 : {
3414 112 : return pPLCF ? pPLCF->GetIdx() : 0;
3415 : }
3416 :
3417 112 : void WW8PLCFx_SEPX::SetIdx( sal_uLong nIdx )
3418 : {
3419 112 : if( pPLCF ) pPLCF->SetIdx( nIdx );
3420 112 : }
3421 :
3422 224 : bool WW8PLCFx_SEPX::SeekPos(WW8_CP nCpPos)
3423 : {
3424 224 : return pPLCF && pPLCF->SeekPos( nCpPos );
3425 : }
3426 :
3427 0 : WW8_CP WW8PLCFx_SEPX::Where()
3428 : {
3429 0 : return pPLCF ? pPLCF->Where() : 0;
3430 : }
3431 :
3432 405 : void WW8PLCFx_SEPX::GetSprms(WW8PLCFxDesc* p)
3433 : {
3434 810 : if( !pPLCF ) return;
3435 :
3436 : void* pData;
3437 :
3438 405 : p->bRealLineEnd = false;
3439 405 : if (!pPLCF->Get( p->nStartPos, p->nEndPos, pData ))
3440 : {
3441 32 : p->nStartPos = p->nEndPos = WW8_CP_MAX; // PLCF completely processed
3442 32 : p->pMemPos = 0;
3443 32 : p->nSprmsLen = 0;
3444 : }
3445 : else
3446 : {
3447 373 : sal_uInt32 nPo = SVBT32ToUInt32( (sal_uInt8*)pData+2 );
3448 373 : if (nPo == 0xFFFFFFFF)
3449 : {
3450 0 : p->nStartPos = p->nEndPos = WW8_CP_MAX; // Sepx empty
3451 0 : p->pMemPos = 0;
3452 0 : p->nSprmsLen = 0;
3453 : }
3454 : else
3455 : {
3456 373 : pStrm->Seek( nPo );
3457 :
3458 : // read len
3459 373 : if (GetFIBVersion() <= ww::eWW2) // eWW6 ?, docs say yes, but...
3460 : {
3461 1 : sal_uInt8 nSiz(0);
3462 1 : pStrm->ReadUChar( nSiz );
3463 1 : nSprmSiz = nSiz;
3464 : }
3465 : else
3466 372 : pStrm->ReadUInt16( nSprmSiz );
3467 :
3468 373 : if( nSprmSiz > nArrMax )
3469 : { // does not fit
3470 0 : delete[] pSprms;
3471 0 : nArrMax = nSprmSiz; // Get more memory
3472 0 : pSprms = new sal_uInt8[nArrMax];
3473 : }
3474 373 : nSprmSiz = pStrm->Read(pSprms, nSprmSiz); // read Sprms
3475 :
3476 373 : p->nSprmsLen = nSprmSiz;
3477 373 : p->pMemPos = pSprms; // return Position
3478 : }
3479 : }
3480 : }
3481 :
3482 45 : void WW8PLCFx_SEPX::advance()
3483 : {
3484 45 : if (pPLCF)
3485 45 : pPLCF->advance();
3486 45 : }
3487 :
3488 2927 : const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId ) const
3489 : {
3490 2927 : return HasSprm( nId, pSprms, nSprmSiz);
3491 : }
3492 :
3493 2927 : const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, const sal_uInt8* pOtherSprms,
3494 : long nOtherSprmSiz ) const
3495 : {
3496 2927 : const sal_uInt8 *pRet = 0;
3497 2927 : if (pPLCF)
3498 : {
3499 2927 : WW8SprmIter aIter(pOtherSprms, nOtherSprmSiz, maSprmParser);
3500 2927 : pRet = aIter.FindSprm(nId);
3501 : }
3502 2927 : return pRet;
3503 : }
3504 :
3505 170 : bool WW8PLCFx_SEPX::Find4Sprms(sal_uInt16 nId1,sal_uInt16 nId2,sal_uInt16 nId3,sal_uInt16 nId4,
3506 : sal_uInt8*& p1, sal_uInt8*& p2, sal_uInt8*& p3, sal_uInt8*& p4) const
3507 : {
3508 170 : if( !pPLCF )
3509 0 : return false;
3510 :
3511 170 : bool bFound = false;
3512 170 : p1 = 0;
3513 170 : p2 = 0;
3514 170 : p3 = 0;
3515 170 : p4 = 0;
3516 :
3517 170 : sal_uInt8* pSp = pSprms;
3518 170 : sal_uInt16 i=0;
3519 2480 : while (i + maSprmParser.MinSprmLen() <= nSprmSiz)
3520 : {
3521 : // Sprm found?
3522 2140 : sal_uInt16 nAktId = maSprmParser.GetSprmId(pSp);
3523 2140 : bool bOk = true;
3524 2140 : if( nAktId == nId1 )
3525 6 : p1 = pSp + maSprmParser.DistanceToData(nId1);
3526 2134 : else if( nAktId == nId2 )
3527 6 : p2 = pSp + maSprmParser.DistanceToData(nId2);
3528 2128 : else if( nAktId == nId3 )
3529 6 : p3 = pSp + maSprmParser.DistanceToData(nId3);
3530 2122 : else if( nAktId == nId4 )
3531 6 : p4 = pSp + maSprmParser.DistanceToData(nId4);
3532 : else
3533 2116 : bOk = false;
3534 2140 : bFound |= bOk;
3535 : // increment pointer so that it points to next SPRM
3536 2140 : sal_uInt16 x = maSprmParser.GetSprmSize(nAktId, pSp);
3537 2140 : i = i + x;
3538 2140 : pSp += x;
3539 : }
3540 170 : return bFound;
3541 : }
3542 :
3543 6 : const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const
3544 : {
3545 6 : if( !pPLCF )
3546 0 : return 0;
3547 :
3548 6 : sal_uInt8* pSp = pSprms;
3549 :
3550 6 : sal_uInt16 i=0;
3551 105 : while (i + maSprmParser.MinSprmLen() <= nSprmSiz)
3552 : {
3553 : // Sprm found?
3554 99 : sal_uInt16 nAktId = maSprmParser.GetSprmId(pSp);
3555 99 : if (nAktId == nId)
3556 : {
3557 8 : sal_uInt8 *pRet = pSp + maSprmParser.DistanceToData(nId);
3558 8 : if (*pRet == n2nd)
3559 6 : return pRet;
3560 : }
3561 : // increment pointer so that it points to next SPRM
3562 93 : sal_uInt16 x = maSprmParser.GetSprmSize(nAktId, pSp);
3563 93 : i = i + x;
3564 93 : pSp += x;
3565 : }
3566 :
3567 0 : return 0; // Sprm not found
3568 : }
3569 :
3570 219 : WW8PLCFx_SubDoc::WW8PLCFx_SubDoc(SvStream* pSt, ww::WordVersion eVersion,
3571 : WW8_CP nStartCp, long nFcRef, long nLenRef, long nFcTxt, long nLenTxt,
3572 : long nStruct)
3573 219 : : WW8PLCFx(eVersion, true), pRef(0), pTxt(0)
3574 : {
3575 219 : if( nLenRef && nLenTxt )
3576 : {
3577 7 : pRef = new WW8PLCF(*pSt, nFcRef, nLenRef, nStruct, nStartCp);
3578 7 : pTxt = new WW8PLCF(*pSt, nFcTxt, nLenTxt, 0, nStartCp);
3579 : }
3580 219 : }
3581 :
3582 657 : WW8PLCFx_SubDoc::~WW8PLCFx_SubDoc()
3583 : {
3584 219 : delete pRef;
3585 219 : delete pTxt;
3586 438 : }
3587 :
3588 351 : sal_uLong WW8PLCFx_SubDoc::GetIdx() const
3589 : {
3590 : // Probably pTxt ... no need for it
3591 351 : if( pRef )
3592 32 : return ( pRef->GetIdx() << 16 | pTxt->GetIdx() );
3593 319 : return 0;
3594 : }
3595 :
3596 336 : void WW8PLCFx_SubDoc::SetIdx( sal_uLong nIdx )
3597 : {
3598 336 : if( pRef )
3599 : {
3600 17 : pRef->SetIdx( nIdx >> 16 );
3601 : // Probably pTxt ... no need for it
3602 17 : pTxt->SetIdx( nIdx & 0xFFFF );
3603 : }
3604 336 : }
3605 :
3606 672 : bool WW8PLCFx_SubDoc::SeekPos( WW8_CP nCpPos )
3607 : {
3608 672 : return ( pRef ) ? pRef->SeekPos( nCpPos ) : false;
3609 : }
3610 :
3611 0 : WW8_CP WW8PLCFx_SubDoc::Where()
3612 : {
3613 0 : return ( pRef ) ? pRef->Where() : WW8_CP_MAX;
3614 : }
3615 :
3616 922 : void WW8PLCFx_SubDoc::GetSprms(WW8PLCFxDesc* p)
3617 : {
3618 922 : p->nStartPos = p->nEndPos = WW8_CP_MAX;
3619 922 : p->pMemPos = 0;
3620 922 : p->nSprmsLen = 0;
3621 922 : p->bRealLineEnd = false;
3622 :
3623 922 : if (!pRef)
3624 1737 : return;
3625 :
3626 57 : sal_uLong nNr = pRef->GetIdx();
3627 :
3628 : void *pData;
3629 : WW8_CP nFoo;
3630 57 : if (!pRef->Get(p->nStartPos, nFoo, pData))
3631 : {
3632 7 : p->nEndPos = p->nStartPos = WW8_CP_MAX;
3633 7 : return;
3634 : }
3635 :
3636 50 : p->nEndPos = p->nStartPos + 1;
3637 :
3638 50 : if (!pTxt)
3639 0 : return;
3640 :
3641 50 : pTxt->SetIdx(nNr);
3642 :
3643 50 : if (!pTxt->Get(p->nCp2OrIdx, p->nSprmsLen, pData))
3644 : {
3645 0 : p->nEndPos = p->nStartPos = WW8_CP_MAX;
3646 0 : p->nSprmsLen = 0;
3647 0 : return;
3648 : }
3649 :
3650 50 : p->nSprmsLen -= p->nCp2OrIdx;
3651 : }
3652 :
3653 16 : void WW8PLCFx_SubDoc::advance()
3654 : {
3655 16 : if (pRef && pTxt)
3656 : {
3657 16 : pRef->advance();
3658 16 : pTxt->advance();
3659 : }
3660 16 : }
3661 :
3662 : // fields
3663 511 : WW8PLCFx_FLD::WW8PLCFx_FLD( SvStream* pSt, const WW8Fib& rMyFib, short nType)
3664 511 : : WW8PLCFx(rMyFib.GetFIBVersion(), true), pPLCF(0), rFib(rMyFib)
3665 : {
3666 : long nFc, nLen;
3667 :
3668 511 : switch( nType )
3669 : {
3670 : case MAN_HDFT:
3671 73 : nFc = rFib.fcPlcffldHdr;
3672 73 : nLen = rFib.lcbPlcffldHdr;
3673 73 : break;
3674 : case MAN_FTN:
3675 73 : nFc = rFib.fcPlcffldFtn;
3676 73 : nLen = rFib.lcbPlcffldFtn;
3677 73 : break;
3678 : case MAN_EDN:
3679 73 : nFc = rFib.fcPlcffldEdn;
3680 73 : nLen = rFib.lcbPlcffldEdn;
3681 73 : break;
3682 : case MAN_AND:
3683 73 : nFc = rFib.fcPlcffldAtn;
3684 73 : nLen = rFib.lcbPlcffldAtn;
3685 73 : break;
3686 : case MAN_TXBX:
3687 73 : nFc = rFib.fcPlcffldTxbx;
3688 73 : nLen = rFib.lcbPlcffldTxbx;
3689 73 : break;
3690 : case MAN_TXBX_HDFT:
3691 73 : nFc = rFib.fcPlcffldHdrTxbx;
3692 73 : nLen = rFib.lcbPlcffldHdrTxbx;
3693 73 : break;
3694 : default:
3695 73 : nFc = rFib.fcPlcffldMom;
3696 73 : nLen = rFib.lcbPlcffldMom;
3697 73 : break;
3698 : }
3699 :
3700 511 : if( nLen )
3701 23 : pPLCF = new WW8PLCFspecial( pSt, nFc, nLen, 2 );
3702 511 : }
3703 :
3704 1533 : WW8PLCFx_FLD::~WW8PLCFx_FLD()
3705 : {
3706 511 : delete pPLCF;
3707 1022 : }
3708 :
3709 112 : sal_uLong WW8PLCFx_FLD::GetIdx() const
3710 : {
3711 112 : return pPLCF ? pPLCF->GetIdx() : 0;
3712 : }
3713 :
3714 112 : void WW8PLCFx_FLD::SetIdx( sal_uLong nIdx )
3715 : {
3716 112 : if( pPLCF )
3717 13 : pPLCF->SetIdx( nIdx );
3718 112 : }
3719 :
3720 441 : bool WW8PLCFx_FLD::SeekPos(WW8_CP nCpPos)
3721 : {
3722 441 : return pPLCF ? pPLCF->SeekPosExact( nCpPos ) : false;
3723 : }
3724 :
3725 0 : WW8_CP WW8PLCFx_FLD::Where()
3726 : {
3727 0 : return pPLCF ? pPLCF->Where() : WW8_CP_MAX;
3728 : }
3729 :
3730 57 : bool WW8PLCFx_FLD::StartPosIsFieldStart()
3731 : {
3732 : void* pData;
3733 : sal_Int32 nTest;
3734 57 : if (
3735 114 : (!pPLCF || !pPLCF->Get(nTest, pData) ||
3736 57 : ((((sal_uInt8*)pData)[0] & 0x1f) != 0x13))
3737 : )
3738 31 : return false;
3739 26 : return true;
3740 : }
3741 :
3742 57 : bool WW8PLCFx_FLD::EndPosIsFieldEnd(WW8_CP& nCP)
3743 : {
3744 57 : bool bRet = false;
3745 :
3746 57 : if (pPLCF)
3747 : {
3748 57 : long n = pPLCF->GetIdx();
3749 :
3750 57 : pPLCF->advance();
3751 :
3752 : void* pData;
3753 : sal_Int32 nTest;
3754 57 : if ( pPLCF->Get(nTest, pData) && ((((sal_uInt8*)pData)[0] & 0x1f) == 0x15) )
3755 : {
3756 26 : nCP = nTest;
3757 26 : bRet = true;
3758 : }
3759 :
3760 57 : pPLCF->SetIdx(n);
3761 : }
3762 :
3763 57 : return bRet;
3764 : }
3765 :
3766 571 : void WW8PLCFx_FLD::GetSprms(WW8PLCFxDesc* p)
3767 : {
3768 571 : p->nStartPos = p->nEndPos = WW8_CP_MAX;
3769 571 : p->pMemPos = 0;
3770 571 : p->nSprmsLen = 0;
3771 571 : p->bRealLineEnd = false;
3772 :
3773 571 : if (!pPLCF)
3774 : {
3775 404 : p->nStartPos = WW8_CP_MAX; // there are no fields
3776 877 : return;
3777 : }
3778 :
3779 167 : long n = pPLCF->GetIdx();
3780 :
3781 : sal_Int32 nP;
3782 : void *pData;
3783 167 : if (!pPLCF->Get(nP, pData)) // end of PLCFspecial?
3784 : {
3785 52 : p->nStartPos = WW8_CP_MAX; // PLCF completely processed
3786 52 : return;
3787 : }
3788 :
3789 115 : p->nStartPos = nP;
3790 :
3791 115 : pPLCF->advance();
3792 115 : if (!pPLCF->Get(nP, pData)) // end of PLCFspecial?
3793 : {
3794 17 : p->nStartPos = WW8_CP_MAX; // PLCF completely processed
3795 17 : return;
3796 : }
3797 :
3798 98 : p->nEndPos = nP;
3799 :
3800 98 : pPLCF->SetIdx(n);
3801 :
3802 98 : p->nCp2OrIdx = pPLCF->GetIdx();
3803 : }
3804 :
3805 57 : void WW8PLCFx_FLD::advance()
3806 : {
3807 57 : pPLCF->advance();
3808 57 : }
3809 :
3810 26 : bool WW8PLCFx_FLD::GetPara(long nIdx, WW8FieldDesc& rF)
3811 : {
3812 : OSL_ENSURE( pPLCF, "Call without PLCFspecial field" );
3813 26 : if( !pPLCF )
3814 0 : return false;
3815 :
3816 26 : long n = pPLCF->GetIdx();
3817 26 : pPLCF->SetIdx(nIdx);
3818 :
3819 26 : bool bOk = WW8GetFieldPara(*pPLCF, rF);
3820 :
3821 26 : pPLCF->SetIdx(n);
3822 26 : return bOk;
3823 : }
3824 :
3825 : // WW8PLCF_Book
3826 :
3827 : /* to be optimized like this: */
3828 202 : void WW8ReadSTTBF(bool bVer8, SvStream& rStrm, sal_uInt32 nStart, sal_Int32 nLen,
3829 : sal_uInt16 nExtraLen, rtl_TextEncoding eCS, std::vector<OUString> &rArray,
3830 : std::vector<ww::bytes>* pExtraArray, ::std::vector<OUString>* pValueArray)
3831 : {
3832 202 : if (nLen==0) // Handle Empty STTBF
3833 348 : return;
3834 :
3835 56 : sal_Size nOldPos = rStrm.Tell();
3836 56 : if (checkSeek(rStrm, nStart))
3837 : {
3838 56 : sal_uInt16 nLen2(0);
3839 56 : rStrm.ReadUInt16( nLen2 ); // bVer67: total length of structure
3840 : // bVer8 : count of strings
3841 :
3842 56 : if( bVer8 )
3843 : {
3844 56 : sal_uInt16 nStrings(0);
3845 56 : bool bUnicode = (0xFFFF == nLen2);
3846 56 : if (bUnicode)
3847 55 : rStrm.ReadUInt16( nStrings );
3848 : else
3849 1 : nStrings = nLen2;
3850 :
3851 56 : rStrm.ReadUInt16( nExtraLen );
3852 :
3853 16769 : for (sal_uInt16 i=0; i < nStrings; ++i)
3854 : {
3855 16713 : if (bUnicode)
3856 73 : rArray.push_back(read_uInt16_PascalString(rStrm));
3857 : else
3858 : {
3859 16640 : OString aTmp = read_uInt8_lenPrefixed_uInt8s_ToOString(rStrm);
3860 16640 : rArray.push_back(OStringToOUString(aTmp, eCS));
3861 : }
3862 :
3863 : // Skip the extra data
3864 16713 : if (nExtraLen)
3865 : {
3866 12 : if (pExtraArray)
3867 : {
3868 12 : ww::bytes extraData;
3869 132 : for (sal_uInt16 j = 0; j < nExtraLen; ++j)
3870 : {
3871 120 : sal_uInt8 iTmp(0);
3872 120 : rStrm.ReadUChar( iTmp );
3873 120 : extraData.push_back(iTmp);
3874 : }
3875 12 : pExtraArray->push_back(extraData);
3876 : }
3877 : else
3878 0 : rStrm.SeekRel( nExtraLen );
3879 : }
3880 : }
3881 : // read the value of the document variables, if requested.
3882 56 : if (pValueArray)
3883 : {
3884 0 : for (sal_uInt16 i=0; i < nStrings; ++i)
3885 : {
3886 0 : if( bUnicode )
3887 0 : pValueArray->push_back(read_uInt16_PascalString(rStrm));
3888 : else
3889 : {
3890 0 : OString aTmp = read_uInt8_lenPrefixed_uInt8s_ToOString(rStrm);
3891 0 : pValueArray->push_back(OStringToOUString(aTmp, eCS));
3892 : }
3893 : }
3894 : }
3895 : }
3896 : else
3897 : {
3898 0 : if( nLen2 != nLen )
3899 : {
3900 : OSL_ENSURE(nLen2 == nLen,
3901 : "Fib length and read length are different");
3902 0 : if (nLen > USHRT_MAX)
3903 0 : nLen = USHRT_MAX;
3904 0 : else if (nLen < 2 )
3905 0 : nLen = 2;
3906 0 : nLen2 = static_cast<sal_uInt16>(nLen);
3907 : }
3908 0 : sal_uLong nRead = 0;
3909 0 : for( nLen2 -= 2; nRead < nLen2; )
3910 : {
3911 0 : sal_uInt8 nBChar(0);
3912 0 : rStrm.ReadUChar( nBChar );
3913 0 : ++nRead;
3914 0 : if (nBChar)
3915 : {
3916 0 : OString aTmp = read_uInt8s_ToOString(rStrm, nBChar);
3917 0 : nRead += aTmp.getLength();
3918 0 : rArray.push_back(OStringToOUString(aTmp, eCS));
3919 : }
3920 : else
3921 0 : rArray.push_back(OUString());
3922 :
3923 : // Skip the extra data (for bVer67 versions this must come from
3924 : // external knowledge)
3925 0 : if (nExtraLen)
3926 : {
3927 0 : if (pExtraArray)
3928 : {
3929 0 : ww::bytes extraData;
3930 0 : for (sal_uInt16 i=0;i < nExtraLen;++i)
3931 : {
3932 0 : sal_uInt8 iTmp(0);
3933 0 : rStrm.ReadUChar( iTmp );
3934 0 : extraData.push_back(iTmp);
3935 : }
3936 0 : pExtraArray->push_back(extraData);
3937 : }
3938 : else
3939 0 : rStrm.SeekRel( nExtraLen );
3940 0 : nRead+=nExtraLen;
3941 : }
3942 : }
3943 : }
3944 : }
3945 56 : rStrm.Seek(nOldPos);
3946 : }
3947 :
3948 73 : WW8PLCFx_Book::WW8PLCFx_Book(SvStream* pTblSt, const WW8Fib& rFib)
3949 73 : : WW8PLCFx(rFib.GetFIBVersion(), false), pStatus(0), nIsEnd(0), nBookmarkId(1)
3950 : {
3951 78 : if( !rFib.fcPlcfbkf || !rFib.lcbPlcfbkf || !rFib.fcPlcfbkl ||
3952 10 : !rFib.lcbPlcfbkl || !rFib.fcSttbfbkmk || !rFib.lcbSttbfbkmk )
3953 : {
3954 68 : pBook[0] = pBook[1] = 0;
3955 68 : nIMax = 0;
3956 : }
3957 : else
3958 : {
3959 5 : pBook[0] = new WW8PLCFspecial(pTblSt,rFib.fcPlcfbkf,rFib.lcbPlcfbkf,4);
3960 :
3961 5 : pBook[1] = new WW8PLCFspecial(pTblSt,rFib.fcPlcfbkl,rFib.lcbPlcfbkl,0);
3962 :
3963 5 : rtl_TextEncoding eStructChrSet = WW8Fib::GetFIBCharset(rFib.chseTables);
3964 :
3965 : WW8ReadSTTBF( (7 < rFib.nVersion), *pTblSt, rFib.fcSttbfbkmk,
3966 5 : rFib.lcbSttbfbkmk, 0, eStructChrSet, aBookNames );
3967 :
3968 5 : nIMax = aBookNames.size();
3969 :
3970 5 : if( pBook[0]->GetIMax() < nIMax ) // Count of Bookmarks
3971 0 : nIMax = pBook[0]->GetIMax();
3972 5 : if( pBook[1]->GetIMax() < nIMax )
3973 0 : nIMax = pBook[1]->GetIMax();
3974 5 : pStatus = new eBookStatus[ nIMax ];
3975 5 : memset( pStatus, 0, nIMax * sizeof( eBookStatus ) );
3976 : }
3977 73 : }
3978 :
3979 219 : WW8PLCFx_Book::~WW8PLCFx_Book()
3980 : {
3981 73 : delete[] pStatus;
3982 73 : delete pBook[1];
3983 73 : delete pBook[0];
3984 146 : }
3985 :
3986 112 : sal_uLong WW8PLCFx_Book::GetIdx() const
3987 : {
3988 112 : return nIMax ? pBook[0]->GetIdx() : 0;
3989 : }
3990 :
3991 112 : void WW8PLCFx_Book::SetIdx( sal_uLong nI )
3992 : {
3993 112 : if( nIMax )
3994 11 : pBook[0]->SetIdx( nI );
3995 112 : }
3996 :
3997 112 : sal_uLong WW8PLCFx_Book::GetIdx2() const
3998 : {
3999 112 : return nIMax ? ( pBook[1]->GetIdx() | ( ( nIsEnd ) ? 0x80000000 : 0 ) ) : 0;
4000 : }
4001 :
4002 112 : void WW8PLCFx_Book::SetIdx2( sal_uLong nI )
4003 : {
4004 112 : if( nIMax )
4005 : {
4006 11 : pBook[1]->SetIdx( nI & 0x7fffffff );
4007 11 : nIsEnd = (sal_uInt16)( ( nI >> 31 ) & 1 ); // 0 oder 1
4008 : }
4009 112 : }
4010 :
4011 217 : bool WW8PLCFx_Book::SeekPos(WW8_CP nCpPos)
4012 : {
4013 217 : if( !pBook[0] )
4014 205 : return false;
4015 :
4016 12 : bool bOk = pBook[0]->SeekPosExact( nCpPos );
4017 12 : bOk &= pBook[1]->SeekPosExact( nCpPos );
4018 12 : nIsEnd = 0;
4019 :
4020 12 : return bOk;
4021 : }
4022 :
4023 0 : WW8_CP WW8PLCFx_Book::Where()
4024 : {
4025 0 : return pBook[nIsEnd]->Where();
4026 : }
4027 :
4028 324 : long WW8PLCFx_Book::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
4029 : {
4030 : void* pData;
4031 324 : rEnd = WW8_CP_MAX;
4032 324 : rLen = 0;
4033 :
4034 324 : if (!pBook[0] || !pBook[1] || !nIMax || (pBook[nIsEnd]->GetIdx()) >= nIMax)
4035 : {
4036 290 : rStart = rEnd = WW8_CP_MAX;
4037 290 : return -1;
4038 : }
4039 :
4040 34 : pBook[nIsEnd]->Get( rStart, pData ); // query position
4041 34 : return pBook[nIsEnd]->GetIdx();
4042 : }
4043 :
4044 : // Der Operator ++ hat eine Tuecke: Wenn 2 Bookmarks aneinandergrenzen, dann
4045 : // sollte erst das Ende des ersten und dann der Anfang des 2. erreicht werden.
4046 : // Liegen jedoch 2 Bookmarks der Laenge 0 aufeinander, *muss* von jedem Bookmark
4047 : // erst der Anfang und dann das Ende gefunden werden.
4048 : // Der Fall: ][
4049 : // [...]
4050 : // ][
4051 : // ist noch nicht geloest, dabei muesste ich in den Anfangs- und Endindices
4052 : // vor- und zurueckspringen, wobei ein weiterer Index oder ein Bitfeld
4053 : // oder etwas aehnliches zum Merken der bereits abgearbeiteten Bookmarks
4054 : // noetig wird.
4055 34 : void WW8PLCFx_Book::advance()
4056 : {
4057 34 : if( pBook[0] && pBook[1] && nIMax )
4058 : {
4059 34 : (*pBook[nIsEnd]).advance();
4060 :
4061 34 : sal_uLong l0 = pBook[0]->Where();
4062 34 : sal_uLong l1 = pBook[1]->Where();
4063 34 : if( l0 < l1 )
4064 7 : nIsEnd = 0;
4065 27 : else if( l1 < l0 )
4066 16 : nIsEnd = 1;
4067 : else
4068 : {
4069 11 : const void * p = pBook[0]->GetData(pBook[0]->GetIdx());
4070 11 : long nPairFor = (p == NULL)? 0L : SVBT16ToShort(*((SVBT16*) p));
4071 11 : if (nPairFor == pBook[1]->GetIdx())
4072 5 : nIsEnd = 0;
4073 : else
4074 6 : nIsEnd = ( nIsEnd ) ? 0 : 1;
4075 : }
4076 : }
4077 34 : }
4078 :
4079 0 : long WW8PLCFx_Book::GetLen() const
4080 : {
4081 0 : if( nIsEnd )
4082 : {
4083 : OSL_ENSURE( !this, "Incorrect call (1) of PLCF_Book::GetLen()" );
4084 0 : return 0;
4085 : }
4086 : void * p;
4087 : WW8_CP nStartPos;
4088 0 : if( !pBook[0]->Get( nStartPos, p ) )
4089 : {
4090 : OSL_ENSURE( !this, "Incorrect call (2) of PLCF_Book::GetLen()" );
4091 0 : return 0;
4092 : }
4093 0 : sal_uInt16 nEndIdx = SVBT16ToShort( *((SVBT16*)p) );
4094 0 : long nNum = pBook[1]->GetPos( nEndIdx );
4095 0 : nNum -= nStartPos;
4096 0 : return nNum;
4097 : }
4098 :
4099 0 : void WW8PLCFx_Book::SetStatus(sal_uInt16 nIndex, eBookStatus eStat )
4100 : {
4101 : OSL_ENSURE(nIndex < nIMax, "set status of non existing bookmark!");
4102 0 : pStatus[nIndex] = (eBookStatus)( pStatus[nIndex] | eStat );
4103 0 : }
4104 :
4105 34 : eBookStatus WW8PLCFx_Book::GetStatus() const
4106 : {
4107 34 : if( !pStatus )
4108 0 : return BOOK_NORMAL;
4109 34 : long nEndIdx = GetHandle();
4110 34 : return ( nEndIdx < nIMax ) ? pStatus[nEndIdx] : BOOK_NORMAL;
4111 : }
4112 :
4113 68 : long WW8PLCFx_Book::GetHandle() const
4114 : {
4115 68 : if( !pBook[0] || !pBook[1] )
4116 0 : return LONG_MAX;
4117 :
4118 68 : if( nIsEnd )
4119 34 : return pBook[1]->GetIdx();
4120 : else
4121 : {
4122 34 : if (const void* p = pBook[0]->GetData(pBook[0]->GetIdx()))
4123 34 : return SVBT16ToShort( *((SVBT16*)p) );
4124 : else
4125 0 : return LONG_MAX;
4126 : }
4127 : }
4128 :
4129 1 : OUString WW8PLCFx_Book::GetBookmark(long nStart,long nEnd, sal_uInt16 &nIndex)
4130 : {
4131 1 : bool bFound = false;
4132 1 : sal_uInt16 i = 0;
4133 1 : if( pBook[0] && pBook[1] )
4134 : {
4135 : WW8_CP nStartAkt, nEndAkt;
4136 0 : do
4137 : {
4138 : void* p;
4139 : sal_uInt16 nEndIdx;
4140 :
4141 0 : if( pBook[0]->GetData( i, nStartAkt, p ) && p )
4142 0 : nEndIdx = SVBT16ToShort( *((SVBT16*)p) );
4143 : else
4144 : {
4145 : OSL_ENSURE( !this, "Bookmark-EndIdx not readable" );
4146 0 : nEndIdx = i;
4147 : }
4148 :
4149 0 : nEndAkt = pBook[1]->GetPos( nEndIdx );
4150 :
4151 0 : if ((nStartAkt >= nStart) && (nEndAkt <= nEnd))
4152 : {
4153 0 : nIndex = i;
4154 0 : bFound=true;
4155 0 : break;
4156 : }
4157 0 : ++i;
4158 : }
4159 0 : while (i < pBook[0]->GetIMax());
4160 : }
4161 1 : return bFound ? aBookNames[i] : OUString();
4162 : }
4163 :
4164 1 : OUString WW8PLCFx_Book::GetUniqueBookmarkName(const OUString &rSuggestedName)
4165 : {
4166 1 : OUString aRet(rSuggestedName.isEmpty() ? OUString("Unnamed") : rSuggestedName);
4167 1 : size_t i = 0;
4168 2 : while (i < aBookNames.size())
4169 : {
4170 0 : if (aRet.equals(aBookNames[i]))
4171 : {
4172 0 : sal_Int32 len = aRet.getLength();
4173 0 : sal_Int32 p = len - 1;
4174 0 : while (p > 0 && aRet[p] >= '0' && aRet[p] <= '9')
4175 0 : --p;
4176 0 : aRet = aRet.copy(0, p+1) + OUString::number(nBookmarkId++);
4177 0 : i = 0; // start search from beginning
4178 : }
4179 : else
4180 0 : ++i;
4181 : }
4182 1 : return aRet;
4183 : }
4184 :
4185 1 : bool WW8PLCFx_Book::MapName(OUString& rName)
4186 : {
4187 1 : if( !pBook[0] || !pBook[1] )
4188 0 : return false;
4189 :
4190 1 : bool bFound = false;
4191 1 : sal_uInt16 i = 0;
4192 1 : do
4193 : {
4194 1 : if (rName.equalsIgnoreAsciiCase(aBookNames[i]))
4195 : {
4196 1 : rName = aBookNames[i];
4197 1 : bFound = true;
4198 : }
4199 1 : ++i;
4200 : }
4201 1 : while (!bFound && i < pBook[0]->GetIMax());
4202 1 : return bFound;
4203 : }
4204 :
4205 17 : const OUString* WW8PLCFx_Book::GetName() const
4206 : {
4207 17 : const OUString *pRet = 0;
4208 17 : if (!nIsEnd && (pBook[0]->GetIdx() < nIMax))
4209 17 : pRet = &(aBookNames[pBook[0]->GetIdx()]);
4210 17 : return pRet;
4211 : }
4212 :
4213 : #ifndef DUMP
4214 :
4215 : // Am Ende eines Absatzes reichen bei WW6 die Attribute bis hinter das <CR>.
4216 : // Das wird fuer die Verwendung mit dem SW um 1 Zeichen zurueckgesetzt, wenn
4217 : // dadurch kein AErger zu erwarten ist.
4218 19714 : void WW8PLCFMan::AdjustEnds( WW8PLCFxDesc& rDesc )
4219 : {
4220 : //Store old end position for supercool new property finder that uses
4221 : //cp instead of fc's as nature intended
4222 19714 : rDesc.nOrigEndPos = rDesc.nEndPos;
4223 19714 : rDesc.nOrigStartPos = rDesc.nStartPos;
4224 :
4225 : /*
4226 : Normally given ^XXX{para end}^ we don't actually insert a para end
4227 : character into the document, so we clip the para end property one to the
4228 : left to make the para properties end when the paragraph text does. In a
4229 : drawing textbox we actually do insert a para end character, so we don't
4230 : clip it. Making the para end properties end after the para end char.
4231 : */
4232 19714 : if (GetDoingDrawTextBox())
4233 20315 : return;
4234 :
4235 19113 : if ( (&rDesc == pPap) && rDesc.bRealLineEnd )
4236 : {
4237 8016 : if ( pPap->nEndPos != WW8_CP_MAX ) // Para adjust
4238 : {
4239 3974 : nLineEnd = pPap->nEndPos;// nLineEnd zeigt *hinter* das <CR>
4240 3974 : pPap->nEndPos--; // Absatzende um 1 Zeichen verkuerzen
4241 :
4242 : // gibt es bereits ein CharAttr-Ende das auf das jetzige
4243 : // Absatzende zeigt ? ... dann auch um 1 Zeichen verkuerzen
4244 3974 : if (pChp->nEndPos == nLineEnd)
4245 756 : pChp->nEndPos--;
4246 :
4247 : // gibt es bereits ein Sep-Ende, das auf das jetzige Absatzende
4248 : // zeigt ? ... dann auch um 1 Zeichen verkuerzen
4249 3974 : if( pSep->nEndPos == nLineEnd )
4250 29 : pSep->nEndPos--;
4251 : }
4252 : }
4253 15105 : else if ( (&rDesc == pChp) || (&rDesc == pSep) )
4254 : {
4255 : // Char Adjust oder Sep Adjust Wenn Ende Char-Attr == Absatzende ...
4256 3974 : if( (rDesc.nEndPos == nLineEnd) && (rDesc.nEndPos > rDesc.nStartPos) )
4257 913 : rDesc.nEndPos--; // ... dann um 1 Zeichen verkuerzen
4258 : }
4259 : }
4260 :
4261 30857 : void WW8PLCFxDesc::ReduceByOffset()
4262 : {
4263 : OSL_ENSURE((WW8_CP_MAX == nStartPos) || (nStartPos <= nEndPos),
4264 : "Attr-Anfang und -Ende ueber Kreuz" );
4265 :
4266 30857 : if( nStartPos != WW8_CP_MAX )
4267 : {
4268 : /*
4269 : ##516##,##517##
4270 : Force the property change to happen at the beginning of this
4271 : subdocument, same as in GetNewNoSprms, except that the target type is
4272 : attributes attached to a piece that might span subdocument boundaries
4273 : */
4274 29190 : if (nCpOfs > nStartPos)
4275 1307 : nStartPos = 0;
4276 : else
4277 27883 : nStartPos -= nCpOfs;
4278 : }
4279 30857 : if( nEndPos != WW8_CP_MAX )
4280 : {
4281 : OSL_ENSURE(nCpOfs <= nEndPos,
4282 : "oh oh, so much for the subdocument piece theory");
4283 28980 : nEndPos -= nCpOfs;
4284 : }
4285 30857 : }
4286 :
4287 19714 : void WW8PLCFMan::GetNewSprms( WW8PLCFxDesc& rDesc )
4288 : {
4289 19714 : rDesc.pPLCFx->GetSprms(&rDesc);
4290 19714 : rDesc.ReduceByOffset();
4291 :
4292 19714 : rDesc.bFirstSprm = true;
4293 19714 : AdjustEnds( rDesc );
4294 19714 : rDesc.nOrigSprmsLen = rDesc.nSprmsLen;
4295 19714 : }
4296 :
4297 5906 : void WW8PLCFMan::GetNewNoSprms( WW8PLCFxDesc& rDesc )
4298 : {
4299 : rDesc.nCp2OrIdx = rDesc.pPLCFx->GetNoSprms(rDesc.nStartPos, rDesc.nEndPos,
4300 5906 : rDesc.nSprmsLen);
4301 :
4302 : OSL_ENSURE((WW8_CP_MAX == rDesc.nStartPos) || (rDesc.nStartPos <= rDesc.nEndPos),
4303 : "Attr-Anfang und -Ende ueber Kreuz" );
4304 :
4305 5906 : rDesc.ReduceByOffset();
4306 :
4307 5906 : rDesc.bFirstSprm = true;
4308 5906 : rDesc.nOrigSprmsLen = rDesc.nSprmsLen;
4309 5906 : }
4310 :
4311 92622 : sal_uInt16 WW8PLCFMan::GetId(const WW8PLCFxDesc* p) const
4312 : {
4313 92622 : sal_uInt16 nId = 0; // Id = 0 for empty attributes
4314 :
4315 92622 : if (p == pFld)
4316 122 : nId = eFLD;
4317 92500 : else if (p == pFtn)
4318 2 : nId = eFTN;
4319 92498 : else if (p == pEdn)
4320 0 : nId = eEDN;
4321 92498 : else if (p == pAnd)
4322 30 : nId = eAND;
4323 92468 : else if (p->nSprmsLen >= maSprmParser.MinSprmLen())
4324 77660 : nId = maSprmParser.GetSprmId(p->pMemPos);
4325 :
4326 92622 : return nId;
4327 : }
4328 :
4329 290 : WW8PLCFMan::WW8PLCFMan(WW8ScannerBase* pBase, ManTypes nType, long nStartCp,
4330 : bool bDoingDrawTextBox)
4331 : : maSprmParser(pBase->pWw8Fib->GetFIBVersion()),
4332 290 : mbDoingDrawTextBox(bDoingDrawTextBox)
4333 : {
4334 290 : pWwFib = pBase->pWw8Fib;
4335 :
4336 290 : nLastWhereIdxCp = 0;
4337 290 : memset( aD, 0, sizeof( aD ) );
4338 290 : nLineEnd = WW8_CP_MAX;
4339 290 : nManType = nType;
4340 : sal_uInt16 i;
4341 :
4342 290 : if( MAN_MAINTEXT == nType )
4343 : {
4344 : // Suchreihenfolge der Attribute
4345 78 : nPLCF = MAN_ANZ_PLCF;
4346 78 : pFld = &aD[0];
4347 78 : pBkm = &aD[1];
4348 78 : pEdn = &aD[2];
4349 78 : pFtn = &aD[3];
4350 78 : pAnd = &aD[4];
4351 :
4352 78 : pPcd = ( pBase->pPLCFx_PCD ) ? &aD[5] : 0;
4353 : //pPcdA index == pPcd index + 1
4354 78 : pPcdA = ( pBase->pPLCFx_PCDAttrs ) ? &aD[6] : 0;
4355 :
4356 78 : pChp = &aD[7];
4357 78 : pPap = &aD[8];
4358 78 : pSep = &aD[9];
4359 :
4360 78 : pSep->pPLCFx = pBase->pSepPLCF;
4361 78 : pFtn->pPLCFx = pBase->pFtnPLCF;
4362 78 : pEdn->pPLCFx = pBase->pEdnPLCF;
4363 78 : pBkm->pPLCFx = pBase->pBook;
4364 78 : pAnd->pPLCFx = pBase->pAndPLCF;
4365 :
4366 : }
4367 : else
4368 : {
4369 : // Suchreihenfolge der Attribute
4370 212 : nPLCF = 7;
4371 212 : pFld = &aD[0];
4372 212 : pBkm = ( pBase->pBook ) ? &aD[1] : 0;
4373 :
4374 212 : pPcd = ( pBase->pPLCFx_PCD ) ? &aD[2] : 0;
4375 : //pPcdA index == pPcd index + 1
4376 212 : pPcdA= ( pBase->pPLCFx_PCDAttrs ) ? &aD[3] : 0;
4377 :
4378 212 : pChp = &aD[4];
4379 212 : pPap = &aD[5];
4380 212 : pSep = &aD[6]; // Dummy
4381 :
4382 212 : pAnd = pFtn = pEdn = 0; // unbenutzt bei SpezText
4383 : }
4384 :
4385 290 : pChp->pPLCFx = pBase->pChpPLCF;
4386 290 : pPap->pPLCFx = pBase->pPapPLCF;
4387 290 : if( pPcd )
4388 286 : pPcd->pPLCFx = pBase->pPLCFx_PCD;
4389 290 : if( pPcdA )
4390 286 : pPcdA->pPLCFx= pBase->pPLCFx_PCDAttrs;
4391 290 : if( pBkm )
4392 290 : pBkm->pPLCFx = pBase->pBook;
4393 :
4394 290 : pMagicTables = pBase->pMagicTables;
4395 290 : pSubdocs = pBase->pSubdocs;
4396 290 : pExtendedAtrds = pBase->pExtendedAtrds;
4397 :
4398 290 : switch( nType ) // Feld-Initialisierung
4399 : {
4400 : case MAN_HDFT:
4401 118 : pFld->pPLCFx = pBase->pFldHdFtPLCF;
4402 118 : pFdoa = pBase->pHdFtFdoa;
4403 118 : pTxbx = pBase->pHdFtTxbx;
4404 118 : pTxbxBkd = pBase->pHdFtTxbxBkd;
4405 118 : break;
4406 : case MAN_FTN:
4407 1 : pFld->pPLCFx = pBase->pFldFtnPLCF;
4408 1 : pFdoa = pTxbx = pTxbxBkd = 0;
4409 1 : break;
4410 : case MAN_EDN:
4411 0 : pFld->pPLCFx = pBase->pFldEdnPLCF;
4412 0 : pFdoa = pTxbx = pTxbxBkd = 0;
4413 0 : break;
4414 : case MAN_AND:
4415 15 : pFld->pPLCFx = pBase->pFldAndPLCF;
4416 15 : pFdoa = pTxbx = pTxbxBkd = 0;
4417 15 : break;
4418 : case MAN_TXBX:
4419 78 : pFld->pPLCFx = pBase->pFldTxbxPLCF;
4420 78 : pTxbx = pBase->pMainTxbx;
4421 78 : pTxbxBkd = pBase->pMainTxbxBkd;
4422 78 : pFdoa = 0;
4423 78 : break;
4424 : case MAN_TXBX_HDFT:
4425 0 : pFld->pPLCFx = pBase->pFldTxbxHdFtPLCF;
4426 0 : pTxbx = pBase->pHdFtTxbx;
4427 0 : pTxbxBkd = pBase->pHdFtTxbxBkd;
4428 0 : pFdoa = 0;
4429 0 : break;
4430 : default:
4431 78 : pFld->pPLCFx = pBase->pFldPLCF;
4432 78 : pFdoa = pBase->pMainFdoa;
4433 78 : pTxbx = pBase->pMainTxbx;
4434 78 : pTxbxBkd = pBase->pMainTxbxBkd;
4435 78 : break;
4436 : }
4437 :
4438 290 : nCpO = pWwFib->GetBaseCp(nType);
4439 :
4440 290 : if( nStartCp || nCpO )
4441 217 : SeekPos( nStartCp ); // PLCFe auf Text-StartPos einstellen
4442 :
4443 : // initialisieren der Member-Vars Low-Level
4444 290 : GetChpPLCF()->ResetAttrStartEnd();
4445 290 : GetPapPLCF()->ResetAttrStartEnd();
4446 2554 : for( i=0; i < nPLCF; i++)
4447 : {
4448 2264 : WW8PLCFxDesc* p = &aD[i];
4449 :
4450 : /*
4451 : ##516##,##517##
4452 : For subdocuments we modify the cp of properties to be relative to
4453 : the beginning of subdocuments, we should also do the same for
4454 : piecetable changes, and piecetable properties, otherwise a piece
4455 : change that happens in a subdocument is lost.
4456 : */
4457 5346 : p->nCpOfs = ( p == pChp || p == pPap || p == pBkm || p == pPcd ||
4458 4814 : p == pPcdA ) ? nCpO : 0;
4459 :
4460 2264 : p->nCp2OrIdx = 0;
4461 2264 : p->bFirstSprm = false;
4462 2264 : p->pIdStk = 0;
4463 :
4464 2264 : if ((p == pChp) || (p == pPap))
4465 580 : p->nStartPos = p->nEndPos = nStartCp;
4466 : else
4467 1684 : p->nStartPos = p->nEndPos = WW8_CP_MAX;
4468 : }
4469 :
4470 : // initialisieren der Member-Vars High-Level
4471 2554 : for( i=0; i<nPLCF; i++){
4472 2264 : WW8PLCFxDesc* p = &aD[i];
4473 :
4474 2264 : if( !p->pPLCFx )
4475 : {
4476 220 : p->nStartPos = p->nEndPos = WW8_CP_MAX;
4477 220 : continue;
4478 : }
4479 :
4480 2044 : if( p->pPLCFx->IsSprm() )
4481 : {
4482 : // Vorsicht: nEndPos muss bereits
4483 1468 : p->pIdStk = new std::stack<sal_uInt16>;
4484 1468 : if ((p == pChp) || (p == pPap))
4485 : {
4486 580 : WW8_CP nTemp = p->nEndPos+p->nCpOfs;
4487 580 : p->pMemPos = 0;
4488 580 : p->nSprmsLen = 0;
4489 580 : p->nStartPos = nTemp;
4490 580 : if (!(*p->pPLCFx).SeekPos(p->nStartPos))
4491 2 : p->nEndPos = p->nStartPos = WW8_CP_MAX;
4492 : else
4493 578 : GetNewSprms( *p );
4494 : }
4495 : else
4496 888 : GetNewSprms( *p ); // bei allen PLCFen initialisiert sein
4497 : }
4498 576 : else if( p->pPLCFx )
4499 576 : GetNewNoSprms( *p );
4500 : }
4501 290 : }
4502 :
4503 290 : WW8PLCFMan::~WW8PLCFMan()
4504 : {
4505 2554 : for( sal_uInt16 i=0; i<nPLCF; i++)
4506 2264 : delete aD[i].pIdStk;
4507 290 : }
4508 :
4509 : // 0. welche Attr.-Klasse,
4510 : // 1. ob ein Attr.-Start ist,
4511 : // 2. CP, wo ist naechste Attr.-Aenderung
4512 270667 : sal_uInt16 WW8PLCFMan::WhereIdx(bool* pbStart, long* pPos) const
4513 : {
4514 : OSL_ENSURE(nPLCF,"What the hell");
4515 270667 : long nNext = LONG_MAX; // SuchReihenfolge:
4516 270667 : sal_uInt16 nNextIdx = nPLCF;// first ending found ( CHP, PAP, ( SEP ) ),
4517 270667 : bool bStart = true; // dann Anfaenge finden ( ( SEP ), PAP, CHP )
4518 : sal_uInt16 i;
4519 : const WW8PLCFxDesc* pD;
4520 2927861 : for (i=0; i < nPLCF; i++)
4521 : {
4522 2657194 : pD = &aD[i];
4523 2657194 : if (pD != pPcdA)
4524 : {
4525 2397344 : if( (pD->nEndPos < nNext) && (pD->nStartPos == WW8_CP_MAX) )
4526 : {
4527 : // sonst ist Anfang = Ende
4528 370235 : nNext = pD->nEndPos;
4529 370235 : nNextIdx = i;
4530 370235 : bStart = false;
4531 : }
4532 : }
4533 : }
4534 2927861 : for (i=nPLCF; i > 0; i--)
4535 : {
4536 2657194 : pD = &aD[i-1];
4537 2657194 : if (pD != pPcdA)
4538 : {
4539 2397344 : if( pD->nStartPos < nNext )
4540 : {
4541 161980 : nNext = pD->nStartPos;
4542 161980 : nNextIdx = i-1;
4543 161980 : bStart = true;
4544 : }
4545 : }
4546 : }
4547 270667 : if( pPos )
4548 90401 : *pPos = nNext;
4549 270667 : if( pbStart )
4550 180266 : *pbStart = bStart;
4551 270667 : return nNextIdx;
4552 : }
4553 :
4554 : // gibt die CP-Pos der naechsten Attribut-Aenderung zurueck
4555 90401 : WW8_CP WW8PLCFMan::Where() const
4556 : {
4557 : long l;
4558 90401 : WhereIdx(0, &l);
4559 90401 : return l;
4560 : }
4561 :
4562 217 : void WW8PLCFMan::SeekPos( long nNewCp )
4563 : {
4564 217 : pChp->pPLCFx->SeekPos( nNewCp + nCpO ); // Attribute neu
4565 217 : pPap->pPLCFx->SeekPos( nNewCp + nCpO ); // aufsetzen
4566 217 : pFld->pPLCFx->SeekPos( nNewCp );
4567 217 : if( pPcd )
4568 215 : pPcd->pPLCFx->SeekPos( nNewCp + nCpO );
4569 217 : if( pBkm )
4570 217 : pBkm->pPLCFx->SeekPos( nNewCp + nCpO );
4571 217 : }
4572 :
4573 112 : void WW8PLCFMan::SaveAllPLCFx( WW8PLCFxSaveAll& rSave ) const
4574 : {
4575 112 : sal_uInt16 i, n=0;
4576 112 : if( pPcd )
4577 112 : pPcd->Save( rSave.aS[n++] );
4578 112 : if( pPcdA )
4579 112 : pPcdA->Save( rSave.aS[n++] );
4580 :
4581 1232 : for(i=0; i<nPLCF; ++i)
4582 1120 : if( pPcd != &aD[i] && pPcdA != &aD[i] )
4583 896 : aD[i].Save( rSave.aS[n++] );
4584 112 : }
4585 :
4586 112 : void WW8PLCFMan::RestoreAllPLCFx( const WW8PLCFxSaveAll& rSave )
4587 : {
4588 112 : sal_uInt16 i, n=0;
4589 112 : if( pPcd )
4590 112 : pPcd->Restore( rSave.aS[n++] );
4591 112 : if( pPcdA )
4592 112 : pPcdA->Restore( rSave.aS[n++] );
4593 :
4594 1232 : for(i=0; i<nPLCF; ++i)
4595 1120 : if( pPcd != &aD[i] && pPcdA != &aD[i] )
4596 896 : aD[i].Restore( rSave.aS[n++] );
4597 112 : }
4598 :
4599 47071 : void WW8PLCFMan::GetSprmStart( short nIdx, WW8PLCFManResult* pRes ) const
4600 : {
4601 47071 : memset( pRes, 0, sizeof( WW8PLCFManResult ) );
4602 :
4603 : // Pruefen !!!
4604 :
4605 47071 : pRes->nMemLen = 0;
4606 :
4607 47071 : const WW8PLCFxDesc* p = &aD[nIdx];
4608 :
4609 : // first Sprm in a Group
4610 47071 : if( p->bFirstSprm )
4611 : {
4612 15056 : if( p == pPap )
4613 5415 : pRes->nFlags |= MAN_MASK_NEW_PAP;
4614 9641 : else if( p == pSep )
4615 87 : pRes->nFlags |= MAN_MASK_NEW_SEP;
4616 : }
4617 47071 : pRes->pMemPos = p->pMemPos;
4618 47071 : pRes->nSprmId = GetId(p);
4619 47071 : pRes->nCp2OrIdx = p->nCp2OrIdx;
4620 47071 : if ((p == pFtn) || (p == pEdn) || (p == pAnd))
4621 16 : pRes->nMemLen = p->nSprmsLen;
4622 47055 : else if (p->nSprmsLen >= maSprmParser.MinSprmLen()) //Normal
4623 : {
4624 : // Length of actual sprm
4625 39590 : pRes->nMemLen = maSprmParser.GetSprmSize(pRes->nSprmId, pRes->pMemPos);
4626 : }
4627 47071 : }
4628 :
4629 43788 : void WW8PLCFMan::GetSprmEnd( short nIdx, WW8PLCFManResult* pRes ) const
4630 : {
4631 43788 : memset( pRes, 0, sizeof( WW8PLCFManResult ) );
4632 :
4633 43788 : const WW8PLCFxDesc* p = &aD[nIdx];
4634 :
4635 43788 : if (!(p->pIdStk->empty()))
4636 43788 : pRes->nSprmId = p->pIdStk->top(); // get end position
4637 : else
4638 : {
4639 : OSL_ENSURE( !this, "No Id on the Stack" );
4640 0 : pRes->nSprmId = 0;
4641 : }
4642 43788 : }
4643 :
4644 5612 : void WW8PLCFMan::GetNoSprmStart( short nIdx, WW8PLCFManResult* pRes ) const
4645 : {
4646 5612 : const WW8PLCFxDesc* p = &aD[nIdx];
4647 :
4648 5612 : pRes->nCpPos = p->nStartPos;
4649 5612 : pRes->nMemLen = p->nSprmsLen;
4650 5612 : pRes->nCp2OrIdx = p->nCp2OrIdx;
4651 :
4652 5612 : if( p == pFld )
4653 0 : pRes->nSprmId = eFLD;
4654 5612 : else if( p == pFtn )
4655 0 : pRes->nSprmId = eFTN;
4656 5612 : else if( p == pEdn )
4657 0 : pRes->nSprmId = eEDN;
4658 5612 : else if( p == pBkm )
4659 34 : pRes->nSprmId = eBKN;
4660 5578 : else if( p == pAnd )
4661 0 : pRes->nSprmId = eAND;
4662 5578 : else if( p == pPcd )
4663 : {
4664 : //We slave the piece table attributes to the piece table, the piece
4665 : //table attribute iterator contains the sprms for this piece.
4666 5578 : GetSprmStart( nIdx+1, pRes );
4667 : }
4668 : else
4669 0 : pRes->nSprmId = 0; // default: not found
4670 5612 : }
4671 :
4672 5296 : void WW8PLCFMan::GetNoSprmEnd( short nIdx, WW8PLCFManResult* pRes ) const
4673 : {
4674 5296 : pRes->nMemLen = -1; // Ende-Kennzeichen
4675 :
4676 5296 : if( &aD[nIdx] == pBkm )
4677 0 : pRes->nSprmId = eBKN;
4678 5296 : else if( &aD[nIdx] == pPcd )
4679 : {
4680 : //We slave the piece table attributes to the piece table, the piece
4681 : //table attribute iterator contains the sprms for this piece.
4682 5296 : GetSprmEnd( nIdx+1, pRes );
4683 : }
4684 : else
4685 0 : pRes->nSprmId = 0;
4686 5296 : }
4687 :
4688 198 : bool WW8PLCFMan::TransferOpenSprms(std::stack<sal_uInt16> &rStack)
4689 : {
4690 1803 : for (int i = 0; i < nPLCF; ++i)
4691 : {
4692 1605 : WW8PLCFxDesc* p = &aD[i];
4693 1605 : if (!p || !p->pIdStk)
4694 525 : continue;
4695 2970 : while (!p->pIdStk->empty())
4696 : {
4697 810 : rStack.push(p->pIdStk->top());
4698 810 : p->pIdStk->pop();
4699 : }
4700 : }
4701 198 : return rStack.empty();
4702 : }
4703 :
4704 89339 : void WW8PLCFMan::AdvSprm(short nIdx, bool bStart)
4705 : {
4706 89339 : WW8PLCFxDesc* p = &aD[nIdx]; // Sprm-Klasse(!) ermitteln
4707 :
4708 89339 : p->bFirstSprm = false;
4709 89339 : if( bStart )
4710 : {
4711 45551 : sal_uInt16 nLastId = GetId(p);
4712 45551 : p->pIdStk->push(nLastId); // merke Id fuer Attribut-Ende
4713 :
4714 45551 : if( p->nSprmsLen )
4715 : { /*
4716 : Pruefe, ob noch Sprm(s) abzuarbeiten sind
4717 : */
4718 38119 : if( p->pMemPos )
4719 : {
4720 : // Length of last sprm
4721 38103 : sal_uInt16 nSprmL = maSprmParser.GetSprmSize(nLastId, p->pMemPos);
4722 :
4723 : // Gesamtlaenge Sprms um SprmLaenge verringern
4724 38103 : p->nSprmsLen -= nSprmL;
4725 :
4726 : // Pos des evtl. naechsten Sprm
4727 38103 : if (p->nSprmsLen < maSprmParser.MinSprmLen())
4728 : {
4729 : // sicherheitshalber auf Null setzen, da Enden folgen!
4730 6088 : p->pMemPos = 0;
4731 6088 : p->nSprmsLen = 0;
4732 : }
4733 : else
4734 32015 : p->pMemPos += nSprmL;
4735 : }
4736 : else
4737 16 : p->nSprmsLen = 0;
4738 : }
4739 45551 : if (p->nSprmsLen < maSprmParser.MinSprmLen())
4740 13536 : p->nStartPos = WW8_CP_MAX; // es folgen Enden
4741 : }
4742 : else
4743 : {
4744 43788 : if (!(p->pIdStk->empty()))
4745 43788 : p->pIdStk->pop();
4746 43788 : if (p->pIdStk->empty())
4747 : {
4748 12952 : if ( (p == pChp) || (p == pPap) )
4749 : {
4750 7538 : p->pMemPos = 0;
4751 7538 : p->nSprmsLen = 0;
4752 7538 : p->nStartPos = p->nOrigEndPos+p->nCpOfs;
4753 :
4754 : /*
4755 : On failed seek we have run out of sprms, probably. But if its
4756 : a fastsaved file (has pPcd) then we may be just in a sprm free
4757 : gap between pieces that have them, so set dirty flag in sprm
4758 : finder to consider than.
4759 : */
4760 7538 : if (!(*p->pPLCFx).SeekPos(p->nStartPos))
4761 : {
4762 67 : p->nEndPos = WW8_CP_MAX;
4763 67 : p->pPLCFx->SetDirty(true);
4764 : }
4765 7538 : if (!p->pPLCFx->GetDirty() || pPcd)
4766 7538 : GetNewSprms( *p );
4767 7538 : p->pPLCFx->SetDirty(false);
4768 :
4769 : /*
4770 : #i2325#
4771 : To get the character and paragraph properties you first get
4772 : the pap and chp and then apply the fastsaved pPcd properties
4773 : to the range. If a pap or chp starts inside the pPcd range
4774 : then we must bring the current pPcd range to a halt so as to
4775 : end those sprms, then the pap/chp will be processed, and then
4776 : we must force a restart of the pPcd on that pap/chp starting
4777 : boundary. Doing that effectively means that the pPcd sprms will
4778 : be applied to the new range. Not doing it means that the pPcd
4779 : sprms will only be applied to the first pap/chp set of
4780 : properties contained in the pap/chp range.
4781 :
4782 : So we bring the pPcd to a halt on this location here, by
4783 : settings its end to the current start, then store the starting
4784 : position of the current range to clipstart. The pPcd sprms
4785 : will end as normal (albeit earlier than originally expected),
4786 : and the existance of a clipstart will force the pPcd iterater
4787 : to reread the current set of sprms instead of advancing to its
4788 : next set. Then the clipstart will be set as the starting
4789 : position which will force them to be applied directly after
4790 : the pap and chps.
4791 : */
4792 18403 : if (pPcd && ((p->nStartPos > pPcd->nStartPos) ||
4793 10334 : (pPcd->nStartPos == WW8_CP_MAX)) &&
4794 7007 : (pPcd->nEndPos != p->nStartPos))
4795 : {
4796 5451 : pPcd->nEndPos = p->nStartPos;
4797 : ((WW8PLCFx_PCD *)(pPcd->pPLCFx))->SetClipStart(
4798 5451 : p->nStartPos);
4799 : }
4800 :
4801 : }
4802 : else
4803 : {
4804 5414 : p->pPLCFx->advance(); // next Group of Sprms
4805 5414 : p->pMemPos = 0; // !!!
4806 5414 : p->nSprmsLen = 0;
4807 5414 : GetNewSprms( *p );
4808 : }
4809 : OSL_ENSURE( p->nStartPos <= p->nEndPos, "Attribut ueber Kreuz" );
4810 : }
4811 : }
4812 89339 : }
4813 :
4814 10908 : void WW8PLCFMan::AdvNoSprm(short nIdx, bool bStart)
4815 : {
4816 : /*
4817 : For the case of a piece table we slave the piece table attribute iterator
4818 : to the piece table and access it through that only. They are two separate
4819 : structures, but act together as one logical one. The attributes only go
4820 : to the next entry when the piece changes
4821 : */
4822 10908 : WW8PLCFxDesc* p = &aD[nIdx];
4823 :
4824 10908 : if( p == pPcd )
4825 : {
4826 10874 : AdvSprm(nIdx+1,bStart);
4827 10874 : if( bStart )
4828 5578 : p->nStartPos = aD[nIdx+1].nStartPos;
4829 : else
4830 : {
4831 5296 : if (aD[nIdx+1].pIdStk->empty())
4832 : {
4833 5296 : WW8PLCFx_PCD *pTemp = (WW8PLCFx_PCD*)(pPcd->pPLCFx);
4834 : /*
4835 : #i2325#
4836 : As per normal, go on to the next set of properties, i.e. we
4837 : have traversed over to the next piece. With a clipstart set
4838 : we are being told to reread the current piece sprms so as to
4839 : reapply them to a new chp or pap range.
4840 : */
4841 5296 : if (pTemp->GetClipStart() == -1)
4842 5 : p->pPLCFx->advance();
4843 5296 : p->pMemPos = 0;
4844 5296 : p->nSprmsLen = 0;
4845 5296 : GetNewSprms( aD[nIdx+1] );
4846 5296 : GetNewNoSprms( *p );
4847 5296 : if (pTemp->GetClipStart() != -1)
4848 : {
4849 : /*
4850 : #i2325#, now we will force our starting position to the
4851 : clipping start so as to force the application of these
4852 : sprms after the current pap/chp sprms so as to apply the
4853 : fastsave sprms to the current range.
4854 : */
4855 5291 : p->nStartPos = pTemp->GetClipStart();
4856 5291 : pTemp->SetClipStart(-1);
4857 : }
4858 : }
4859 : }
4860 : }
4861 : else
4862 : { // NoSprm ohne Ende
4863 34 : p->pPLCFx->advance();
4864 34 : p->pMemPos = 0; // MemPos ungueltig
4865 34 : p->nSprmsLen = 0;
4866 34 : GetNewNoSprms( *p );
4867 : }
4868 10908 : }
4869 :
4870 89373 : void WW8PLCFMan::advance()
4871 : {
4872 : bool bStart;
4873 89373 : sal_uInt16 nIdx = WhereIdx(&bStart);
4874 89373 : if (nIdx < nPLCF)
4875 : {
4876 89373 : WW8PLCFxDesc* p = &aD[nIdx];
4877 :
4878 89373 : p->bFirstSprm = true; // Default
4879 :
4880 89373 : if( p->pPLCFx->IsSprm() )
4881 78465 : AdvSprm( nIdx, bStart );
4882 : else // NoSprm
4883 10908 : AdvNoSprm( nIdx, bStart );
4884 : }
4885 89373 : }
4886 :
4887 : // Rueckgabe true fuer Anfang eines Attributes oder Fehler,
4888 : // false fuer Ende d. Attr
4889 : // Restliche Rueckgabewerte werden in der vom Aufrufer zu stellenden Struktur
4890 : // WW8PclxManResults geliefert.
4891 90893 : bool WW8PLCFMan::Get(WW8PLCFManResult* pRes) const
4892 : {
4893 90893 : memset( pRes, 0, sizeof( WW8PLCFManResult ) );
4894 : bool bStart;
4895 90893 : sal_uInt16 nIdx = WhereIdx(&bStart);
4896 :
4897 90893 : if( nIdx >= nPLCF )
4898 : {
4899 : OSL_ENSURE( !this, "Position not found" );
4900 0 : return true;
4901 : }
4902 :
4903 90893 : if( aD[nIdx].pPLCFx->IsSprm() )
4904 : {
4905 79985 : if( bStart )
4906 : {
4907 41493 : GetSprmStart( nIdx, pRes );
4908 41493 : return true;
4909 : }
4910 : else
4911 : {
4912 38492 : GetSprmEnd( nIdx, pRes );
4913 38492 : return false;
4914 : }
4915 : }
4916 : else
4917 : {
4918 10908 : if( bStart )
4919 : {
4920 5612 : GetNoSprmStart( nIdx, pRes );
4921 5612 : return true;
4922 : }
4923 : else
4924 : {
4925 5296 : GetNoSprmEnd( nIdx, pRes );
4926 5296 : return false;
4927 : }
4928 : }
4929 : }
4930 :
4931 8121 : sal_uInt16 WW8PLCFMan::GetColl() const
4932 : {
4933 8121 : if( pPap->pPLCFx )
4934 8121 : return pPap->pPLCFx->GetIstd();
4935 : else
4936 : {
4937 : OSL_ENSURE( !this, "GetColl ohne PLCF_Pap" );
4938 0 : return 0;
4939 : }
4940 : }
4941 :
4942 114 : WW8PLCFx_FLD* WW8PLCFMan::GetFld() const
4943 : {
4944 114 : return (WW8PLCFx_FLD*)pFld->pPLCFx;
4945 : }
4946 :
4947 19425 : const sal_uInt8* WW8PLCFMan::HasParaSprm( sal_uInt16 nId ) const
4948 : {
4949 19425 : return ((WW8PLCFx_Cp_FKP*)pPap->pPLCFx)->HasSprm( nId );
4950 : }
4951 :
4952 1 : const sal_uInt8* WW8PLCFMan::HasCharSprm( sal_uInt16 nId ) const
4953 : {
4954 1 : return ((WW8PLCFx_Cp_FKP*)pChp->pPLCFx)->HasSprm( nId );
4955 : }
4956 :
4957 0 : bool WW8PLCFMan::HasCharSprm(sal_uInt16 nId,
4958 : std::vector<const sal_uInt8 *> &rResult) const
4959 : {
4960 0 : return ((WW8PLCFx_Cp_FKP*)pChp->pPLCFx)->HasSprm(nId, rResult);
4961 : }
4962 :
4963 : #endif // !DUMP
4964 :
4965 2844 : void WW8PLCFx::Save( WW8PLCFxSave1& rSave ) const
4966 : {
4967 2844 : rSave.nPLCFxPos = GetIdx();
4968 2844 : rSave.nPLCFxPos2 = GetIdx2();
4969 2844 : rSave.nPLCFxMemOfs = 0;
4970 2844 : rSave.nStartFC = GetStartFc();
4971 2844 : }
4972 :
4973 2841 : void WW8PLCFx::Restore( const WW8PLCFxSave1& rSave )
4974 : {
4975 2841 : SetIdx( rSave.nPLCFxPos );
4976 2841 : SetIdx2( rSave.nPLCFxPos2 );
4977 2841 : SetStartFc( rSave.nStartFC );
4978 2841 : }
4979 :
4980 1948 : sal_uLong WW8PLCFx_Cp_FKP::GetIdx2() const
4981 : {
4982 1948 : return GetPCDIdx();
4983 : }
4984 :
4985 1945 : void WW8PLCFx_Cp_FKP::SetIdx2( sal_uLong nIdx )
4986 : {
4987 1945 : SetPCDIdx( nIdx );
4988 1945 : }
4989 :
4990 1948 : void WW8PLCFx_Cp_FKP::Save( WW8PLCFxSave1& rSave ) const
4991 : {
4992 1948 : WW8PLCFx::Save( rSave );
4993 :
4994 1948 : rSave.nAttrStart = nAttrStart;
4995 1948 : rSave.nAttrEnd = nAttrEnd;
4996 1948 : rSave.bLineEnd = bLineEnd;
4997 1948 : }
4998 :
4999 1945 : void WW8PLCFx_Cp_FKP::Restore( const WW8PLCFxSave1& rSave )
5000 : {
5001 1945 : WW8PLCFx::Restore( rSave );
5002 :
5003 1945 : nAttrStart = rSave.nAttrStart;
5004 1945 : nAttrEnd = rSave.nAttrEnd;
5005 1945 : bLineEnd = rSave.bLineEnd;
5006 1945 : }
5007 :
5008 2844 : void WW8PLCFxDesc::Save( WW8PLCFxSave1& rSave ) const
5009 : {
5010 2844 : if( pPLCFx )
5011 : {
5012 2844 : pPLCFx->Save( rSave );
5013 2844 : if( pPLCFx->IsSprm() )
5014 : {
5015 2620 : WW8PLCFxDesc aD;
5016 2620 : aD.nStartPos = nOrigStartPos+nCpOfs;
5017 2620 : aD.nCpOfs = rSave.nCpOfs = nCpOfs;
5018 2620 : if (!(pPLCFx->SeekPos(aD.nStartPos)))
5019 : {
5020 418 : aD.nEndPos = WW8_CP_MAX;
5021 418 : pPLCFx->SetDirty(true);
5022 : }
5023 2620 : pPLCFx->GetSprms(&aD);
5024 2620 : pPLCFx->SetDirty(false);
5025 2620 : aD.ReduceByOffset();
5026 2620 : rSave.nStartCp = aD.nStartPos;
5027 2620 : rSave.nPLCFxMemOfs = nOrigSprmsLen - nSprmsLen;
5028 : }
5029 : }
5030 2844 : }
5031 :
5032 2841 : void WW8PLCFxDesc::Restore( const WW8PLCFxSave1& rSave )
5033 : {
5034 2841 : if( pPLCFx )
5035 : {
5036 2841 : pPLCFx->Restore( rSave );
5037 2841 : if( pPLCFx->IsSprm() )
5038 : {
5039 2617 : WW8PLCFxDesc aD;
5040 2617 : aD.nStartPos = rSave.nStartCp+rSave.nCpOfs;
5041 2617 : nCpOfs = aD.nCpOfs = rSave.nCpOfs;
5042 2617 : if (!(pPLCFx->SeekPos(aD.nStartPos)))
5043 : {
5044 418 : aD.nEndPos = WW8_CP_MAX;
5045 418 : pPLCFx->SetDirty(true);
5046 : }
5047 2617 : pPLCFx->GetSprms(&aD);
5048 2617 : pPLCFx->SetDirty(false);
5049 2617 : aD.ReduceByOffset();
5050 2617 : pMemPos = aD.pMemPos + rSave.nPLCFxMemOfs;
5051 : }
5052 : }
5053 2841 : }
5054 :
5055 : namespace
5056 : {
5057 2774 : sal_uInt32 Readcb(SvStream& rSt, ww::WordVersion eVer)
5058 : {
5059 2774 : if (eVer <= ww::eWW2)
5060 : {
5061 : sal_uInt16 nShort;
5062 38 : rSt.ReadUInt16( nShort );
5063 38 : return nShort;
5064 : }
5065 : else
5066 : {
5067 : sal_uInt32 nLong;
5068 2736 : rSt.ReadUInt32( nLong );
5069 2736 : return nLong;
5070 : }
5071 : }
5072 : }
5073 :
5074 464 : WW8_CP WW8Fib::GetBaseCp(ManTypes nType) const
5075 : {
5076 464 : WW8_CP nOffset = 0;
5077 :
5078 464 : switch( nType )
5079 : {
5080 : default:
5081 : case MAN_MAINTEXT:
5082 78 : break;
5083 : case MAN_FTN:
5084 1 : nOffset = ccpText;
5085 1 : break;
5086 : case MAN_HDFT:
5087 118 : nOffset = ccpText + ccpFtn;
5088 118 : break;
5089 : /*
5090 : A subdocument of this kind (MAN_MACRO) probably exists in some defunct
5091 : version of MSWord, but now ccpMcr is always 0. If some example that
5092 : uses this comes to light, this is the likely calculation required
5093 :
5094 : case MAN_MACRO:
5095 : nOffset = ccpText + ccpFtn + ccpHdr;
5096 : break;
5097 :
5098 : */
5099 : case MAN_AND:
5100 30 : nOffset = ccpText + ccpFtn + ccpHdr + ccpMcr;
5101 30 : break;
5102 : case MAN_EDN:
5103 0 : nOffset = ccpText + ccpFtn + ccpHdr + ccpMcr + ccpAtn;
5104 0 : break;
5105 : case MAN_TXBX:
5106 234 : nOffset = ccpText + ccpFtn + ccpHdr + ccpMcr + ccpAtn + ccpEdn;
5107 234 : break;
5108 : case MAN_TXBX_HDFT:
5109 3 : nOffset = ccpText + ccpFtn + ccpHdr + ccpMcr + ccpAtn + ccpEdn +
5110 3 : ccpTxbx;
5111 3 : break;
5112 : }
5113 464 : return nOffset;
5114 : }
5115 :
5116 115336 : ww::WordVersion WW8Fib::GetFIBVersion() const
5117 : {
5118 115336 : ww::WordVersion eVer = ww::eWW8;
5119 : /*
5120 : * Word for Windows 2 I think (1.X might work too if anyone has an example.
5121 : * Various pages claim that the fileformats of Word 1 and 2 for Windows are
5122 : * equivalent to Word for Macintosh 4 and 5. On the other hand
5123 : *
5124 : * wIdents for Word for Mac versions...
5125 : * 0xFE32 for Word 1
5126 : * 0xFE34 for Word 3
5127 : * 0xFE37 for Word 4 et 5.
5128 : *
5129 : * and this document
5130 : * http://cmsdoc.cern.ch/documents/docformat/CMS_CERN_LetterHead.word is
5131 : * claimed to be "Word 5 for Mac" by Office etc and has that wIdent, but
5132 : * its format isn't the same as that of Word 2 for windows. Nor is it
5133 : * the same as that of Word for DOS/PCWord 5
5134 : */
5135 115336 : if (wIdent == 0xa5db)
5136 4357 : eVer = ww::eWW2;
5137 : else
5138 : {
5139 110979 : switch (nVersion)
5140 : {
5141 : case 6:
5142 0 : eVer = ww::eWW6;
5143 0 : break;
5144 : case 7:
5145 0 : eVer = ww::eWW7;
5146 0 : break;
5147 : case 8:
5148 110979 : eVer = ww::eWW8;
5149 110979 : break;
5150 : }
5151 : }
5152 115336 : return eVer;
5153 : }
5154 :
5155 73 : WW8Fib::WW8Fib(SvStream& rSt, sal_uInt8 nWantedVersion, sal_uInt32 nOffset)
5156 73 : : nFibError( 0 )
5157 : {
5158 73 : memset(this, 0, sizeof(*this));
5159 : sal_uInt8 aBits1;
5160 : sal_uInt8 aBits2;
5161 : sal_uInt8 aVer8Bits1; // nur ab WinWord 8 benutzt
5162 73 : rSt.Seek( nOffset );
5163 : /*
5164 : Wunsch-Nr vermerken, File-Versionsnummer ermitteln
5165 : und gegen Wunsch-Nr. checken !
5166 : */
5167 73 : nVersion = nWantedVersion;
5168 73 : rSt.ReadUInt16( wIdent );
5169 73 : rSt.ReadUInt16( nFib );
5170 73 : rSt.ReadUInt16( nProduct );
5171 73 : if( 0 != rSt.GetError() )
5172 : {
5173 : sal_Int16 nFibMin;
5174 : sal_Int16 nFibMax;
5175 : // note: 6 stands for "6 OR 7", 7 stands for "ONLY 7"
5176 0 : switch( nVersion )
5177 : {
5178 : case 6:
5179 0 : nFibMin = 0x0065; // von 101 WinWord 6.0
5180 : // 102 "
5181 : // und 103 WinWord 6.0 fuer Macintosh
5182 : // 104 "
5183 0 : nFibMax = 0x0069; // bis 105 WinWord 95
5184 0 : break;
5185 : case 7:
5186 0 : nFibMin = 0x0069; // von 105 WinWord 95
5187 0 : nFibMax = 0x0069; // bis 105 WinWord 95
5188 0 : break;
5189 : case 8:
5190 0 : nFibMin = 0x006A; // von 106 WinWord 97
5191 0 : nFibMax = 0x00c1; // bis 193 WinWord 97 (?)
5192 0 : break;
5193 : default:
5194 0 : nFibMin = 0; // Programm-Fehler!
5195 0 : nFibMax = 0;
5196 0 : nFib = 1;
5197 : OSL_ENSURE( !this, "Es wurde vergessen, nVersion zu kodieren!" );
5198 0 : break;
5199 : }
5200 0 : if ( (nFib < nFibMin) || (nFib > nFibMax) )
5201 : {
5202 0 : nFibError = ERR_SWG_READ_ERROR; // Error melden
5203 0 : return; // und hopp raus!
5204 : }
5205 : }
5206 :
5207 73 : ww::WordVersion eVer = GetFIBVersion();
5208 :
5209 : // Hilfs-Varis fuer Ver67:
5210 73 : sal_Int16 pnChpFirst_Ver67=0;
5211 73 : sal_Int16 pnPapFirst_Ver67=0;
5212 73 : sal_Int16 cpnBteChp_Ver67=0;
5213 73 : sal_Int16 cpnBtePap_Ver67=0;
5214 :
5215 : // und auf gehts: FIB einlesen
5216 73 : rSt.ReadInt16( lid );
5217 73 : rSt.ReadInt16( pnNext );
5218 73 : rSt.ReadUChar( aBits1 );
5219 73 : rSt.ReadUChar( aBits2 );
5220 73 : rSt.ReadUInt16( nFibBack );
5221 73 : rSt.ReadUInt16( nHash );
5222 73 : rSt.ReadUInt16( nKey );
5223 73 : rSt.ReadUChar( envr );
5224 73 : rSt.ReadUChar( aVer8Bits1 ); // unter Ver67 nur leeres Reservefeld
5225 : // Inhalt von aVer8Bits1
5226 :
5227 : // sal_uInt8 fMac :1;
5228 : // sal_uInt8 fEmptySpecial :1;
5229 : // sal_uInt8 fLoadOverridePage :1;
5230 : // sal_uInt8 fFuturesavedUndo :1;
5231 : // sal_uInt8 fWord97Saved :1;
5232 : // sal_uInt8 :3;
5233 73 : rSt.ReadUInt16( chse );
5234 73 : rSt.ReadUInt16( chseTables );
5235 73 : rSt.ReadInt32( fcMin );
5236 73 : rSt.ReadInt32( fcMac );
5237 :
5238 : // Einschub fuer WW8 *****************************************************
5239 73 : if (IsEightPlus(eVer))
5240 : {
5241 72 : rSt.ReadUInt16( csw );
5242 :
5243 : // Marke: "rgsw" Beginning of the array of shorts
5244 72 : rSt.ReadUInt16( wMagicCreated );
5245 72 : rSt.ReadUInt16( wMagicRevised );
5246 72 : rSt.ReadUInt16( wMagicCreatedPrivate );
5247 72 : rSt.ReadUInt16( wMagicRevisedPrivate );
5248 72 : rSt.SeekRel( 9 * sizeof( sal_Int16 ) );
5249 :
5250 : /*
5251 : // dies sind die 9 unused Felder:
5252 : && (bVer67 || WW8ReadINT16( rSt, pnFbpChpFirst_W6 )) // 1
5253 : && (bVer67 || WW8ReadINT16( rSt, pnChpFirst_W6 )) // 2
5254 : && (bVer67 || WW8ReadINT16( rSt, cpnBteChp_W6 )) // 3
5255 : && (bVer67 || WW8ReadINT16( rSt, pnFbpPapFirst_W6 )) // 4
5256 : && (bVer67 || WW8ReadINT16( rSt, pnPapFirst_W6 )) // 5
5257 : && (bVer67 || WW8ReadINT16( rSt, cpnBtePap_W6 )) // 6
5258 : && (bVer67 || WW8ReadINT16( rSt, pnFbpLvcFirst_W6 )) // 7
5259 : && (bVer67 || WW8ReadINT16( rSt, pnLvcFirst_W6 )) // 8
5260 : && (bVer67 || WW8ReadINT16( rSt, cpnBteLvc_W6 )) // 9
5261 : */
5262 72 : rSt.ReadInt16( lidFE );
5263 72 : rSt.ReadUInt16( clw );
5264 : }
5265 :
5266 : // Ende des Einschubs fuer WW8 *******************************************
5267 :
5268 : // Marke: "rglw" Beginning of the array of longs
5269 73 : rSt.ReadInt32( cbMac );
5270 :
5271 : // 2 Longs uebergehen, da unwichtiger Quatsch
5272 73 : rSt.SeekRel( 2 * sizeof( sal_Int32) );
5273 :
5274 : // weitere 2 Longs nur bei Ver67 ueberspringen
5275 73 : if (IsSevenMinus(eVer))
5276 1 : rSt.SeekRel( 2 * sizeof( sal_Int32) );
5277 :
5278 73 : rSt.ReadInt32( ccpText );
5279 73 : rSt.ReadInt32( ccpFtn );
5280 73 : rSt.ReadInt32( ccpHdr );
5281 73 : rSt.ReadInt32( ccpMcr );
5282 73 : rSt.ReadInt32( ccpAtn );
5283 73 : rSt.ReadInt32( ccpEdn );
5284 73 : rSt.ReadInt32( ccpTxbx );
5285 73 : rSt.ReadInt32( ccpHdrTxbx );
5286 :
5287 : // weiteres Long nur bei Ver67 ueberspringen
5288 73 : if (IsSevenMinus(eVer))
5289 1 : rSt.SeekRel( 1 * sizeof( sal_Int32) );
5290 : else
5291 : {
5292 : // Einschub fuer WW8 *****************************************************
5293 72 : rSt.ReadInt32( pnFbpChpFirst );
5294 72 : rSt.ReadInt32( pnChpFirst );
5295 72 : rSt.ReadInt32( cpnBteChp );
5296 72 : rSt.ReadInt32( pnFbpPapFirst );
5297 72 : rSt.ReadInt32( pnPapFirst );
5298 72 : rSt.ReadInt32( cpnBtePap );
5299 72 : rSt.ReadInt32( pnFbpLvcFirst );
5300 72 : rSt.ReadInt32( pnLvcFirst );
5301 72 : rSt.ReadInt32( cpnBteLvc );
5302 72 : rSt.ReadInt32( fcIslandFirst );
5303 72 : rSt.ReadInt32( fcIslandLim );
5304 72 : rSt.ReadUInt16( cfclcb );
5305 : }
5306 :
5307 : // Ende des Einschubs fuer WW8 *******************************************
5308 :
5309 : // Marke: "rgfclcb" Beginning of array of FC/LCB pairs.
5310 73 : rSt.ReadInt32( fcStshfOrig );
5311 73 : lcbStshfOrig = Readcb(rSt, eVer);
5312 73 : rSt.ReadInt32( fcStshf );
5313 73 : lcbStshf = Readcb(rSt, eVer);
5314 73 : rSt.ReadInt32( fcPlcffndRef );
5315 73 : lcbPlcffndRef = Readcb(rSt, eVer);
5316 73 : rSt.ReadInt32( fcPlcffndTxt );
5317 73 : lcbPlcffndTxt = Readcb(rSt, eVer);
5318 73 : rSt.ReadInt32( fcPlcfandRef );
5319 73 : lcbPlcfandRef = Readcb(rSt, eVer);
5320 73 : rSt.ReadInt32( fcPlcfandTxt );
5321 73 : lcbPlcfandTxt = Readcb(rSt, eVer);
5322 73 : rSt.ReadInt32( fcPlcfsed );
5323 73 : lcbPlcfsed = Readcb(rSt, eVer);
5324 73 : rSt.ReadInt32( fcPlcfpad );
5325 73 : lcbPlcfpad = Readcb(rSt, eVer);
5326 73 : rSt.ReadInt32( fcPlcfphe );
5327 73 : lcbPlcfphe = Readcb(rSt, eVer);
5328 73 : rSt.ReadInt32( fcSttbfglsy );
5329 73 : lcbSttbfglsy = Readcb(rSt, eVer);
5330 73 : rSt.ReadInt32( fcPlcfglsy );
5331 73 : lcbPlcfglsy = Readcb(rSt, eVer);
5332 73 : rSt.ReadInt32( fcPlcfhdd );
5333 73 : lcbPlcfhdd = Readcb(rSt, eVer);
5334 73 : rSt.ReadInt32( fcPlcfbteChpx );
5335 73 : lcbPlcfbteChpx = Readcb(rSt, eVer);
5336 73 : rSt.ReadInt32( fcPlcfbtePapx );
5337 73 : lcbPlcfbtePapx = Readcb(rSt, eVer);
5338 73 : rSt.ReadInt32( fcPlcfsea );
5339 73 : lcbPlcfsea = Readcb(rSt, eVer);
5340 73 : rSt.ReadInt32( fcSttbfffn );
5341 73 : lcbSttbfffn = Readcb(rSt, eVer);
5342 73 : rSt.ReadInt32( fcPlcffldMom );
5343 73 : lcbPlcffldMom = Readcb(rSt, eVer);
5344 73 : rSt.ReadInt32( fcPlcffldHdr );
5345 73 : lcbPlcffldHdr = Readcb(rSt, eVer);
5346 73 : rSt.ReadInt32( fcPlcffldFtn );
5347 73 : lcbPlcffldFtn = Readcb(rSt, eVer);
5348 73 : rSt.ReadInt32( fcPlcffldAtn );
5349 73 : lcbPlcffldAtn = Readcb(rSt, eVer);
5350 73 : rSt.ReadInt32( fcPlcffldMcr );
5351 73 : lcbPlcffldMcr = Readcb(rSt, eVer);
5352 73 : rSt.ReadInt32( fcSttbfbkmk );
5353 73 : lcbSttbfbkmk = Readcb(rSt, eVer);
5354 73 : rSt.ReadInt32( fcPlcfbkf );
5355 73 : lcbPlcfbkf = Readcb(rSt, eVer);
5356 73 : rSt.ReadInt32( fcPlcfbkl );
5357 73 : lcbPlcfbkl = Readcb(rSt, eVer);
5358 73 : rSt.ReadInt32( fcCmds );
5359 73 : lcbCmds = Readcb(rSt, eVer);
5360 73 : rSt.ReadInt32( fcPlcfmcr );
5361 73 : lcbPlcfmcr = Readcb(rSt, eVer);
5362 73 : rSt.ReadInt32( fcSttbfmcr );
5363 73 : lcbSttbfmcr = Readcb(rSt, eVer);
5364 73 : rSt.ReadInt32( fcPrDrvr );
5365 73 : lcbPrDrvr = Readcb(rSt, eVer);
5366 73 : rSt.ReadInt32( fcPrEnvPort );
5367 73 : lcbPrEnvPort = Readcb(rSt, eVer);
5368 73 : rSt.ReadInt32( fcPrEnvLand );
5369 73 : lcbPrEnvLand = Readcb(rSt, eVer);
5370 73 : rSt.ReadInt32( fcWss );
5371 73 : lcbWss = Readcb(rSt, eVer);
5372 73 : rSt.ReadInt32( fcDop );
5373 73 : lcbDop = Readcb(rSt, eVer);
5374 73 : rSt.ReadInt32( fcSttbfAssoc );
5375 73 : lcbSttbfAssoc = Readcb(rSt, eVer);
5376 73 : rSt.ReadInt32( fcClx );
5377 73 : lcbClx = Readcb(rSt, eVer);
5378 73 : rSt.ReadInt32( fcPlcfpgdFtn );
5379 73 : lcbPlcfpgdFtn = Readcb(rSt, eVer);
5380 73 : rSt.ReadInt32( fcAutosaveSource );
5381 73 : lcbAutosaveSource = Readcb(rSt, eVer);
5382 73 : rSt.ReadInt32( fcGrpStAtnOwners );
5383 73 : lcbGrpStAtnOwners = Readcb(rSt, eVer);
5384 73 : rSt.ReadInt32( fcSttbfAtnbkmk );
5385 73 : lcbSttbfAtnbkmk = Readcb(rSt, eVer);
5386 :
5387 : // weiteres short nur bei Ver67 ueberspringen
5388 73 : if (IsSevenMinus(eVer))
5389 : {
5390 1 : rSt.SeekRel( 1*sizeof( sal_Int16) );
5391 :
5392 : // folgende 4 Shorts existieren nur bei Ver67;
5393 1 : rSt.ReadInt16( pnChpFirst_Ver67 );
5394 1 : rSt.ReadInt16( pnPapFirst_Ver67 );
5395 1 : rSt.ReadInt16( cpnBteChp_Ver67 );
5396 1 : rSt.ReadInt16( cpnBtePap_Ver67 );
5397 : }
5398 :
5399 73 : if (eVer > ww::eWW2)
5400 : {
5401 72 : rSt.ReadInt32( fcPlcfdoaMom );
5402 72 : rSt.ReadInt32( lcbPlcfdoaMom );
5403 72 : rSt.ReadInt32( fcPlcfdoaHdr );
5404 72 : rSt.ReadInt32( lcbPlcfdoaHdr );
5405 72 : rSt.ReadInt32( fcPlcfspaMom );
5406 72 : rSt.ReadInt32( lcbPlcfspaMom );
5407 72 : rSt.ReadInt32( fcPlcfspaHdr );
5408 72 : rSt.ReadInt32( lcbPlcfspaHdr );
5409 :
5410 72 : rSt.ReadInt32( fcPlcfAtnbkf );
5411 72 : rSt.ReadInt32( lcbPlcfAtnbkf );
5412 72 : rSt.ReadInt32( fcPlcfAtnbkl );
5413 72 : rSt.ReadInt32( lcbPlcfAtnbkl );
5414 72 : rSt.ReadInt32( fcPms );
5415 72 : rSt.ReadInt32( lcbPMS );
5416 72 : rSt.ReadInt32( fcFormFldSttbf );
5417 72 : rSt.ReadInt32( lcbFormFldSttbf );
5418 72 : rSt.ReadInt32( fcPlcfendRef );
5419 72 : rSt.ReadInt32( lcbPlcfendRef );
5420 72 : rSt.ReadInt32( fcPlcfendTxt );
5421 72 : rSt.ReadInt32( lcbPlcfendTxt );
5422 72 : rSt.ReadInt32( fcPlcffldEdn );
5423 72 : rSt.ReadInt32( lcbPlcffldEdn );
5424 72 : rSt.ReadInt32( fcPlcfpgdEdn );
5425 72 : rSt.ReadInt32( lcbPlcfpgdEdn );
5426 72 : rSt.ReadInt32( fcDggInfo );
5427 72 : rSt.ReadInt32( lcbDggInfo );
5428 72 : rSt.ReadInt32( fcSttbfRMark );
5429 72 : rSt.ReadInt32( lcbSttbfRMark );
5430 72 : rSt.ReadInt32( fcSttbfCaption );
5431 72 : rSt.ReadInt32( lcbSttbfCaption );
5432 72 : rSt.ReadInt32( fcSttbAutoCaption );
5433 72 : rSt.ReadInt32( lcbSttbAutoCaption );
5434 72 : rSt.ReadInt32( fcPlcfwkb );
5435 72 : rSt.ReadInt32( lcbPlcfwkb );
5436 72 : rSt.ReadInt32( fcPlcfspl );
5437 72 : rSt.ReadInt32( lcbPlcfspl );
5438 72 : rSt.ReadInt32( fcPlcftxbxTxt );
5439 72 : rSt.ReadInt32( lcbPlcftxbxTxt );
5440 72 : rSt.ReadInt32( fcPlcffldTxbx );
5441 72 : rSt.ReadInt32( lcbPlcffldTxbx );
5442 72 : rSt.ReadInt32( fcPlcfHdrtxbxTxt );
5443 72 : rSt.ReadInt32( lcbPlcfHdrtxbxTxt );
5444 72 : rSt.ReadInt32( fcPlcffldHdrTxbx );
5445 72 : rSt.ReadInt32( lcbPlcffldHdrTxbx );
5446 72 : rSt.ReadInt32( fcStwUser );
5447 72 : rSt.ReadUInt32( lcbStwUser );
5448 72 : rSt.ReadInt32( fcSttbttmbd );
5449 72 : rSt.ReadUInt32( lcbSttbttmbd );
5450 : }
5451 :
5452 73 : if( 0 == rSt.GetError() )
5453 : {
5454 : // Bit-Flags setzen
5455 73 : fDot = aBits1 & 0x01 ;
5456 73 : fGlsy = ( aBits1 & 0x02 ) >> 1;
5457 73 : fComplex = ( aBits1 & 0x04 ) >> 2;
5458 73 : fHasPic = ( aBits1 & 0x08 ) >> 3;
5459 73 : cQuickSaves = ( aBits1 & 0xf0 ) >> 4;
5460 73 : fEncrypted = aBits2 & 0x01 ;
5461 73 : fWhichTblStm= ( aBits2 & 0x02 ) >> 1;
5462 73 : fReadOnlyRecommended = (aBits2 & 0x4) >> 2;
5463 73 : fWriteReservation = (aBits2 & 0x8) >> 3;
5464 73 : fExtChar = ( aBits2 & 0x10 ) >> 4;
5465 : // dummy = ( aBits2 & 0x20 ) >> 5;
5466 73 : fFarEast = ( aBits2 & 0x40 ) >> 6; // #i90932#
5467 : // dummy = ( aBits2 & 0x80 ) >> 7;
5468 :
5469 : /*
5470 : ggfs. Ziel-Varaiblen, aus xxx_Ver67 fuellen
5471 : oder Flags setzen
5472 : */
5473 73 : if (IsSevenMinus(eVer))
5474 : {
5475 1 : pnChpFirst = pnChpFirst_Ver67;
5476 1 : pnPapFirst = pnPapFirst_Ver67;
5477 1 : cpnBteChp = cpnBteChp_Ver67;
5478 1 : cpnBtePap = cpnBtePap_Ver67;
5479 : }
5480 72 : else if (IsEightPlus(eVer))
5481 : {
5482 72 : fMac = aVer8Bits1 & 0x01 ;
5483 72 : fEmptySpecial = ( aVer8Bits1 & 0x02 ) >> 1;
5484 72 : fLoadOverridePage = ( aVer8Bits1 & 0x04 ) >> 2;
5485 72 : fFuturesavedUndo = ( aVer8Bits1 & 0x08 ) >> 3;
5486 72 : fWord97Saved = ( aVer8Bits1 & 0x10 ) >> 4;
5487 72 : fWord2000Saved = ( aVer8Bits1 & 0x20 ) >> 5;
5488 :
5489 : /*
5490 : speziell fuer WW8:
5491 : ermittle die Werte fuer PLCF LST und PLF LFO
5492 : und PLCF fuer TextBox-Break-Deskriptoren
5493 : */
5494 72 : long nOldPos = rSt.Tell();
5495 :
5496 72 : rSt.Seek( 0x02da );
5497 72 : rSt.ReadInt32( fcSttbFnm );
5498 72 : rSt.ReadInt32( lcbSttbFnm );
5499 72 : rSt.ReadInt32( fcPlcfLst );
5500 72 : rSt.ReadInt32( lcbPlcfLst );
5501 72 : rSt.ReadInt32( fcPlfLfo );
5502 72 : rSt.ReadInt32( lcbPlfLfo );
5503 72 : rSt.ReadInt32( fcPlcftxbxBkd );
5504 72 : rSt.ReadInt32( lcbPlcftxbxBkd );
5505 72 : rSt.ReadInt32( fcPlcfHdrtxbxBkd );
5506 72 : rSt.ReadInt32( lcbPlcfHdrtxbxBkd );
5507 72 : if( 0 != rSt.GetError() )
5508 : {
5509 0 : nFibError = ERR_SWG_READ_ERROR;
5510 : }
5511 :
5512 72 : rSt.Seek( 0x372 ); // fcSttbListNames
5513 72 : rSt.ReadInt32( fcSttbListNames );
5514 72 : rSt.ReadInt32( lcbSttbListNames );
5515 :
5516 72 : if (cfclcb > 93)
5517 : {
5518 69 : rSt.Seek( 0x382 ); // MagicTables
5519 69 : rSt.ReadInt32( fcPlcfTch );
5520 69 : rSt.ReadInt32( lcbPlcfTch );
5521 : }
5522 :
5523 72 : if (cfclcb > 113)
5524 : {
5525 58 : rSt.Seek( 0x41A ); // new ATRD
5526 58 : rSt.ReadInt32( fcAtrdExtra );
5527 58 : rSt.ReadUInt32( lcbAtrdExtra );
5528 : }
5529 :
5530 72 : if( 0 != rSt.GetError() )
5531 0 : nFibError = ERR_SWG_READ_ERROR;
5532 :
5533 72 : rSt.Seek( 0x5bc ); // Actual nFib introduced in Word 2003
5534 72 : rSt.ReadUInt16( nFib_actual );
5535 :
5536 72 : rSt.Seek( nOldPos );
5537 : }
5538 : }
5539 : else
5540 : {
5541 0 : nFibError = ERR_SWG_READ_ERROR; // Error melden
5542 : }
5543 : }
5544 :
5545 12 : WW8Fib::WW8Fib(sal_uInt8 nVer, bool bDot)
5546 : {
5547 12 : memset(this, 0, sizeof(*this));
5548 12 : nVersion = nVer;
5549 12 : if (8 == nVer)
5550 : {
5551 12 : fcMin = 0x800;
5552 12 : wIdent = 0xa5ec;
5553 12 : nFib = 0x0101;
5554 12 : nFibBack = 0xbf;
5555 12 : nProduct = 0x204D;
5556 12 : fDot = bDot;
5557 :
5558 12 : csw = 0x0e; // muss das sein ???
5559 12 : cfclcb = 0x88; // -""-
5560 12 : clw = 0x16; // -""-
5561 12 : pnFbpChpFirst = pnFbpPapFirst = pnFbpLvcFirst = 0x000fffff;
5562 12 : fExtChar = true;
5563 12 : fWord97Saved = fWord2000Saved = true;
5564 :
5565 12 : wMagicCreated = 0x6143;
5566 12 : wMagicRevised = 0x6C6F;
5567 12 : wMagicCreatedPrivate = 0x6E61;
5568 12 : wMagicRevisedPrivate = 0x3038;
5569 : }
5570 : else
5571 : {
5572 0 : fcMin = 0x300;
5573 0 : wIdent = 0xa5dc;
5574 0 : nFib = nFibBack = 0x65;
5575 0 : nProduct = 0xc02d;
5576 : }
5577 :
5578 : //If nFib is 0x00D9 or greater, then cQuickSaves MUST be 0xF
5579 12 : cQuickSaves = nFib >= 0x00D9 ? 0xF : 0;
5580 :
5581 : // --> #i90932#
5582 12 : lid = 0x409; // LANGUAGE_ENGLISH_US
5583 :
5584 12 : LanguageType nLang = Application::GetSettings().GetLanguageTag().getLanguageType();
5585 12 : fFarEast = MsLangId::isCJK(nLang);
5586 12 : if (fFarEast)
5587 0 : lidFE = nLang;
5588 : else
5589 12 : lidFE = lid;
5590 :
5591 12 : LanguageTag aLanguageTag( lid );
5592 24 : LocaleDataWrapper aLocaleWrapper( aLanguageTag );
5593 24 : nNumDecimalSep = aLocaleWrapper.getNumDecimalSep()[0];
5594 12 : }
5595 :
5596 0 : sal_Unicode WW8Fib::getNumDecimalSep() const
5597 : {
5598 0 : return nNumDecimalSep;
5599 : }
5600 :
5601 12 : bool WW8Fib::WriteHeader(SvStream& rStrm)
5602 : {
5603 12 : bool bVer8 = 8 == nVersion;
5604 :
5605 12 : size_t nUnencryptedHdr = bVer8 ? 0x44 : 0x24;
5606 12 : sal_uInt8 *pDataPtr = new sal_uInt8[ nUnencryptedHdr ];
5607 12 : sal_uInt8 *pData = pDataPtr;
5608 12 : memset( pData, 0, nUnencryptedHdr );
5609 :
5610 12 : sal_uLong nPos = rStrm.Tell();
5611 12 : cbMac = rStrm.Seek( STREAM_SEEK_TO_END );
5612 12 : rStrm.Seek( nPos );
5613 :
5614 12 : Set_UInt16( pData, wIdent );
5615 12 : Set_UInt16( pData, nFib );
5616 12 : Set_UInt16( pData, nProduct );
5617 12 : Set_UInt16( pData, lid );
5618 12 : Set_UInt16( pData, pnNext );
5619 :
5620 12 : sal_uInt16 nBits16 = 0;
5621 12 : if( fDot ) nBits16 |= 0x0001;
5622 12 : if( fGlsy) nBits16 |= 0x0002;
5623 12 : if( fComplex ) nBits16 |= 0x0004;
5624 12 : if( fHasPic ) nBits16 |= 0x0008;
5625 12 : nBits16 |= (0xf0 & ( cQuickSaves << 4 ));
5626 12 : if( fEncrypted ) nBits16 |= 0x0100;
5627 12 : if( fWhichTblStm ) nBits16 |= 0x0200;
5628 :
5629 12 : if (fReadOnlyRecommended)
5630 0 : nBits16 |= 0x0400;
5631 12 : if (fWriteReservation)
5632 0 : nBits16 |= 0x0800;
5633 :
5634 12 : if( fExtChar ) nBits16 |= 0x1000;
5635 12 : if( fFarEast ) nBits16 |= 0x4000; // #i90932#
5636 12 : if( fObfuscated ) nBits16 |= 0x8000;
5637 12 : Set_UInt16( pData, nBits16 );
5638 :
5639 12 : Set_UInt16( pData, nFibBack );
5640 12 : Set_UInt16( pData, nHash );
5641 12 : Set_UInt16( pData, nKey );
5642 12 : Set_UInt8( pData, envr );
5643 :
5644 12 : sal_uInt8 nBits8 = 0;
5645 12 : if( bVer8 )
5646 : {
5647 12 : if( fMac ) nBits8 |= 0x0001;
5648 12 : if( fEmptySpecial ) nBits8 |= 0x0002;
5649 12 : if( fLoadOverridePage ) nBits8 |= 0x0004;
5650 12 : if( fFuturesavedUndo ) nBits8 |= 0x0008;
5651 12 : if( fWord97Saved ) nBits8 |= 0x0010;
5652 12 : if( fWord2000Saved ) nBits8 |= 0x0020;
5653 : }
5654 : // unter Ver67 these are only reserved
5655 12 : Set_UInt8( pData, nBits8 );
5656 :
5657 12 : Set_UInt16( pData, chse );
5658 12 : Set_UInt16( pData, chseTables );
5659 12 : Set_UInt32( pData, fcMin );
5660 12 : Set_UInt32( pData, fcMac );
5661 :
5662 : // Einschub fuer WW8 *****************************************************
5663 :
5664 : // Marke: "rgsw" Beginning of the array of shorts
5665 12 : if( bVer8 )
5666 : {
5667 12 : Set_UInt16( pData, csw );
5668 12 : Set_UInt16( pData, wMagicCreated );
5669 12 : Set_UInt16( pData, wMagicRevised );
5670 12 : Set_UInt16( pData, wMagicCreatedPrivate );
5671 12 : Set_UInt16( pData, wMagicRevisedPrivate );
5672 12 : pData += 9 * sizeof( sal_Int16 );
5673 12 : Set_UInt16( pData, lidFE );
5674 12 : Set_UInt16( pData, clw );
5675 : }
5676 :
5677 : // Ende des Einschubs fuer WW8 *******************************************
5678 :
5679 : // Marke: "rglw" Beginning of the array of longs
5680 12 : Set_UInt32( pData, cbMac );
5681 :
5682 12 : rStrm.Write( pDataPtr, nUnencryptedHdr );
5683 12 : delete[] pDataPtr;
5684 12 : return 0 == rStrm.GetError();
5685 : }
5686 :
5687 12 : bool WW8Fib::Write(SvStream& rStrm)
5688 : {
5689 12 : bool bVer8 = 8 == nVersion;
5690 :
5691 12 : WriteHeader( rStrm );
5692 :
5693 12 : size_t nUnencryptedHdr = bVer8 ? 0x44 : 0x24;
5694 :
5695 12 : sal_uInt8 *pDataPtr = new sal_uInt8[ fcMin - nUnencryptedHdr ];
5696 12 : sal_uInt8 *pData = pDataPtr;
5697 12 : memset( pData, 0, fcMin - nUnencryptedHdr );
5698 :
5699 12 : sal_uLong nPos = rStrm.Tell();
5700 12 : cbMac = rStrm.Seek( STREAM_SEEK_TO_END );
5701 12 : rStrm.Seek( nPos );
5702 :
5703 : // 2 Longs uebergehen, da unwichtiger Quatsch
5704 12 : pData += 2 * sizeof( sal_Int32);
5705 :
5706 : // weitere 2 Longs nur bei Ver67 ueberspringen
5707 12 : if( !bVer8 )
5708 0 : pData += 2 * sizeof( sal_Int32);
5709 :
5710 12 : Set_UInt32( pData, ccpText );
5711 12 : Set_UInt32( pData, ccpFtn );
5712 12 : Set_UInt32( pData, ccpHdr );
5713 12 : Set_UInt32( pData, ccpMcr );
5714 12 : Set_UInt32( pData, ccpAtn );
5715 12 : Set_UInt32( pData, ccpEdn );
5716 12 : Set_UInt32( pData, ccpTxbx );
5717 12 : Set_UInt32( pData, ccpHdrTxbx );
5718 :
5719 : // weiteres Long nur bei Ver67 ueberspringen
5720 12 : if( !bVer8 )
5721 0 : pData += 1 * sizeof( sal_Int32);
5722 :
5723 : // Einschub fuer WW8 *****************************************************
5724 12 : if( bVer8 )
5725 : {
5726 12 : Set_UInt32( pData, pnFbpChpFirst );
5727 12 : Set_UInt32( pData, pnChpFirst );
5728 12 : Set_UInt32( pData, cpnBteChp );
5729 12 : Set_UInt32( pData, pnFbpPapFirst );
5730 12 : Set_UInt32( pData, pnPapFirst );
5731 12 : Set_UInt32( pData, cpnBtePap );
5732 12 : Set_UInt32( pData, pnFbpLvcFirst );
5733 12 : Set_UInt32( pData, pnLvcFirst );
5734 12 : Set_UInt32( pData, cpnBteLvc );
5735 12 : Set_UInt32( pData, fcIslandFirst );
5736 12 : Set_UInt32( pData, fcIslandLim );
5737 12 : Set_UInt16( pData, cfclcb );
5738 : }
5739 : // Ende des Einschubs fuer WW8 *******************************************
5740 :
5741 : // Marke: "rgfclcb" Beginning of array of FC/LCB pairs.
5742 12 : Set_UInt32( pData, fcStshfOrig );
5743 12 : Set_UInt32( pData, lcbStshfOrig );
5744 12 : Set_UInt32( pData, fcStshf );
5745 12 : Set_UInt32( pData, lcbStshf );
5746 12 : Set_UInt32( pData, fcPlcffndRef );
5747 12 : Set_UInt32( pData, lcbPlcffndRef );
5748 12 : Set_UInt32( pData, fcPlcffndTxt );
5749 12 : Set_UInt32( pData, lcbPlcffndTxt );
5750 12 : Set_UInt32( pData, fcPlcfandRef );
5751 12 : Set_UInt32( pData, lcbPlcfandRef );
5752 12 : Set_UInt32( pData, fcPlcfandTxt );
5753 12 : Set_UInt32( pData, lcbPlcfandTxt );
5754 12 : Set_UInt32( pData, fcPlcfsed );
5755 12 : Set_UInt32( pData, lcbPlcfsed );
5756 12 : Set_UInt32( pData, fcPlcfpad );
5757 12 : Set_UInt32( pData, lcbPlcfpad );
5758 12 : Set_UInt32( pData, fcPlcfphe );
5759 12 : Set_UInt32( pData, lcbPlcfphe );
5760 12 : Set_UInt32( pData, fcSttbfglsy );
5761 12 : Set_UInt32( pData, lcbSttbfglsy );
5762 12 : Set_UInt32( pData, fcPlcfglsy );
5763 12 : Set_UInt32( pData, lcbPlcfglsy );
5764 12 : Set_UInt32( pData, fcPlcfhdd );
5765 12 : Set_UInt32( pData, lcbPlcfhdd );
5766 12 : Set_UInt32( pData, fcPlcfbteChpx );
5767 12 : Set_UInt32( pData, lcbPlcfbteChpx );
5768 12 : Set_UInt32( pData, fcPlcfbtePapx );
5769 12 : Set_UInt32( pData, lcbPlcfbtePapx );
5770 12 : Set_UInt32( pData, fcPlcfsea );
5771 12 : Set_UInt32( pData, lcbPlcfsea );
5772 12 : Set_UInt32( pData, fcSttbfffn );
5773 12 : Set_UInt32( pData, lcbSttbfffn );
5774 12 : Set_UInt32( pData, fcPlcffldMom );
5775 12 : Set_UInt32( pData, lcbPlcffldMom );
5776 12 : Set_UInt32( pData, fcPlcffldHdr );
5777 12 : Set_UInt32( pData, lcbPlcffldHdr );
5778 12 : Set_UInt32( pData, fcPlcffldFtn );
5779 12 : Set_UInt32( pData, lcbPlcffldFtn );
5780 12 : Set_UInt32( pData, fcPlcffldAtn );
5781 12 : Set_UInt32( pData, lcbPlcffldAtn );
5782 12 : Set_UInt32( pData, fcPlcffldMcr );
5783 12 : Set_UInt32( pData, lcbPlcffldMcr );
5784 12 : Set_UInt32( pData, fcSttbfbkmk );
5785 12 : Set_UInt32( pData, lcbSttbfbkmk );
5786 12 : Set_UInt32( pData, fcPlcfbkf );
5787 12 : Set_UInt32( pData, lcbPlcfbkf );
5788 12 : Set_UInt32( pData, fcPlcfbkl );
5789 12 : Set_UInt32( pData, lcbPlcfbkl );
5790 12 : Set_UInt32( pData, fcCmds );
5791 12 : Set_UInt32( pData, lcbCmds );
5792 12 : Set_UInt32( pData, fcPlcfmcr );
5793 12 : Set_UInt32( pData, lcbPlcfmcr );
5794 12 : Set_UInt32( pData, fcSttbfmcr );
5795 12 : Set_UInt32( pData, lcbSttbfmcr );
5796 12 : Set_UInt32( pData, fcPrDrvr );
5797 12 : Set_UInt32( pData, lcbPrDrvr );
5798 12 : Set_UInt32( pData, fcPrEnvPort );
5799 12 : Set_UInt32( pData, lcbPrEnvPort );
5800 12 : Set_UInt32( pData, fcPrEnvLand );
5801 12 : Set_UInt32( pData, lcbPrEnvLand );
5802 12 : Set_UInt32( pData, fcWss );
5803 12 : Set_UInt32( pData, lcbWss );
5804 12 : Set_UInt32( pData, fcDop );
5805 12 : Set_UInt32( pData, lcbDop );
5806 12 : Set_UInt32( pData, fcSttbfAssoc );
5807 12 : Set_UInt32( pData, lcbSttbfAssoc );
5808 12 : Set_UInt32( pData, fcClx );
5809 12 : Set_UInt32( pData, lcbClx );
5810 12 : Set_UInt32( pData, fcPlcfpgdFtn );
5811 12 : Set_UInt32( pData, lcbPlcfpgdFtn );
5812 12 : Set_UInt32( pData, fcAutosaveSource );
5813 12 : Set_UInt32( pData, lcbAutosaveSource );
5814 12 : Set_UInt32( pData, fcGrpStAtnOwners );
5815 12 : Set_UInt32( pData, lcbGrpStAtnOwners );
5816 12 : Set_UInt32( pData, fcSttbfAtnbkmk );
5817 12 : Set_UInt32( pData, lcbSttbfAtnbkmk );
5818 :
5819 : // weiteres short nur bei Ver67 ueberspringen
5820 12 : if( !bVer8 )
5821 : {
5822 0 : pData += 1*sizeof( sal_Int16);
5823 0 : Set_UInt16( pData, (sal_uInt16)pnChpFirst );
5824 0 : Set_UInt16( pData, (sal_uInt16)pnPapFirst );
5825 0 : Set_UInt16( pData, (sal_uInt16)cpnBteChp );
5826 0 : Set_UInt16( pData, (sal_uInt16)cpnBtePap );
5827 : }
5828 :
5829 12 : Set_UInt32( pData, fcPlcfdoaMom ); // nur bei Ver67, in Ver8 unused
5830 12 : Set_UInt32( pData, lcbPlcfdoaMom ); // nur bei Ver67, in Ver8 unused
5831 12 : Set_UInt32( pData, fcPlcfdoaHdr ); // nur bei Ver67, in Ver8 unused
5832 12 : Set_UInt32( pData, lcbPlcfdoaHdr ); // nur bei Ver67, in Ver8 unused
5833 :
5834 12 : Set_UInt32( pData, fcPlcfspaMom ); // in Ver67 leere Reserve
5835 12 : Set_UInt32( pData, lcbPlcfspaMom ); // in Ver67 leere Reserve
5836 12 : Set_UInt32( pData, fcPlcfspaHdr ); // in Ver67 leere Reserve
5837 12 : Set_UInt32( pData, lcbPlcfspaHdr ); // in Ver67 leere Reserve
5838 :
5839 12 : Set_UInt32( pData, fcPlcfAtnbkf );
5840 12 : Set_UInt32( pData, lcbPlcfAtnbkf );
5841 12 : Set_UInt32( pData, fcPlcfAtnbkl );
5842 12 : Set_UInt32( pData, lcbPlcfAtnbkl );
5843 12 : Set_UInt32( pData, fcPms );
5844 12 : Set_UInt32( pData, lcbPMS );
5845 12 : Set_UInt32( pData, fcFormFldSttbf );
5846 12 : Set_UInt32( pData, lcbFormFldSttbf );
5847 12 : Set_UInt32( pData, fcPlcfendRef );
5848 12 : Set_UInt32( pData, lcbPlcfendRef );
5849 12 : Set_UInt32( pData, fcPlcfendTxt );
5850 12 : Set_UInt32( pData, lcbPlcfendTxt );
5851 12 : Set_UInt32( pData, fcPlcffldEdn );
5852 12 : Set_UInt32( pData, lcbPlcffldEdn );
5853 12 : Set_UInt32( pData, fcPlcfpgdEdn );
5854 12 : Set_UInt32( pData, lcbPlcfpgdEdn );
5855 12 : Set_UInt32( pData, fcDggInfo ); // in Ver67 leere Reserve
5856 12 : Set_UInt32( pData, lcbDggInfo ); // in Ver67 leere Reserve
5857 12 : Set_UInt32( pData, fcSttbfRMark );
5858 12 : Set_UInt32( pData, lcbSttbfRMark );
5859 12 : Set_UInt32( pData, fcSttbfCaption );
5860 12 : Set_UInt32( pData, lcbSttbfCaption );
5861 12 : Set_UInt32( pData, fcSttbAutoCaption );
5862 12 : Set_UInt32( pData, lcbSttbAutoCaption );
5863 12 : Set_UInt32( pData, fcPlcfwkb );
5864 12 : Set_UInt32( pData, lcbPlcfwkb );
5865 12 : Set_UInt32( pData, fcPlcfspl ); // in Ver67 leere Reserve
5866 12 : Set_UInt32( pData, lcbPlcfspl ); // in Ver67 leere Reserve
5867 12 : Set_UInt32( pData, fcPlcftxbxTxt );
5868 12 : Set_UInt32( pData, lcbPlcftxbxTxt );
5869 12 : Set_UInt32( pData, fcPlcffldTxbx );
5870 12 : Set_UInt32( pData, lcbPlcffldTxbx );
5871 12 : Set_UInt32( pData, fcPlcfHdrtxbxTxt );
5872 12 : Set_UInt32( pData, lcbPlcfHdrtxbxTxt );
5873 12 : Set_UInt32( pData, fcPlcffldHdrTxbx );
5874 12 : Set_UInt32( pData, lcbPlcffldHdrTxbx );
5875 :
5876 12 : if( bVer8 )
5877 : {
5878 12 : pData += 0x2da - 0x27a; // Pos + Offset (fcPlcfLst - fcStwUser)
5879 12 : Set_UInt32( pData, fcSttbFnm);
5880 12 : Set_UInt32( pData, lcbSttbFnm);
5881 12 : Set_UInt32( pData, fcPlcfLst );
5882 12 : Set_UInt32( pData, lcbPlcfLst );
5883 12 : Set_UInt32( pData, fcPlfLfo );
5884 12 : Set_UInt32( pData, lcbPlfLfo );
5885 12 : Set_UInt32( pData, fcPlcftxbxBkd );
5886 12 : Set_UInt32( pData, lcbPlcftxbxBkd );
5887 12 : Set_UInt32( pData, fcPlcfHdrtxbxBkd );
5888 12 : Set_UInt32( pData, lcbPlcfHdrtxbxBkd );
5889 :
5890 12 : pData += 0x372 - 0x302; // Pos + Offset (fcSttbListNames - fcDocUndo)
5891 12 : Set_UInt32( pData, fcSttbListNames );
5892 12 : Set_UInt32( pData, lcbSttbListNames );
5893 :
5894 12 : pData += 0x382 - 0x37A;
5895 12 : Set_UInt32( pData, fcPlcfTch );
5896 12 : Set_UInt32( pData, lcbPlcfTch );
5897 :
5898 12 : pData += 0x3FA - 0x38A;
5899 12 : Set_UInt16( pData, (sal_uInt16)0x0002);
5900 12 : Set_UInt16( pData, (sal_uInt16)0x00D9);
5901 :
5902 12 : pData += 0x41A - 0x3FE;
5903 12 : Set_UInt32( pData, fcAtrdExtra );
5904 12 : Set_UInt32( pData, lcbAtrdExtra );
5905 :
5906 12 : pData += 0x4DA - 0x422;
5907 12 : Set_UInt32( pData, fcHplxsdr );
5908 12 : Set_UInt32( pData, 0);
5909 : }
5910 :
5911 12 : rStrm.Write( pDataPtr, fcMin - nUnencryptedHdr );
5912 12 : delete[] pDataPtr;
5913 12 : return 0 == rStrm.GetError();
5914 : }
5915 :
5916 152 : rtl_TextEncoding WW8Fib::GetFIBCharset(sal_uInt16 chs)
5917 : {
5918 : OSL_ENSURE(chs <= 0x100, "overflowed winword charset set");
5919 : rtl_TextEncoding eCharSet =
5920 : (0x0100 == chs)
5921 : ? RTL_TEXTENCODING_APPLE_ROMAN
5922 152 : : rtl_getTextEncodingFromWindowsCharset( static_cast<sal_uInt8>(chs) );
5923 152 : return eCharSet;
5924 : }
5925 :
5926 73 : WW8Style::WW8Style(SvStream& rStream, WW8Fib& rFibPara)
5927 : : rFib(rFibPara), rSt(rStream), cstd(0), cbSTDBaseInFile(0), fStdStylenamesWritten(0)
5928 : , stiMaxWhenSaved(0), istdMaxFixedWhenSaved(0), nVerBuiltInNamesWhenSaved(0)
5929 73 : , ftcAsci(0), ftcFE(0), ftcOther(0), ftcBi(0)
5930 : {
5931 73 : if (!checkSeek(rSt, rFib.fcStshf))
5932 1 : return;
5933 :
5934 73 : sal_uInt16 cbStshi = 0; // 2 bytes size of the following STSHI structure
5935 73 : sal_uInt32 nRemaining = rFib.lcbStshf;
5936 73 : const sal_uInt32 nMinValidStshi = 4;
5937 :
5938 73 : if (rFib.GetFIBVersion() <= ww::eWW2)
5939 : {
5940 1 : cbStshi = 0;
5941 1 : cstd = 256;
5942 : }
5943 : else
5944 : {
5945 72 : if (rFib.nFib < 67) // old Version ? (need to find this again to fix)
5946 0 : cbStshi = nMinValidStshi;
5947 : else // new version
5948 : {
5949 72 : if (nRemaining < sizeof(cbStshi))
5950 0 : return;
5951 : // lies die Laenge der in der Datei gespeicherten Struktur
5952 72 : rSt.ReadUInt16( cbStshi );
5953 72 : nRemaining-=2;
5954 : }
5955 : }
5956 :
5957 73 : cbStshi = std::min(static_cast<sal_uInt32>(cbStshi), nRemaining);
5958 73 : if (cbStshi < nMinValidStshi)
5959 1 : return;
5960 :
5961 72 : sal_uInt16 nRead = cbStshi;
5962 : do
5963 : {
5964 : sal_uInt16 a16Bit;
5965 :
5966 72 : rSt.ReadUInt16( cstd );
5967 :
5968 72 : rSt.ReadUInt16( cbSTDBaseInFile );
5969 :
5970 99 : if( 6 > nRead ) break;
5971 72 : rSt.ReadUInt16( a16Bit );
5972 72 : fStdStylenamesWritten = a16Bit & 0x0001;
5973 :
5974 72 : if( 8 > nRead ) break;
5975 72 : rSt.ReadUInt16( stiMaxWhenSaved );
5976 :
5977 72 : if( 10 > nRead ) break;
5978 72 : rSt.ReadUInt16( istdMaxFixedWhenSaved );
5979 :
5980 72 : if( 12 > nRead ) break;
5981 72 : rSt.ReadUInt16( nVerBuiltInNamesWhenSaved );
5982 :
5983 72 : if( 14 > nRead ) break;
5984 72 : rSt.ReadUInt16( ftcAsci );
5985 :
5986 72 : if( 16 > nRead ) break;
5987 72 : rSt.ReadUInt16( ftcFE );
5988 :
5989 72 : if ( 18 > nRead ) break;
5990 72 : rSt.ReadUInt16( ftcOther );
5991 :
5992 72 : ftcBi = ftcOther;
5993 :
5994 72 : if ( 20 > nRead ) break;
5995 45 : rSt.ReadUInt16( ftcBi );
5996 :
5997 : // ggfs. den Rest ueberlesen
5998 45 : if( 20 < nRead )
5999 31 : rSt.SeekRel( nRead-20 );
6000 : }
6001 : while( false ); // Trick: obiger Block wird genau einmal durchlaufen
6002 : // und kann vorzeitig per "break" verlassen werden.
6003 :
6004 72 : nRemaining -= cbStshi;
6005 :
6006 : //There will be stshi.cstd (cbSTD, STD) pairs in the file following the
6007 : //STSHI. Note that styles can be empty, i.e. cbSTD == 0
6008 72 : const sal_uInt32 nMinRecordSize = sizeof(sal_uInt16);
6009 72 : sal_uInt16 nMaxPossibleRecords = nRemaining/nMinRecordSize;
6010 :
6011 : OSL_ENSURE(cstd <= nMaxPossibleRecords,
6012 : "allegedly more styles that available data\n");
6013 72 : cstd = std::min(cstd, nMaxPossibleRecords);
6014 : }
6015 :
6016 : // Read1STDFixed() liest ein Style ein. Wenn der Style vollstaendig vorhanden
6017 : // ist, d.h. kein leerer Slot, dann wird Speicher alloziert und ein Pointer auf
6018 : // die ( evtl. mit Nullen aufgefuellten ) STD geliefert. Ist es ein leerer
6019 : // Slot, dann wird ein Nullpointer zurueckgeliefert.
6020 2709 : WW8_STD* WW8Style::Read1STDFixed( short& rSkip, short* pcbStd )
6021 : {
6022 2709 : WW8_STD* pStd = 0;
6023 :
6024 2709 : sal_uInt16 cbStd(0);
6025 2709 : rSt.ReadUInt16( cbStd ); // lies Laenge
6026 :
6027 2709 : sal_uInt16 nRead = cbSTDBaseInFile;
6028 2709 : if( cbStd >= cbSTDBaseInFile )
6029 : {
6030 : // Fixed part vollst. vorhanden
6031 :
6032 : // read fixed part of STD
6033 1920 : pStd = new WW8_STD;
6034 1920 : memset( pStd, 0, sizeof( *pStd ) );
6035 :
6036 : do
6037 : {
6038 : sal_uInt16 a16Bit;
6039 :
6040 1920 : if( 2 > nRead ) break;
6041 1920 : a16Bit = 0;
6042 1920 : rSt.ReadUInt16( a16Bit );
6043 1920 : pStd->sti = a16Bit & 0x0fff ;
6044 1920 : pStd->fScratch = sal_uInt16(0 != ( a16Bit & 0x1000 ));
6045 1920 : pStd->fInvalHeight = sal_uInt16(0 != ( a16Bit & 0x2000 ));
6046 1920 : pStd->fHasUpe = sal_uInt16(0 != ( a16Bit & 0x4000 ));
6047 1920 : pStd->fMassCopy = sal_uInt16(0 != ( a16Bit & 0x8000 ));
6048 :
6049 1920 : if( 4 > nRead ) break;
6050 1920 : a16Bit = 0;
6051 1920 : rSt.ReadUInt16( a16Bit );
6052 1920 : pStd->sgc = a16Bit & 0x000f ;
6053 1920 : pStd->istdBase = ( a16Bit & 0xfff0 ) >> 4;
6054 :
6055 1920 : if( 6 > nRead ) break;
6056 1920 : a16Bit = 0;
6057 1920 : rSt.ReadUInt16( a16Bit );
6058 1920 : pStd->cupx = a16Bit & 0x000f ;
6059 1920 : pStd->istdNext = ( a16Bit & 0xfff0 ) >> 4;
6060 :
6061 1920 : if( 8 > nRead ) break;
6062 1920 : a16Bit = 0;
6063 1920 : rSt.ReadUInt16( pStd->bchUpe );
6064 :
6065 : // ab Ver8 sollten diese beiden Felder dazukommen:
6066 1920 : if(10 > nRead ) break;
6067 1920 : a16Bit = 0;
6068 1920 : rSt.ReadUInt16( a16Bit );
6069 1920 : pStd->fAutoRedef = a16Bit & 0x0001 ;
6070 1920 : pStd->fHidden = ( a16Bit & 0x0002 ) >> 1;
6071 :
6072 : // man kann nie wissen: vorsichtshalber ueberlesen
6073 : // wir eventuelle Fuellsel, die noch zum BASE-Part gehoeren...
6074 1920 : if( 10 < nRead )
6075 918 : rSt.SeekRel( nRead-10 );
6076 : }
6077 : while( false ); // Trick: obiger Block wird genau einmal durchlaufen
6078 : // und kann vorzeitig per "break" verlassen werden.
6079 :
6080 1920 : if( (0 != rSt.GetError()) || !nRead )
6081 0 : DELETEZ( pStd ); // per NULL den Error melden
6082 :
6083 1920 : rSkip = cbStd - cbSTDBaseInFile;
6084 : }
6085 : else
6086 : { // Fixed part zu kurz
6087 789 : if( cbStd )
6088 0 : rSt.SeekRel( cbStd ); // ueberlies Reste
6089 789 : rSkip = 0;
6090 : }
6091 2709 : if( pcbStd )
6092 960 : *pcbStd = cbStd;
6093 2709 : return pStd;
6094 : }
6095 :
6096 2709 : WW8_STD* WW8Style::Read1Style( short& rSkip, OUString* pString, short* pcbStd )
6097 : {
6098 : // Attention: MacWord-Documents have their Stylenames
6099 : // always in ANSI, even if eStructCharSet == CHARSET_MAC !!
6100 :
6101 2709 : WW8_STD* pStd = Read1STDFixed( rSkip, pcbStd ); // lese STD
6102 :
6103 : // String gewuenscht ?
6104 2709 : if( pString )
6105 : { // echter Style ?
6106 960 : if ( pStd )
6107 : {
6108 960 : switch( rFib.nVersion )
6109 : {
6110 : case 6:
6111 : case 7:
6112 : // lies Pascal-String
6113 0 : *pString = read_uInt8_BeltAndBracesString(rSt, RTL_TEXTENCODING_MS_1252);
6114 : // leading len and trailing zero --> 2
6115 0 : rSkip -= pString->getLength() + 2;
6116 0 : break;
6117 : case 8:
6118 : // handle Unicode-String with leading length short and
6119 : // trailing zero
6120 960 : if (TestBeltAndBraces(rSt))
6121 : {
6122 960 : *pString = read_uInt16_BeltAndBracesString(rSt);
6123 960 : rSkip -= (pString->getLength() + 2) * 2;
6124 : }
6125 : else
6126 : {
6127 : /*
6128 : #i8114#
6129 : This is supposed to be impossible, its just supposed
6130 : to be 16 bit count followed by the string and ending
6131 : in a 0 short. But "Lotus SmartSuite Product: Word Pro"
6132 : is creating invalid style names in ww7- format. So we
6133 : use the belt and braces of the ms strings to see if
6134 : they are not corrupt. If they are then we try them as
6135 : 8bit ones
6136 : */
6137 0 : *pString = read_uInt8_BeltAndBracesString(rSt,RTL_TEXTENCODING_MS_1252);
6138 : // leading len and trailing zero --> 2
6139 0 : rSkip -= pString->getLength() + 2;
6140 : }
6141 960 : break;
6142 : default:
6143 : OSL_ENSURE(!this, "Es wurde vergessen, nVersion zu kodieren!");
6144 0 : break;
6145 : }
6146 : }
6147 : else
6148 0 : *pString = OUString(); // Kann keinen Namen liefern
6149 : }
6150 2709 : return pStd;
6151 : }
6152 :
6153 : struct WW8_FFN_Ver6 : public WW8_FFN_BASE
6154 : {
6155 : // ab Ver6
6156 : sal_Char szFfn[65]; // 0x6 bzw. 0x40 ab Ver8 zero terminated string that
6157 : // records name of font.
6158 : // Maximal size of szFfn is 65 characters.
6159 : // Vorsicht: Dieses Array kann auch kleiner sein!!!
6160 : // Possibly followed by a second sz which records the
6161 : // name of an alternate font to use if the first named
6162 : // font does not exist on this system.
6163 : };
6164 : struct WW8_FFN_Ver8 : public WW8_FFN_BASE
6165 : {
6166 : // ab Ver8 sind folgende beiden Felder eingeschoben,
6167 : // werden von uns ignoriert.
6168 : sal_Char panose[ 10 ]; // 0x6 PANOSE
6169 : sal_Char fs[ 24 ]; // 0x10 FONTSIGNATURE
6170 :
6171 : // ab Ver8 als Unicode
6172 : sal_uInt16 szFfn[65]; // 0x6 bzw. 0x40 ab Ver8 zero terminated string that
6173 : // records name of font.
6174 : // Maximal size of szFfn is 65 characters.
6175 : // Vorsicht: Dieses Array kann auch kleiner sein!!!
6176 : // Possibly followed by a second sz which records the
6177 : // name of an alternate font to use if the first named
6178 : // font does not exist on this system.
6179 : };
6180 :
6181 : // #i43762# check font name for illegal characters
6182 485 : static void lcl_checkFontname( OUString& sString )
6183 : {
6184 : // for efficiency, we'd like to use String methods as far as possible.
6185 : // Hence, we will:
6186 : // 1) convert all invalid chars to \u0001
6187 : // 2) then erase all \u0001 chars (if any were found), and
6188 : // 3) erase leading/trailing ';', in case a font name was
6189 : // completely removed
6190 :
6191 : // convert all invalid chars to \u0001
6192 485 : OUStringBuffer aBuf(sString);
6193 485 : const sal_Int32 nLen = aBuf.getLength();
6194 485 : bool bFound = false;
6195 5953 : for ( sal_Int32 n = 0; n < nLen; ++n )
6196 : {
6197 5468 : if ( aBuf[n] < 0x20 )
6198 : {
6199 0 : aBuf[n] = 1;
6200 0 : bFound = true;
6201 : }
6202 : }
6203 485 : sString = aBuf.makeStringAndClear();
6204 :
6205 : // if anything was found, remove \u0001 + leading/trailing ';'
6206 485 : if( bFound )
6207 : {
6208 0 : sString = comphelper::string::strip(sString.replaceAll("\001", ""), ';');
6209 485 : }
6210 485 : }
6211 :
6212 : namespace
6213 : {
6214 72 : sal_uInt16 calcMaxFonts(sal_uInt8 *p, sal_Int32 nFFn)
6215 : {
6216 : // Figure out the max number of fonts defined here
6217 72 : sal_uInt16 nMax = 0;
6218 72 : sal_Int32 nRemaining = nFFn;
6219 652 : while (nRemaining)
6220 : {
6221 : //p[0] is cbFfnM1, the alleged total length of FFN - 1.
6222 : //i.e. length after cbFfnM1
6223 580 : sal_uInt16 cbFfnM1 = *p++;
6224 580 : --nRemaining;
6225 :
6226 580 : if (cbFfnM1 > nRemaining)
6227 72 : break;
6228 :
6229 508 : nMax++;
6230 508 : nRemaining -= cbFfnM1;
6231 508 : p += cbFfnM1;
6232 : }
6233 72 : return nMax;
6234 : }
6235 : }
6236 :
6237 73 : WW8Fonts::WW8Fonts( SvStream& rSt, WW8Fib& rFib )
6238 73 : : pFontA(0), nMax(0)
6239 : {
6240 : // Attention: MacWord-Documents have their Fontnames
6241 : // always in ANSI, even if eStructCharSet == CHARSET_MAC !!
6242 73 : if( rFib.lcbSttbfffn <= 2 )
6243 : {
6244 : OSL_ENSURE( !this, "Fonttabelle kaputt! (rFib.lcbSttbfffn < 2)" );
6245 2 : return;
6246 : }
6247 :
6248 72 : if (!checkSeek(rSt, rFib.fcSttbfffn))
6249 0 : return;
6250 :
6251 72 : sal_Int32 nFFn = rFib.lcbSttbfffn - 2;
6252 :
6253 : // allocate Font Array
6254 72 : sal_uInt8* pA = new sal_uInt8[nFFn];
6255 72 : memset(pA, 0, nFFn);
6256 :
6257 72 : ww::WordVersion eVersion = rFib.GetFIBVersion();
6258 :
6259 72 : if( eVersion >= ww::eWW8 )
6260 : {
6261 : // bVer8: read the count of strings in nMax
6262 72 : rSt.ReadUInt16( nMax );
6263 : }
6264 :
6265 : // Ver8: skip undefined uint16
6266 : // Ver67: skip the herein stored total byte of structure
6267 : // - we already got that information in rFib.lcbSttbfffn
6268 72 : rSt.SeekRel( 2 );
6269 :
6270 : // read all font information
6271 72 : nFFn = rSt.Read(pA, nFFn);
6272 72 : sal_uInt16 nCalcMax = calcMaxFonts(pA, nFFn);
6273 :
6274 72 : if (eVersion < ww::eWW8)
6275 0 : nMax = nCalcMax;
6276 : else
6277 : {
6278 : //newer versions include purportive count of fonts, so take min of that
6279 : //and calced max
6280 72 : nMax = std::min(nMax, nCalcMax);
6281 : }
6282 :
6283 72 : if( nMax )
6284 : {
6285 : // allocate Index Array
6286 71 : pFontA = new WW8_FFN[ nMax ];
6287 71 : WW8_FFN* p = pFontA;
6288 :
6289 71 : if( eVersion <= ww::eWW2 )
6290 : {
6291 0 : WW8_FFN_BASE* pVer2 = (WW8_FFN_BASE*)pA;
6292 0 : for(sal_uInt16 i=0; i<nMax; ++i, ++p)
6293 : {
6294 0 : p->cbFfnM1 = pVer2->cbFfnM1;
6295 :
6296 0 : p->prg = 0;
6297 0 : p->fTrueType = 0;
6298 0 : p->ff = 0;
6299 :
6300 0 : p->wWeight = ( *(((sal_uInt8*)pVer2) + 1) );
6301 0 : p->chs = ( *(((sal_uInt8*)pVer2) + 2) );
6302 : /*
6303 : #i8726# 7- seems to encode the name in the same encoding as
6304 : the font, e.g load the doc in 97 and save to see the unicode
6305 : ver of the asian fontnames in that example to confirm.
6306 : */
6307 0 : rtl_TextEncoding eEnc = WW8Fib::GetFIBCharset(p->chs);
6308 0 : if ((eEnc == RTL_TEXTENCODING_SYMBOL) || (eEnc == RTL_TEXTENCODING_DONTKNOW))
6309 0 : eEnc = RTL_TEXTENCODING_MS_1252;
6310 :
6311 0 : p->sFontname = OUString ( (((const sal_Char*)pVer2) + 1 + 2), strlen((((const sal_Char*)pVer2) + 1 + 2)), eEnc);
6312 0 : pVer2 = (WW8_FFN_BASE*)( ((sal_uInt8*)pVer2) + pVer2->cbFfnM1 + 1 );
6313 : }
6314 : }
6315 71 : else if( eVersion < ww::eWW8 )
6316 : {
6317 0 : WW8_FFN_Ver6* pVer6 = (WW8_FFN_Ver6*)pA;
6318 : sal_uInt8 c2;
6319 0 : for(sal_uInt16 i=0; i<nMax; ++i, ++p)
6320 : {
6321 0 : p->cbFfnM1 = pVer6->cbFfnM1;
6322 0 : c2 = *(((sal_uInt8*)pVer6) + 1);
6323 :
6324 0 : p->prg = c2 & 0x02;
6325 0 : p->fTrueType = (c2 & 0x04) >> 2;
6326 : // ein Reserve-Bit ueberspringen
6327 0 : p->ff = (c2 & 0x70) >> 4;
6328 :
6329 0 : p->wWeight = SVBT16ToShort( *(SVBT16*)&pVer6->wWeight );
6330 0 : p->chs = pVer6->chs;
6331 0 : p->ibszAlt = pVer6->ibszAlt;
6332 : /*
6333 : #i8726# 7- seems to encode the name in the same encoding as
6334 : the font, e.g load the doc in 97 and save to see the unicode
6335 : ver of the asian fontnames in that example to confirm.
6336 : */
6337 0 : rtl_TextEncoding eEnc = WW8Fib::GetFIBCharset(p->chs);
6338 0 : if ((eEnc == RTL_TEXTENCODING_SYMBOL) || (eEnc == RTL_TEXTENCODING_DONTKNOW))
6339 0 : eEnc = RTL_TEXTENCODING_MS_1252;
6340 0 : p->sFontname = OUString(pVer6->szFfn, rtl_str_getLength(pVer6->szFfn), eEnc);
6341 0 : const sal_uInt16 maxStrSize = sizeof (pVer6->szFfn) / sizeof (pVer6->szFfn[0]);
6342 0 : if (p->ibszAlt && p->ibszAlt < maxStrSize) //don't start after end of string
6343 : {
6344 0 : const sal_Char *pAlt = pVer6->szFfn+p->ibszAlt;
6345 0 : p->sFontname += ";" + OUString(pAlt, rtl_str_getLength(pAlt), eEnc);
6346 : }
6347 : else
6348 : {
6349 : //#i18369# if it's a symbol font set Symbol as fallback
6350 0 : if (
6351 0 : RTL_TEXTENCODING_SYMBOL == WW8Fib::GetFIBCharset(p->chs)
6352 0 : && p->sFontname!="Symbol"
6353 : )
6354 : {
6355 0 : p->sFontname += ";Symbol";
6356 : }
6357 : }
6358 0 : pVer6 = (WW8_FFN_Ver6*)( ((sal_uInt8*)pVer6) + pVer6->cbFfnM1 + 1 );
6359 : }
6360 : }
6361 : else
6362 : {
6363 : //count of bytes in minimum FontFamilyInformation payload
6364 71 : const sal_uInt8 cbMinFFNPayload = 41;
6365 71 : sal_uInt16 nValidFonts = 0;
6366 71 : sal_Int32 nRemainingFFn = nFFn;
6367 71 : sal_uInt8* pRaw = pA;
6368 556 : for (sal_uInt16 i=0; i < nMax && nRemainingFFn; ++i, ++p)
6369 : {
6370 : //pRaw[0] is cbFfnM1, the alleged total length of FFN - 1
6371 : //i.e. length after cbFfnM1
6372 485 : sal_uInt8 cbFfnM1 = *pRaw++;
6373 485 : --nRemainingFFn;
6374 :
6375 485 : if (cbFfnM1 > nRemainingFFn)
6376 0 : break;
6377 :
6378 485 : if (cbFfnM1 < cbMinFFNPayload)
6379 0 : break;
6380 :
6381 485 : p->cbFfnM1 = cbFfnM1;
6382 :
6383 485 : sal_uInt8 *pVer8 = pRaw;
6384 :
6385 485 : sal_uInt8 c2 = *pVer8++;
6386 485 : --cbFfnM1;
6387 :
6388 485 : p->prg = c2 & 0x02;
6389 485 : p->fTrueType = (c2 & 0x04) >> 2;
6390 : // ein Reserve-Bit ueberspringen
6391 485 : p->ff = (c2 & 0x70) >> 4;
6392 :
6393 485 : p->wWeight = SVBT16ToShort(*(SVBT16*)pVer8);
6394 485 : pVer8+=2;
6395 485 : cbFfnM1-=2;
6396 :
6397 485 : p->chs = *pVer8++;
6398 485 : --cbFfnM1;
6399 :
6400 485 : p->ibszAlt = *pVer8++;
6401 485 : --cbFfnM1;
6402 :
6403 485 : pVer8 += 10; //PANOSE
6404 485 : cbFfnM1-=10;
6405 485 : pVer8 += 24; //FONTSIGNATURE
6406 485 : cbFfnM1-=24;
6407 :
6408 : OSL_ASSERT(cbFfnM1 >= 2);
6409 :
6410 485 : sal_uInt8 nMaxNullTerminatedPossible = cbFfnM1/2 - 1;
6411 485 : sal_Unicode *pPrimary = reinterpret_cast<sal_Unicode*>(pVer8);
6412 485 : pPrimary[nMaxNullTerminatedPossible] = 0;
6413 : #ifdef OSL_BIGENDIAN
6414 : swapEndian(pPrimary);
6415 : #endif
6416 485 : p->sFontname = pPrimary;
6417 485 : if (p->ibszAlt && p->ibszAlt < nMaxNullTerminatedPossible)
6418 : {
6419 43 : sal_Unicode *pSecondary = pPrimary + p->ibszAlt;
6420 : #ifdef OSL_BIGENDIAN
6421 : swapEndian(pSecondary);
6422 : #endif
6423 43 : p->sFontname += ";" + OUString(pSecondary);
6424 : }
6425 :
6426 : // #i43762# check font name for illegal characters
6427 485 : lcl_checkFontname( p->sFontname );
6428 :
6429 : // Zeiger auf Ursprungsarray einen Font nach hinten setzen
6430 485 : pRaw += p->cbFfnM1;
6431 485 : nRemainingFFn -= p->cbFfnM1;
6432 485 : ++nValidFonts;
6433 : }
6434 : OSL_ENSURE(nMax == nValidFonts, "Font count differs with availability");
6435 71 : nMax = std::min(nMax, nValidFonts);
6436 : }
6437 : }
6438 72 : delete[] pA;
6439 : }
6440 :
6441 6344 : const WW8_FFN* WW8Fonts::GetFont( sal_uInt16 nNum ) const
6442 : {
6443 6344 : if( !pFontA || nNum >= nMax )
6444 165 : return 0;
6445 :
6446 6179 : return &pFontA[ nNum ];
6447 : }
6448 :
6449 : // Suche zu einem Header / Footer den Index in der WW-Liste von Headern / Footern
6450 :
6451 : // Pferdefuesse bei WinWord6 und -7:
6452 : // 1) Am Anfang des Einlesens muss WWPLCF_HdFt mit Fib und Dop konstruiert werden
6453 : // 2) Der Haupttext muss sequentiell ueber alle Sections gelesen werden
6454 : // 3) Fuer jedes vorkommende Header / Footer - Attribut des Haupttextes
6455 : // ( Darf pro Section maximal eins sein ) muss UpdateIndex() genau einmal
6456 : // mit dem Parameter des Attributes gerufen werden. Dieser Aufruf muss *nach*
6457 : // dem letzten Aufruf von GetTextPos() passieren.
6458 : // 4) GetTextPos() darf mit genau einem der obenstehen WW_... aufgerufen werden
6459 : // ( nicht verodern ! )
6460 : // -> dann liefert GetTextPos() vielleicht auch ein richtiges Ergebnis
6461 :
6462 32 : WW8PLCF_HdFt::WW8PLCF_HdFt( SvStream* pSt, WW8Fib& rFib, WW8Dop& rDop )
6463 32 : : aPLCF(*pSt, rFib.fcPlcfhdd , rFib.lcbPlcfhdd , 0)
6464 : {
6465 32 : nIdxOffset = 0;
6466 :
6467 : /*
6468 : cmc 23/02/2000: This dop.grpfIhdt has a bit set for each special
6469 : footnote *and endnote!!* separator,continuation separator, and
6470 : continuation notice entry, the documentation does not mention the
6471 : endnote separators, the documentation also gets the index numbers
6472 : backwards when specifiying which bits to test. The bottom six bits
6473 : of this value must be tested and skipped over. Each section's
6474 : grpfIhdt is then tested for the existence of the appropriate headers
6475 : and footers, at the end of each section the nIdxOffset must be updated
6476 : to point to the beginning of the next section's group of headers and
6477 : footers in this PLCF, UpdateIndex does that task.
6478 : */
6479 224 : for( sal_uInt8 nI = 0x1; nI <= 0x20; nI <<= 1 )
6480 192 : if( nI & rDop.grpfIhdt ) // Bit gesetzt ?
6481 0 : nIdxOffset++;
6482 :
6483 32 : nTextOfs = rFib.ccpText + rFib.ccpFtn; // Groesse des Haupttextes
6484 : // und der Fussnoten
6485 32 : }
6486 :
6487 2 : bool WW8PLCF_HdFt::GetTextPos(sal_uInt8 grpfIhdt, sal_uInt8 nWhich, WW8_CP& rStart,
6488 : long& rLen)
6489 : {
6490 2 : sal_uInt8 nI = 0x01;
6491 2 : short nIdx = nIdxOffset;
6492 : while (true)
6493 : {
6494 6 : if( nI & nWhich )
6495 2 : break; // found
6496 4 : if( grpfIhdt & nI )
6497 1 : nIdx++; // uninteresting Header / Footer
6498 4 : nI <<= 1; // text next bit
6499 4 : if( nI > 0x20 )
6500 0 : return false; // not found
6501 : }
6502 : // nIdx ist HdFt-Index
6503 : WW8_CP nEnd;
6504 : void* pData;
6505 :
6506 2 : aPLCF.SetIdx( nIdx ); // Lookup suitable CP
6507 2 : aPLCF.Get( rStart, nEnd, pData );
6508 2 : rLen = nEnd - rStart;
6509 2 : aPLCF.advance();
6510 :
6511 6 : return true;
6512 : }
6513 :
6514 304 : bool WW8PLCF_HdFt::GetTextPosExact(short nIdx, WW8_CP& rStart, long& rLen)
6515 : {
6516 : WW8_CP nEnd;
6517 : void* pData;
6518 :
6519 304 : aPLCF.SetIdx( nIdx ); // Lookup suitable CP
6520 304 : aPLCF.Get( rStart, nEnd, pData );
6521 304 : rLen = nEnd - rStart;
6522 304 : return true;
6523 : }
6524 :
6525 31 : void WW8PLCF_HdFt::UpdateIndex( sal_uInt8 grpfIhdt )
6526 : {
6527 : // Caution: Description is not correct
6528 217 : for( sal_uInt8 nI = 0x01; nI <= 0x20; nI <<= 1 )
6529 186 : if( nI & grpfIhdt )
6530 122 : nIdxOffset++;
6531 31 : }
6532 :
6533 : // WW8Dop
6534 :
6535 73 : WW8Dop::WW8Dop(SvStream& rSt, sal_Int16 nFib, sal_Int32 nPos, sal_uInt32 nSize) : bUseThaiLineBreakingRules(false)
6536 : {
6537 73 : memset( &nDataStart, 0, (&nDataEnd - &nDataStart) );
6538 73 : fDontUseHTMLAutoSpacing = true; //default
6539 73 : fAcetateShowAtn = true; //default
6540 73 : const sal_uInt32 nMaxDopSize = 0x268;
6541 73 : sal_uInt8* pDataPtr = new sal_uInt8[ nMaxDopSize ];
6542 73 : sal_uInt8* pData = pDataPtr;
6543 :
6544 73 : sal_uInt32 nRead = nMaxDopSize < nSize ? nMaxDopSize : nSize;
6545 73 : rSt.Seek( nPos );
6546 73 : if (2 > nSize || nRead != rSt.Read(pData, nRead))
6547 0 : nDopError = ERR_SWG_READ_ERROR; // Error melden
6548 : else
6549 : {
6550 73 : if (nMaxDopSize > nRead)
6551 41 : memset( pData + nRead, 0, nMaxDopSize - nRead );
6552 :
6553 : // dann mal die Daten auswerten
6554 : sal_uInt32 a32Bit;
6555 : sal_uInt16 a16Bit;
6556 : sal_uInt8 a8Bit;
6557 :
6558 73 : a16Bit = Get_UShort( pData ); // 0 0x00
6559 73 : fFacingPages = 0 != ( a16Bit & 0x0001 ) ;
6560 73 : fWidowControl = 0 != ( a16Bit & 0x0002 ) ;
6561 73 : fPMHMainDoc = 0 != ( a16Bit & 0x0004 ) ;
6562 73 : grfSuppression = ( a16Bit & 0x0018 ) >> 3;
6563 73 : fpc = ( a16Bit & 0x0060 ) >> 5;
6564 73 : grpfIhdt = ( a16Bit & 0xff00 ) >> 8;
6565 :
6566 73 : a16Bit = Get_UShort( pData ); // 2 0x02
6567 73 : rncFtn = a16Bit & 0x0003 ;
6568 73 : nFtn = ( a16Bit & ~0x0003 ) >> 2 ;
6569 :
6570 73 : a8Bit = Get_Byte( pData ); // 4 0x04
6571 73 : fOutlineDirtySave = 0 != ( a8Bit & 0x01 );
6572 :
6573 73 : a8Bit = Get_Byte( pData ); // 5 0x05
6574 73 : fOnlyMacPics = 0 != ( a8Bit & 0x01 );
6575 73 : fOnlyWinPics = 0 != ( a8Bit & 0x02 );
6576 73 : fLabelDoc = 0 != ( a8Bit & 0x04 );
6577 73 : fHyphCapitals = 0 != ( a8Bit & 0x08 );
6578 73 : fAutoHyphen = 0 != ( a8Bit & 0x10 );
6579 73 : fFormNoFields = 0 != ( a8Bit & 0x20 );
6580 73 : fLinkStyles = 0 != ( a8Bit & 0x40 );
6581 73 : fRevMarking = 0 != ( a8Bit & 0x80 );
6582 :
6583 73 : a8Bit = Get_Byte( pData ); // 6 0x06
6584 73 : fBackup = 0 != ( a8Bit & 0x01 );
6585 73 : fExactCWords = 0 != ( a8Bit & 0x02 );
6586 73 : fPagHidden = 0 != ( a8Bit & 0x04 );
6587 73 : fPagResults = 0 != ( a8Bit & 0x08 );
6588 73 : fLockAtn = 0 != ( a8Bit & 0x10 );
6589 73 : fMirrorMargins = 0 != ( a8Bit & 0x20 );
6590 73 : fReadOnlyRecommended = 0 != ( a8Bit & 0x40 );
6591 73 : fDfltTrueType = 0 != ( a8Bit & 0x80 );
6592 :
6593 73 : a8Bit = Get_Byte( pData ); // 7 0x07
6594 73 : fPagSuppressTopSpacing = 0 != ( a8Bit & 0x01 );
6595 73 : fProtEnabled = 0 != ( a8Bit & 0x02 );
6596 73 : fDispFormFldSel = 0 != ( a8Bit & 0x04 );
6597 73 : fRMView = 0 != ( a8Bit & 0x08 );
6598 73 : fRMPrint = 0 != ( a8Bit & 0x10 );
6599 73 : fWriteReservation = 0 != ( a8Bit & 0x20 );
6600 73 : fLockRev = 0 != ( a8Bit & 0x40 );
6601 73 : fEmbedFonts = 0 != ( a8Bit & 0x80 );
6602 :
6603 73 : a8Bit = Get_Byte( pData ); // 8 0x08
6604 73 : copts_fNoTabForInd = 0 != ( a8Bit & 0x01 );
6605 73 : copts_fNoSpaceRaiseLower = 0 != ( a8Bit & 0x02 );
6606 73 : copts_fSupressSpbfAfterPgBrk = 0 != ( a8Bit & 0x04 );
6607 73 : copts_fWrapTrailSpaces = 0 != ( a8Bit & 0x08 );
6608 73 : copts_fMapPrintTextColor = 0 != ( a8Bit & 0x10 );
6609 73 : copts_fNoColumnBalance = 0 != ( a8Bit & 0x20 );
6610 73 : copts_fConvMailMergeEsc = 0 != ( a8Bit & 0x40 );
6611 73 : copts_fSupressTopSpacing = 0 != ( a8Bit & 0x80 );
6612 :
6613 73 : a8Bit = Get_Byte( pData ); // 9 0x09
6614 73 : copts_fOrigWordTableRules = 0 != ( a8Bit & 0x01 );
6615 73 : copts_fTransparentMetafiles = 0 != ( a8Bit & 0x02 );
6616 73 : copts_fShowBreaksInFrames = 0 != ( a8Bit & 0x04 );
6617 73 : copts_fSwapBordersFacingPgs = 0 != ( a8Bit & 0x08 );
6618 73 : copts_fExpShRtn = 0 != ( a8Bit & 0x20 ); // #i56856#
6619 :
6620 73 : dxaTab = Get_Short( pData ); // 10 0x0a
6621 73 : wSpare = Get_UShort( pData ); // 12 0x0c
6622 73 : dxaHotZ = Get_UShort( pData ); // 14 0x0e
6623 73 : cConsecHypLim = Get_UShort( pData ); // 16 0x10
6624 73 : wSpare2 = Get_UShort( pData ); // 18 0x12
6625 73 : dttmCreated = Get_Long( pData ); // 20 0x14
6626 73 : dttmRevised = Get_Long( pData ); // 24 0x18
6627 73 : dttmLastPrint = Get_Long( pData ); // 28 0x1c
6628 73 : nRevision = Get_Short( pData ); // 32 0x20
6629 73 : tmEdited = Get_Long( pData ); // 34 0x22
6630 73 : cWords = Get_Long( pData ); // 38 0x26
6631 73 : cCh = Get_Long( pData ); // 42 0x2a
6632 73 : cPg = Get_Short( pData ); // 46 0x2e
6633 73 : cParas = Get_Long( pData ); // 48 0x30
6634 :
6635 73 : a16Bit = Get_UShort( pData ); // 52 0x34
6636 73 : rncEdn = a16Bit & 0x0003 ;
6637 73 : nEdn = ( a16Bit & ~0x0003 ) >> 2;
6638 :
6639 73 : a16Bit = Get_UShort( pData ); // 54 0x36
6640 73 : epc = a16Bit & 0x0003 ;
6641 73 : nfcFtnRef = ( a16Bit & 0x003c ) >> 2;
6642 73 : nfcEdnRef = ( a16Bit & 0x03c0 ) >> 6;
6643 73 : fPrintFormData = 0 != ( a16Bit & 0x0400 );
6644 73 : fSaveFormData = 0 != ( a16Bit & 0x0800 );
6645 73 : fShadeFormData = 0 != ( a16Bit & 0x1000 );
6646 73 : fWCFtnEdn = 0 != ( a16Bit & 0x8000 );
6647 :
6648 73 : cLines = Get_Long( pData ); // 56 0x38
6649 73 : cWordsFtnEnd = Get_Long( pData ); // 60 0x3c
6650 73 : cChFtnEdn = Get_Long( pData ); // 64 0x40
6651 73 : cPgFtnEdn = Get_Short( pData ); // 68 0x44
6652 73 : cParasFtnEdn = Get_Long( pData ); // 70 0x46
6653 73 : cLinesFtnEdn = Get_Long( pData ); // 74 0x4a
6654 73 : lKeyProtDoc = Get_Long( pData ); // 78 0x4e
6655 :
6656 73 : a16Bit = Get_UShort( pData ); // 82 0x52
6657 73 : wvkSaved = a16Bit & 0x0007 ;
6658 73 : wScaleSaved = ( a16Bit & 0x0ff8 ) >> 3 ;
6659 73 : zkSaved = ( a16Bit & 0x3000 ) >> 12;
6660 73 : fRotateFontW6 = ( a16Bit & 0x4000 ) >> 14;
6661 73 : iGutterPos = ( a16Bit & 0x8000 ) >> 15;
6662 : /*
6663 : bei nFib >= 103 gehts weiter:
6664 : */
6665 73 : if (nFib >= 103) // Word 6/32bit, 95, 97, 2000, 2002, 2003, 2007
6666 : {
6667 72 : a32Bit = Get_ULong( pData ); // 84 0x54
6668 72 : SetCompatabilityOptions(a32Bit);
6669 : }
6670 :
6671 : //#i22436#, for all WW7- documents
6672 73 : if (nFib <= 104) // Word 95
6673 1 : fUsePrinterMetrics = true;
6674 :
6675 : /*
6676 : bei nFib > 105 gehts weiter:
6677 : */
6678 73 : if (nFib > 105) // Word 97, 2000, 2002, 2003, 2007
6679 : {
6680 72 : adt = Get_Short( pData ); // 88 0x58
6681 :
6682 72 : doptypography.ReadFromMem(pData); // 90 0x5a
6683 :
6684 72 : memcpy( &dogrid, pData, sizeof( WW8_DOGRID )); // 400 0x190
6685 72 : pData += sizeof( WW8_DOGRID );
6686 :
6687 72 : a16Bit = Get_UShort( pData ); // 410 0x19a
6688 : // die untersten 9 Bit sind uninteressant
6689 72 : fHtmlDoc = ( a16Bit & 0x0200 ) >> 9 ;
6690 72 : fSnapBorder = ( a16Bit & 0x0800 ) >> 11 ;
6691 72 : fIncludeHeader = ( a16Bit & 0x1000 ) >> 12 ;
6692 72 : fIncludeFooter = ( a16Bit & 0x2000 ) >> 13 ;
6693 72 : fForcePageSizePag = ( a16Bit & 0x4000 ) >> 14 ;
6694 72 : fMinFontSizePag = ( a16Bit & 0x8000 ) >> 15 ;
6695 :
6696 72 : a16Bit = Get_UShort( pData ); // 412 0x19c
6697 72 : fHaveVersions = 0 != ( a16Bit & 0x0001 );
6698 72 : fAutoVersion = 0 != ( a16Bit & 0x0002 );
6699 :
6700 72 : pData += 12; // 414 0x19e
6701 :
6702 72 : cChWS = Get_Long( pData ); // 426 0x1aa
6703 72 : cChWSFtnEdn = Get_Long( pData ); // 430 0x1ae
6704 72 : grfDocEvents = Get_Long( pData ); // 434 0x1b2
6705 :
6706 72 : pData += 4+30+8; // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc
6707 :
6708 72 : cDBC = Get_Long( pData ); // 480 0x1e0
6709 72 : cDBCFtnEdn = Get_Long( pData ); // 484 0x1e4
6710 :
6711 72 : pData += 1 * sizeof( sal_Int32); // 488 0x1e8
6712 :
6713 72 : nfcFtnRef = Get_Short( pData ); // 492 0x1ec
6714 72 : nfcEdnRef = Get_Short( pData ); // 494 0x1ee
6715 72 : hpsZoonFontPag = Get_Short( pData ); // 496 0x1f0
6716 72 : dywDispPag = Get_Short( pData ); // 498 0x1f2
6717 :
6718 72 : if (nRead >= 516)
6719 : {
6720 : //500 -> 508, Appear to be repeated here in 2000+
6721 68 : pData += 8; // 500 0x1f4
6722 68 : a32Bit = Get_Long( pData ); // 508 0x1fc
6723 68 : SetCompatabilityOptions(a32Bit);
6724 68 : a32Bit = Get_Long( pData ); // 512 0x200
6725 :
6726 : // i#78591#
6727 68 : SetCompatabilityOptions2(a32Bit);
6728 : }
6729 72 : if (nRead >= 550)
6730 : {
6731 60 : pData += 32;
6732 60 : a16Bit = Get_UShort( pData );
6733 60 : fDoNotEmbedSystemFont = ( a16Bit & 0x0001 );
6734 60 : fWordCompat = ( a16Bit & 0x0002 ) >> 1;
6735 60 : fLiveRecover = ( a16Bit & 0x0004 ) >> 2;
6736 60 : fEmbedFactoids = ( a16Bit & 0x0008 ) >> 3;
6737 60 : fFactoidXML = ( a16Bit & 0x00010 ) >> 4;
6738 60 : fFactoidAllDone = ( a16Bit & 0x0020 ) >> 5;
6739 60 : fFolioPrint = ( a16Bit & 0x0040 ) >> 6;
6740 60 : fReverseFolio = ( a16Bit & 0x0080 ) >> 7;
6741 60 : iTextLineEnding = ( a16Bit & 0x0700 ) >> 8;
6742 60 : fHideFcc = ( a16Bit & 0x0800 ) >> 11;
6743 60 : fAcetateShowMarkup = ( a16Bit & 0x1000 ) >> 12;
6744 60 : fAcetateShowAtn = ( a16Bit & 0x2000 ) >> 13;
6745 60 : fAcetateShowInsDel = ( a16Bit & 0x4000 ) >> 14;
6746 60 : fAcetateShowProps = ( a16Bit & 0x8000 ) >> 15;
6747 : }
6748 72 : if (nRead >= 600)
6749 : {
6750 54 : pData += 48;
6751 54 : a16Bit = Get_Short(pData);
6752 54 : fUseBackGroundInAllmodes = (a16Bit & 0x0080) >> 7;
6753 : }
6754 : }
6755 : }
6756 73 : delete[] pDataPtr;
6757 73 : }
6758 :
6759 12 : WW8Dop::WW8Dop() : bUseThaiLineBreakingRules(false)
6760 : {
6761 : // first set everything to a default of 0
6762 12 : memset( &nDataStart, 0, (&nDataEnd - &nDataStart) );
6763 :
6764 12 : fWidowControl = true;
6765 12 : fpc = 1;
6766 12 : nFtn = 1;
6767 12 : fOutlineDirtySave = true;
6768 12 : fHyphCapitals = true;
6769 12 : fBackup = true;
6770 12 : fPagHidden = true;
6771 12 : fPagResults = true;
6772 12 : fDfltTrueType = true;
6773 :
6774 : /*
6775 : Writer acts like this all the time at the moment, ideally we need an
6776 : option for these two as well to import word docs that are not like
6777 : this by default
6778 : */
6779 12 : fNoLeading = true;
6780 12 : fUsePrinterMetrics = true;
6781 :
6782 12 : fRMView = true;
6783 12 : fRMPrint = true;
6784 12 : dxaTab = 0x2d0;
6785 12 : dxaHotZ = 0x168;
6786 12 : nRevision = 1;
6787 12 : nEdn = 1;
6788 :
6789 12 : epc = 3;
6790 12 : nfcEdnRef = 2;
6791 12 : fShadeFormData = true;
6792 :
6793 12 : wvkSaved = 2;
6794 12 : wScaleSaved = 100;
6795 12 : zkSaved = 0;
6796 :
6797 12 : lvl = 9;
6798 12 : fIncludeHeader = true;
6799 12 : fIncludeFooter = true;
6800 :
6801 12 : cChWS = /**!!**/ 0;
6802 12 : cChWSFtnEdn = /**!!**/ 0;
6803 :
6804 12 : cDBC = /**!!**/ 0;
6805 12 : cDBCFtnEdn = /**!!**/ 0;
6806 :
6807 12 : fAcetateShowAtn = true;
6808 12 : }
6809 :
6810 152 : void WW8Dop::SetCompatabilityOptions(sal_uInt32 a32Bit)
6811 : {
6812 152 : fNoTabForInd = ( a32Bit & 0x00000001 ) ;
6813 152 : fNoSpaceRaiseLower = ( a32Bit & 0x00000002 ) >> 1 ;
6814 152 : fSupressSpbfAfterPageBreak = ( a32Bit & 0x00000004 ) >> 2 ;
6815 152 : fWrapTrailSpaces = ( a32Bit & 0x00000008 ) >> 3 ;
6816 152 : fMapPrintTextColor = ( a32Bit & 0x00000010 ) >> 4 ;
6817 152 : fNoColumnBalance = ( a32Bit & 0x00000020 ) >> 5 ;
6818 152 : fConvMailMergeEsc = ( a32Bit & 0x00000040 ) >> 6 ;
6819 152 : fSupressTopSpacing = ( a32Bit & 0x00000080 ) >> 7 ;
6820 152 : fOrigWordTableRules = ( a32Bit & 0x00000100 ) >> 8 ;
6821 152 : fTransparentMetafiles = ( a32Bit & 0x00000200 ) >> 9 ;
6822 152 : fShowBreaksInFrames = ( a32Bit & 0x00000400 ) >> 10 ;
6823 152 : fSwapBordersFacingPgs = ( a32Bit & 0x00000800 ) >> 11 ;
6824 152 : fCompatabilityOptions_Unknown1_13 = ( a32Bit & 0x00001000 ) >> 12 ;
6825 152 : fExpShRtn = ( a32Bit & 0x00002000 ) >> 13 ; // #i56856#
6826 152 : fCompatabilityOptions_Unknown1_15 = ( a32Bit & 0x00004000 ) >> 14 ;
6827 152 : fCompatabilityOptions_Unknown1_16 = ( a32Bit & 0x00008000 ) >> 15 ;
6828 152 : fSuppressTopSpacingMac5 = ( a32Bit & 0x00010000 ) >> 16 ;
6829 152 : fTruncDxaExpand = ( a32Bit & 0x00020000 ) >> 17 ;
6830 152 : fPrintBodyBeforeHdr = ( a32Bit & 0x00040000 ) >> 18 ;
6831 152 : fNoLeading = ( a32Bit & 0x00080000 ) >> 19 ;
6832 152 : fCompatabilityOptions_Unknown1_21 = ( a32Bit & 0x00100000 ) >> 20 ;
6833 152 : fMWSmallCaps = ( a32Bit & 0x00200000 ) >> 21 ;
6834 152 : fCompatabilityOptions_Unknown1_23 = ( a32Bit & 0x00400000 ) >> 22 ;
6835 152 : fCompatabilityOptions_Unknown1_24 = ( a32Bit & 0x00800800 ) >> 23 ;
6836 152 : fCompatabilityOptions_Unknown1_25 = ( a32Bit & 0x01000000 ) >> 24 ;
6837 152 : fCompatabilityOptions_Unknown1_26 = ( a32Bit & 0x02000000 ) >> 25 ;
6838 152 : fCompatabilityOptions_Unknown1_27 = ( a32Bit & 0x04000000 ) >> 26 ;
6839 152 : fCompatabilityOptions_Unknown1_28 = ( a32Bit & 0x08000000 ) >> 27 ;
6840 152 : fCompatabilityOptions_Unknown1_29 = ( a32Bit & 0x10000000 ) >> 28 ;
6841 152 : fCompatabilityOptions_Unknown1_30 = ( a32Bit & 0x20000000 ) >> 29 ;
6842 152 : fCompatabilityOptions_Unknown1_31 = ( a32Bit & 0x40000000 ) >> 30 ;
6843 :
6844 152 : fUsePrinterMetrics = ( a32Bit & 0x80000000 ) >> 31 ;
6845 152 : }
6846 :
6847 97 : sal_uInt32 WW8Dop::GetCompatabilityOptions() const
6848 : {
6849 97 : sal_uInt32 a32Bit = 0;
6850 97 : if (fNoTabForInd) a32Bit |= 0x00000001;
6851 97 : if (fNoSpaceRaiseLower) a32Bit |= 0x00000002;
6852 97 : if (fSupressSpbfAfterPageBreak) a32Bit |= 0x00000004;
6853 97 : if (fWrapTrailSpaces) a32Bit |= 0x00000008;
6854 97 : if (fMapPrintTextColor) a32Bit |= 0x00000010;
6855 97 : if (fNoColumnBalance) a32Bit |= 0x00000020;
6856 97 : if (fConvMailMergeEsc) a32Bit |= 0x00000040;
6857 97 : if (fSupressTopSpacing) a32Bit |= 0x00000080;
6858 97 : if (fOrigWordTableRules) a32Bit |= 0x00000100;
6859 97 : if (fTransparentMetafiles) a32Bit |= 0x00000200;
6860 97 : if (fShowBreaksInFrames) a32Bit |= 0x00000400;
6861 97 : if (fSwapBordersFacingPgs) a32Bit |= 0x00000800;
6862 97 : if (fCompatabilityOptions_Unknown1_13) a32Bit |= 0x00001000;
6863 97 : if (fExpShRtn) a32Bit |= 0x00002000; // #i56856#
6864 97 : if (fCompatabilityOptions_Unknown1_15) a32Bit |= 0x00004000;
6865 97 : if (fCompatabilityOptions_Unknown1_16) a32Bit |= 0x00008000;
6866 97 : if (fSuppressTopSpacingMac5) a32Bit |= 0x00010000;
6867 97 : if (fTruncDxaExpand) a32Bit |= 0x00020000;
6868 97 : if (fPrintBodyBeforeHdr) a32Bit |= 0x00040000;
6869 97 : if (fNoLeading) a32Bit |= 0x00080000;
6870 97 : if (fCompatabilityOptions_Unknown1_21) a32Bit |= 0x00100000;
6871 97 : if (fMWSmallCaps) a32Bit |= 0x00200000;
6872 97 : if (fCompatabilityOptions_Unknown1_23) a32Bit |= 0x00400000;
6873 97 : if (fCompatabilityOptions_Unknown1_24) a32Bit |= 0x00800000;
6874 97 : if (fCompatabilityOptions_Unknown1_25) a32Bit |= 0x01000000;
6875 97 : if (fCompatabilityOptions_Unknown1_26) a32Bit |= 0x02000000;
6876 97 : if (fCompatabilityOptions_Unknown1_27) a32Bit |= 0x04000000;
6877 97 : if (fCompatabilityOptions_Unknown1_28) a32Bit |= 0x08000000;
6878 97 : if (fCompatabilityOptions_Unknown1_29) a32Bit |= 0x10000000;
6879 97 : if (fCompatabilityOptions_Unknown1_30) a32Bit |= 0x20000000;
6880 97 : if (fCompatabilityOptions_Unknown1_31) a32Bit |= 0x40000000;
6881 97 : if (fUsePrinterMetrics) a32Bit |= 0x80000000;
6882 97 : return a32Bit;
6883 : }
6884 :
6885 : // i#78591#
6886 80 : void WW8Dop::SetCompatabilityOptions2(sal_uInt32 a32Bit)
6887 : {
6888 80 : fCompatabilityOptions_Unknown2_1 = ( a32Bit & 0x00000001 );
6889 80 : fCompatabilityOptions_Unknown2_2 = ( a32Bit & 0x00000002 ) >> 1 ;
6890 80 : fDontUseHTMLAutoSpacing = ( a32Bit & 0x00000004 ) >> 2 ;
6891 80 : fCompatabilityOptions_Unknown2_4 = ( a32Bit & 0x00000008 ) >> 3 ;
6892 80 : fCompatabilityOptions_Unknown2_5 = ( a32Bit & 0x00000010 ) >> 4 ;
6893 80 : fCompatabilityOptions_Unknown2_6 = ( a32Bit & 0x00000020 ) >> 5 ;
6894 80 : fCompatabilityOptions_Unknown2_7 = ( a32Bit & 0x00000040 ) >> 6 ;
6895 80 : fCompatabilityOptions_Unknown2_8 = ( a32Bit & 0x00000080 ) >> 7 ;
6896 80 : fCompatabilityOptions_Unknown2_9 = ( a32Bit & 0x00000100 ) >> 8 ;
6897 80 : fCompatabilityOptions_Unknown2_10 = ( a32Bit & 0x00000200 ) >> 9 ;
6898 80 : fCompatabilityOptions_Unknown2_11 = ( a32Bit & 0x00000400 ) >> 10 ;
6899 80 : fCompatabilityOptions_Unknown2_12 = ( a32Bit & 0x00000800 ) >> 11 ;
6900 80 : fCompatabilityOptions_Unknown2_13 = ( a32Bit & 0x00001000 ) >> 12 ;
6901 80 : fCompatabilityOptions_Unknown2_14 = ( a32Bit & 0x00002000 ) >> 13 ;
6902 80 : fCompatabilityOptions_Unknown2_15 = ( a32Bit & 0x00004000 ) >> 14 ;
6903 80 : fCompatabilityOptions_Unknown2_16 = ( a32Bit & 0x00008000 ) >> 15 ;
6904 80 : fCompatabilityOptions_Unknown2_17 = ( a32Bit & 0x00010000 ) >> 16 ;
6905 80 : fCompatabilityOptions_Unknown2_18 = ( a32Bit & 0x00020000 ) >> 17 ;
6906 80 : fCompatabilityOptions_Unknown2_19 = ( a32Bit & 0x00040000 ) >> 18 ;
6907 80 : fCompatabilityOptions_Unknown2_20 = ( a32Bit & 0x00080000 ) >> 19 ;
6908 80 : fCompatabilityOptions_Unknown2_21 = ( a32Bit & 0x00100000 ) >> 20 ;
6909 80 : fCompatabilityOptions_Unknown2_22 = ( a32Bit & 0x00200000 ) >> 21 ;
6910 80 : fCompatabilityOptions_Unknown2_23 = ( a32Bit & 0x00400000 ) >> 22 ;
6911 80 : fCompatabilityOptions_Unknown2_24 = ( a32Bit & 0x00800800 ) >> 23 ;
6912 80 : fCompatabilityOptions_Unknown2_25 = ( a32Bit & 0x01000800 ) >> 24 ;
6913 80 : fCompatabilityOptions_Unknown2_26 = ( a32Bit & 0x02000800 ) >> 25 ;
6914 80 : fCompatabilityOptions_Unknown2_27 = ( a32Bit & 0x04000800 ) >> 26 ;
6915 80 : fCompatabilityOptions_Unknown2_28 = ( a32Bit & 0x08000800 ) >> 27 ;
6916 80 : fCompatabilityOptions_Unknown2_29 = ( a32Bit & 0x10000800 ) >> 28 ;
6917 80 : fCompatabilityOptions_Unknown2_30 = ( a32Bit & 0x20000800 ) >> 29 ;
6918 80 : fCompatabilityOptions_Unknown2_31 = ( a32Bit & 0x40000800 ) >> 30 ;
6919 80 : fCompatabilityOptions_Unknown2_32 = ( a32Bit & 0x80000000 ) >> 31 ;
6920 80 : }
6921 :
6922 85 : sal_uInt32 WW8Dop::GetCompatabilityOptions2() const
6923 : {
6924 85 : sal_uInt32 a32Bit = 0;
6925 85 : if (fCompatabilityOptions_Unknown2_1) a32Bit |= 0x00000001;
6926 85 : if (fCompatabilityOptions_Unknown2_2) a32Bit |= 0x00000002;
6927 85 : if (fDontUseHTMLAutoSpacing) a32Bit |= 0x00000004;
6928 85 : if (fCompatabilityOptions_Unknown2_4) a32Bit |= 0x00000008;
6929 85 : if (fCompatabilityOptions_Unknown2_5) a32Bit |= 0x00000010;
6930 85 : if (fCompatabilityOptions_Unknown2_6) a32Bit |= 0x00000020;
6931 85 : if (fCompatabilityOptions_Unknown2_7) a32Bit |= 0x00000040;
6932 85 : if (fCompatabilityOptions_Unknown2_8) a32Bit |= 0x00000080;
6933 85 : if (fCompatabilityOptions_Unknown2_9) a32Bit |= 0x00000100;
6934 85 : if (fCompatabilityOptions_Unknown2_10) a32Bit |= 0x00000200;
6935 85 : if (fCompatabilityOptions_Unknown2_11) a32Bit |= 0x00000400;
6936 85 : if (fCompatabilityOptions_Unknown2_12) a32Bit |= 0x00000800;
6937 85 : if (fCompatabilityOptions_Unknown2_13) a32Bit |= 0x00001000;
6938 : //#i42909# set thai "line breaking rules" compatibility option
6939 : // pflin, wonder whether bUseThaiLineBreakingRules is correct
6940 : // when importing word document.
6941 85 : if (bUseThaiLineBreakingRules) a32Bit |= 0x00002000;
6942 85 : else if (fCompatabilityOptions_Unknown2_14) a32Bit |= 0x00002000;
6943 85 : if (fCompatabilityOptions_Unknown2_15) a32Bit |= 0x00004000;
6944 85 : if (fCompatabilityOptions_Unknown2_16) a32Bit |= 0x00008000;
6945 85 : if (fCompatabilityOptions_Unknown2_17) a32Bit |= 0x00010000;
6946 85 : if (fCompatabilityOptions_Unknown2_18) a32Bit |= 0x00020000;
6947 85 : if (fCompatabilityOptions_Unknown2_19) a32Bit |= 0x00040000;
6948 85 : if (fCompatabilityOptions_Unknown2_20) a32Bit |= 0x00080000;
6949 85 : if (fCompatabilityOptions_Unknown2_21) a32Bit |= 0x00100000;
6950 85 : if (fCompatabilityOptions_Unknown2_22) a32Bit |= 0x00200000;
6951 85 : if (fCompatabilityOptions_Unknown2_23) a32Bit |= 0x00400000;
6952 85 : if (fCompatabilityOptions_Unknown2_24) a32Bit |= 0x00800000;
6953 85 : if (fCompatabilityOptions_Unknown2_25) a32Bit |= 0x01000000;
6954 85 : if (fCompatabilityOptions_Unknown2_26) a32Bit |= 0x02000000;
6955 85 : if (fCompatabilityOptions_Unknown2_27) a32Bit |= 0x04000000;
6956 85 : if (fCompatabilityOptions_Unknown2_28) a32Bit |= 0x08000000;
6957 85 : if (fCompatabilityOptions_Unknown2_29) a32Bit |= 0x10000000;
6958 85 : if (fCompatabilityOptions_Unknown2_30) a32Bit |= 0x20000000;
6959 85 : if (fCompatabilityOptions_Unknown2_31) a32Bit |= 0x40000000;
6960 85 : if (fCompatabilityOptions_Unknown2_32) a32Bit |= 0x80000000;
6961 85 : return a32Bit;
6962 : }
6963 :
6964 12 : bool WW8Dop::Write(SvStream& rStrm, WW8Fib& rFib) const
6965 : {
6966 12 : const int nMaxDopLen = 610;
6967 12 : sal_uInt32 nLen = 8 == rFib.nVersion ? nMaxDopLen : 84;
6968 12 : rFib.fcDop = rStrm.Tell();
6969 12 : rFib.lcbDop = nLen;
6970 :
6971 : sal_uInt8 aData[ nMaxDopLen ];
6972 12 : memset( aData, 0, nMaxDopLen );
6973 12 : sal_uInt8* pData = aData;
6974 :
6975 : // dann mal die Daten auswerten
6976 : sal_uInt16 a16Bit;
6977 : sal_uInt8 a8Bit;
6978 :
6979 12 : a16Bit = 0; // 0 0x00
6980 12 : if (fFacingPages)
6981 2 : a16Bit |= 0x0001;
6982 12 : if (fWidowControl)
6983 12 : a16Bit |= 0x0002;
6984 12 : if (fPMHMainDoc)
6985 0 : a16Bit |= 0x0004;
6986 12 : a16Bit |= ( 0x0018 & (grfSuppression << 3));
6987 12 : a16Bit |= ( 0x0060 & (fpc << 5));
6988 12 : a16Bit |= ( 0xff00 & (grpfIhdt << 8));
6989 12 : Set_UInt16( pData, a16Bit );
6990 :
6991 12 : a16Bit = 0; // 2 0x02
6992 12 : a16Bit |= ( 0x0003 & rncFtn );
6993 12 : a16Bit |= ( ~0x0003 & (nFtn << 2));
6994 12 : Set_UInt16( pData, a16Bit );
6995 :
6996 12 : a8Bit = 0; // 4 0x04
6997 12 : if( fOutlineDirtySave ) a8Bit |= 0x01;
6998 12 : Set_UInt8( pData, a8Bit );
6999 :
7000 12 : a8Bit = 0; // 5 0x05
7001 12 : if( fOnlyMacPics ) a8Bit |= 0x01;
7002 12 : if( fOnlyWinPics ) a8Bit |= 0x02;
7003 12 : if( fLabelDoc ) a8Bit |= 0x04;
7004 12 : if( fHyphCapitals ) a8Bit |= 0x08;
7005 12 : if( fAutoHyphen ) a8Bit |= 0x10;
7006 12 : if( fFormNoFields ) a8Bit |= 0x20;
7007 12 : if( fLinkStyles ) a8Bit |= 0x40;
7008 12 : if( fRevMarking ) a8Bit |= 0x80;
7009 12 : Set_UInt8( pData, a8Bit );
7010 :
7011 12 : a8Bit = 0; // 6 0x06
7012 12 : if( fBackup ) a8Bit |= 0x01;
7013 12 : if( fExactCWords ) a8Bit |= 0x02;
7014 12 : if( fPagHidden ) a8Bit |= 0x04;
7015 12 : if( fPagResults ) a8Bit |= 0x08;
7016 12 : if( fLockAtn ) a8Bit |= 0x10;
7017 12 : if( fMirrorMargins ) a8Bit |= 0x20;
7018 12 : if( fReadOnlyRecommended ) a8Bit |= 0x40;
7019 12 : if( fDfltTrueType ) a8Bit |= 0x80;
7020 12 : Set_UInt8( pData, a8Bit );
7021 :
7022 12 : a8Bit = 0; // 7 0x07
7023 12 : if( fPagSuppressTopSpacing ) a8Bit |= 0x01;
7024 12 : if( fProtEnabled ) a8Bit |= 0x02;
7025 12 : if( fDispFormFldSel ) a8Bit |= 0x04;
7026 12 : if( fRMView ) a8Bit |= 0x08;
7027 12 : if( fRMPrint ) a8Bit |= 0x10;
7028 12 : if( fWriteReservation ) a8Bit |= 0x20;
7029 12 : if( fLockRev ) a8Bit |= 0x40;
7030 12 : if( fEmbedFonts ) a8Bit |= 0x80;
7031 12 : Set_UInt8( pData, a8Bit );
7032 :
7033 12 : a8Bit = 0; // 8 0x08
7034 12 : if( copts_fNoTabForInd ) a8Bit |= 0x01;
7035 12 : if( copts_fNoSpaceRaiseLower ) a8Bit |= 0x02;
7036 12 : if( copts_fSupressSpbfAfterPgBrk ) a8Bit |= 0x04;
7037 12 : if( copts_fWrapTrailSpaces ) a8Bit |= 0x08;
7038 12 : if( copts_fMapPrintTextColor ) a8Bit |= 0x10;
7039 12 : if( copts_fNoColumnBalance ) a8Bit |= 0x20;
7040 12 : if( copts_fConvMailMergeEsc ) a8Bit |= 0x40;
7041 12 : if( copts_fSupressTopSpacing ) a8Bit |= 0x80;
7042 12 : Set_UInt8( pData, a8Bit );
7043 :
7044 12 : a8Bit = 0; // 9 0x09
7045 12 : if( copts_fOrigWordTableRules ) a8Bit |= 0x01;
7046 12 : if( copts_fTransparentMetafiles ) a8Bit |= 0x02;
7047 12 : if( copts_fShowBreaksInFrames ) a8Bit |= 0x04;
7048 12 : if( copts_fSwapBordersFacingPgs ) a8Bit |= 0x08;
7049 12 : if( copts_fExpShRtn ) a8Bit |= 0x20; // #i56856#
7050 12 : Set_UInt8( pData, a8Bit );
7051 :
7052 12 : Set_UInt16( pData, dxaTab ); // 10 0x0a
7053 12 : Set_UInt16( pData, wSpare ); // 12 0x0c
7054 12 : Set_UInt16( pData, dxaHotZ ); // 14 0x0e
7055 12 : Set_UInt16( pData, cConsecHypLim ); // 16 0x10
7056 12 : Set_UInt16( pData, wSpare2 ); // 18 0x12
7057 12 : Set_UInt32( pData, dttmCreated ); // 20 0x14
7058 12 : Set_UInt32( pData, dttmRevised ); // 24 0x18
7059 12 : Set_UInt32( pData, dttmLastPrint ); // 28 0x1c
7060 12 : Set_UInt16( pData, nRevision ); // 32 0x20
7061 12 : Set_UInt32( pData, tmEdited ); // 34 0x22
7062 12 : Set_UInt32( pData, cWords ); // 38 0x26
7063 12 : Set_UInt32( pData, cCh ); // 42 0x2a
7064 12 : Set_UInt16( pData, cPg ); // 46 0x2e
7065 12 : Set_UInt32( pData, cParas ); // 48 0x30
7066 :
7067 12 : a16Bit = 0; // 52 0x34
7068 12 : a16Bit |= ( 0x0003 & rncEdn );
7069 12 : a16Bit |= (~0x0003 & ( nEdn << 2));
7070 12 : Set_UInt16( pData, a16Bit );
7071 :
7072 12 : a16Bit = 0; // 54 0x36
7073 12 : a16Bit |= (0x0003 & epc );
7074 12 : a16Bit |= (0x003c & (nfcFtnRef << 2));
7075 12 : a16Bit |= (0x03c0 & (nfcEdnRef << 6));
7076 12 : if( fPrintFormData ) a16Bit |= 0x0400;
7077 12 : if( fSaveFormData ) a16Bit |= 0x0800;
7078 12 : if( fShadeFormData ) a16Bit |= 0x1000;
7079 12 : if( fWCFtnEdn ) a16Bit |= 0x8000;
7080 12 : Set_UInt16( pData, a16Bit );
7081 :
7082 12 : Set_UInt32( pData, cLines ); // 56 0x38
7083 12 : Set_UInt32( pData, cWordsFtnEnd ); // 60 0x3c
7084 12 : Set_UInt32( pData, cChFtnEdn ); // 64 0x40
7085 12 : Set_UInt16( pData, cPgFtnEdn ); // 68 0x44
7086 12 : Set_UInt32( pData, cParasFtnEdn ); // 70 0x46
7087 12 : Set_UInt32( pData, cLinesFtnEdn ); // 74 0x4a
7088 12 : Set_UInt32( pData, lKeyProtDoc ); // 78 0x4e
7089 :
7090 12 : a16Bit = 0; // 82 0x52
7091 12 : if (wvkSaved)
7092 12 : a16Bit |= 0x0007;
7093 12 : a16Bit |= (0x0ff8 & (wScaleSaved << 3));
7094 12 : a16Bit |= (0x3000 & (zkSaved << 12));
7095 12 : Set_UInt16( pData, a16Bit );
7096 :
7097 12 : if( 8 == rFib.nVersion )
7098 : {
7099 12 : Set_UInt32(pData, GetCompatabilityOptions()); // 84 0x54
7100 :
7101 12 : Set_UInt16( pData, adt ); // 88 0x58
7102 :
7103 12 : doptypography.WriteToMem(pData); // 400 0x190
7104 :
7105 12 : memcpy( pData, &dogrid, sizeof( WW8_DOGRID ));
7106 12 : pData += sizeof( WW8_DOGRID );
7107 :
7108 12 : a16Bit = 0x12; // lvl auf 9 setzen // 410 0x19a
7109 12 : if( fHtmlDoc ) a16Bit |= 0x0200;
7110 12 : if( fSnapBorder ) a16Bit |= 0x0800;
7111 12 : if( fIncludeHeader ) a16Bit |= 0x1000;
7112 12 : if( fIncludeFooter ) a16Bit |= 0x2000;
7113 12 : if( fForcePageSizePag ) a16Bit |= 0x4000;
7114 12 : if( fMinFontSizePag ) a16Bit |= 0x8000;
7115 12 : Set_UInt16( pData, a16Bit );
7116 :
7117 12 : a16Bit = 0; // 412 0x19c
7118 12 : if( fHaveVersions ) a16Bit |= 0x0001;
7119 12 : if( fAutoVersion ) a16Bit |= 0x0002;
7120 12 : Set_UInt16( pData, a16Bit );
7121 :
7122 12 : pData += 12; // 414 0x19e
7123 :
7124 12 : Set_UInt32( pData, cChWS ); // 426 0x1aa
7125 12 : Set_UInt32( pData, cChWSFtnEdn ); // 430 0x1ae
7126 12 : Set_UInt32( pData, grfDocEvents ); // 434 0x1b2
7127 :
7128 12 : pData += 4+30+8; // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc
7129 :
7130 12 : Set_UInt32( pData, cDBC ); // 480 0x1e0
7131 12 : Set_UInt32( pData, cDBCFtnEdn ); // 484 0x1e4
7132 :
7133 12 : pData += 1 * sizeof( sal_Int32); // 488 0x1e8
7134 :
7135 12 : Set_UInt16( pData, nfcFtnRef ); // 492 0x1ec
7136 12 : Set_UInt16( pData, nfcEdnRef ); // 494 0x1ee
7137 12 : Set_UInt16( pData, hpsZoonFontPag ); // 496 0x1f0
7138 12 : Set_UInt16( pData, dywDispPag ); // 498 0x1f2
7139 :
7140 : //500 -> 508, Appear to be repeated here in 2000+
7141 12 : pData += 8;
7142 12 : Set_UInt32(pData, GetCompatabilityOptions());
7143 12 : Set_UInt32(pData, GetCompatabilityOptions2());
7144 12 : pData += 32;
7145 :
7146 12 : a16Bit = 0;
7147 12 : if (fAcetateShowMarkup)
7148 0 : a16Bit |= 0x1000;
7149 : //Word XP at least requires fAcetateShowMarkup to honour fAcetateShowAtn
7150 12 : if (fAcetateShowAtn)
7151 : {
7152 12 : a16Bit |= 0x1000;
7153 12 : a16Bit |= 0x2000;
7154 : }
7155 12 : Set_UInt16(pData, a16Bit);
7156 :
7157 12 : pData += 48;
7158 12 : a16Bit = 0x0080;
7159 12 : Set_UInt16(pData, a16Bit);
7160 : }
7161 12 : rStrm.Write( aData, nLen );
7162 12 : return 0 == rStrm.GetError();
7163 : }
7164 :
7165 72 : void WW8DopTypography::ReadFromMem(sal_uInt8 *&pData)
7166 : {
7167 72 : sal_uInt16 a16Bit = Get_UShort(pData);
7168 72 : fKerningPunct = (a16Bit & 0x0001);
7169 72 : iJustification = (a16Bit & 0x0006) >> 1;
7170 72 : iLevelOfKinsoku = (a16Bit & 0x0018) >> 3;
7171 72 : f2on1 = (a16Bit & 0x0020) >> 5;
7172 72 : reserved1 = (a16Bit & 0x03C0) >> 6;
7173 72 : reserved2 = (a16Bit & 0xFC00) >> 10;
7174 :
7175 72 : cchFollowingPunct = Get_Short(pData);
7176 72 : cchLeadingPunct = Get_Short(pData);
7177 :
7178 : sal_Int16 i;
7179 7344 : for (i=0; i < nMaxFollowing; ++i)
7180 7272 : rgxchFPunct[i] = Get_Short(pData);
7181 3744 : for (i=0; i < nMaxLeading; ++i)
7182 3672 : rgxchLPunct[i] = Get_Short(pData);
7183 :
7184 72 : if (cchFollowingPunct >= 0 && cchFollowingPunct < nMaxFollowing)
7185 70 : rgxchFPunct[cchFollowingPunct]=0;
7186 : else
7187 2 : rgxchFPunct[nMaxFollowing - 1]=0;
7188 :
7189 72 : if (cchLeadingPunct >= 0 && cchLeadingPunct < nMaxLeading)
7190 71 : rgxchLPunct[cchLeadingPunct]=0;
7191 : else
7192 1 : rgxchLPunct[nMaxLeading - 1]=0;
7193 :
7194 72 : }
7195 :
7196 12 : void WW8DopTypography::WriteToMem(sal_uInt8 *&pData) const
7197 : {
7198 12 : sal_uInt16 a16Bit = sal_uInt16(fKerningPunct);
7199 12 : a16Bit |= (iJustification << 1) & 0x0006;
7200 12 : a16Bit |= (iLevelOfKinsoku << 3) & 0x0018;
7201 12 : a16Bit |= (int(f2on1) << 5) & 0x0020;
7202 12 : a16Bit |= (reserved1 << 6) & 0x03C0;
7203 12 : a16Bit |= (reserved2 << 10) & 0xFC00;
7204 12 : Set_UInt16(pData,a16Bit);
7205 :
7206 12 : Set_UInt16(pData,cchFollowingPunct);
7207 12 : Set_UInt16(pData,cchLeadingPunct);
7208 :
7209 : sal_Int16 i;
7210 1224 : for (i=0; i < nMaxFollowing; ++i)
7211 1212 : Set_UInt16(pData,rgxchFPunct[i]);
7212 624 : for (i=0; i < nMaxLeading; ++i)
7213 612 : Set_UInt16(pData,rgxchLPunct[i]);
7214 12 : }
7215 :
7216 55 : sal_uInt16 WW8DopTypography::GetConvertedLang() const
7217 : {
7218 : sal_uInt16 nLang;
7219 : //I have assumed peoples republic/taiwan == simplified/traditional
7220 :
7221 : //This isn't a documented issue, so we might have it all wrong,
7222 : //i.e. i.e. whats with the powers of two ?
7223 :
7224 : /*
7225 : One example of 3 for reserved1 which was really Japanese, perhaps last bit
7226 : is for some other use ?, or redundant. If more examples trigger the assert
7227 : we might be able to figure it out.
7228 : */
7229 55 : switch(reserved1 & 0xE)
7230 : {
7231 : case 2: //Japan
7232 19 : nLang = LANGUAGE_JAPANESE;
7233 19 : break;
7234 : case 4: //Chinese (Peoples Republic)
7235 12 : nLang = LANGUAGE_CHINESE_SIMPLIFIED;
7236 12 : break;
7237 : case 6: //Korean
7238 12 : nLang = LANGUAGE_KOREAN;
7239 12 : break;
7240 : case 8: //Chinese (Taiwan)
7241 12 : nLang = LANGUAGE_CHINESE_TRADITIONAL;
7242 12 : break;
7243 : default:
7244 : OSL_ENSURE(!this, "Unknown MS Asian Typography language, report");
7245 0 : nLang = LANGUAGE_CHINESE_SIMPLIFIED_LEGACY;
7246 0 : break;
7247 : case 0:
7248 : //And here we have the possibility that it says 2, but its really
7249 : //a bug and only japanese level 2 has been selected after a custom
7250 : //version was chosen on last save!
7251 0 : nLang = LANGUAGE_JAPANESE;
7252 0 : break;
7253 : }
7254 55 : return nLang;
7255 : }
7256 :
7257 : // Sprms
7258 :
7259 483336 : sal_uInt16 wwSprmParser::GetSprmTailLen(sal_uInt16 nId, const sal_uInt8* pSprm)
7260 : const
7261 : {
7262 483336 : SprmInfo aSprm = GetSprmInfo(nId);
7263 483336 : sal_uInt16 nL = 0; // number of Bytes to read
7264 :
7265 : //sprmPChgTabs
7266 483336 : switch( nId )
7267 : {
7268 : case 23:
7269 : case 0xC615:
7270 1929 : if( pSprm[1 + mnDelta] != 255 )
7271 1929 : nL = static_cast< sal_uInt16 >(pSprm[1 + mnDelta] + aSprm.nLen);
7272 : else
7273 : {
7274 0 : sal_uInt8 nDel = pSprm[2 + mnDelta];
7275 0 : sal_uInt8 nIns = pSprm[3 + mnDelta + 4 * nDel];
7276 :
7277 0 : nL = 2 + 4 * nDel + 3 * nIns;
7278 : }
7279 1929 : break;
7280 : case 0xD608:
7281 5297 : nL = SVBT16ToShort( &pSprm[1 + mnDelta] );
7282 5297 : break;
7283 : default:
7284 476110 : switch (aSprm.nVari)
7285 : {
7286 : case L_FIX:
7287 416029 : nL = aSprm.nLen; // Excl. Token
7288 416029 : break;
7289 : case L_VAR:
7290 : // Variable 1-Byte Length?
7291 : // Excl. Token + Var-Lengthbyte
7292 60081 : nL = static_cast< sal_uInt16 >(pSprm[1 + mnDelta] + aSprm.nLen);
7293 60081 : break;
7294 : case L_VAR2:
7295 : // Variable 2-Byte Length?
7296 : // Excl. Token + Var-Lengthbyte
7297 0 : nL = static_cast< sal_uInt16 >(SVBT16ToShort( &pSprm[1 + mnDelta] ) + aSprm.nLen - 1);
7298 0 : break;
7299 : default:
7300 : OSL_ENSURE(!this, "Unknown sprm variant");
7301 0 : break;
7302 : }
7303 476110 : break;
7304 : }
7305 483336 : return nL;
7306 : }
7307 :
7308 : // one or two bytes at the beginning at the sprm id
7309 451098 : sal_uInt16 wwSprmParser::GetSprmId(const sal_uInt8* pSp) const
7310 : {
7311 451098 : ASSERT_RET_ON_FAIL(pSp, "Why GetSprmId with pSp of 0", 0);
7312 :
7313 451098 : sal_uInt16 nId = 0;
7314 :
7315 451098 : if (ww::IsSevenMinus(meVersion))
7316 : {
7317 4170 : nId = *pSp;
7318 4170 : if (0x0100 < nId)
7319 0 : nId = 0;
7320 : }
7321 : else
7322 : {
7323 446928 : nId = SVBT16ToShort(pSp);
7324 446928 : if (0x0800 > nId)
7325 3980 : nId = 0;
7326 : }
7327 :
7328 451098 : return nId;
7329 : }
7330 :
7331 : // with tokens and length byte
7332 483336 : sal_uInt16 wwSprmParser::GetSprmSize(sal_uInt16 nId, const sal_uInt8* pSprm) const
7333 : {
7334 483336 : return GetSprmTailLen(nId, pSprm) + 1 + mnDelta + SprmDataOfs(nId);
7335 : }
7336 :
7337 873173 : sal_uInt8 wwSprmParser::SprmDataOfs(sal_uInt16 nId) const
7338 : {
7339 873173 : return GetSprmInfo(nId).nVari;
7340 : }
7341 :
7342 389837 : sal_uInt16 wwSprmParser::DistanceToData(sal_uInt16 nId) const
7343 : {
7344 389837 : return 1 + mnDelta + SprmDataOfs(nId);
7345 : }
7346 :
7347 9143 : sal_uInt8* wwSprmParser::findSprmData(sal_uInt16 nId, sal_uInt8* pSprms,
7348 : sal_uInt16 nLen) const
7349 : {
7350 31882 : while (nLen >= MinSprmLen())
7351 : {
7352 19205 : sal_uInt16 nAktId = GetSprmId(pSprms);
7353 : // gib Zeiger auf Daten
7354 19205 : sal_uInt16 nSize = GetSprmSize(nAktId, pSprms);
7355 :
7356 19205 : bool bValid = nSize <= nLen;
7357 :
7358 : SAL_WARN_IF(!bValid, "sw.ww8",
7359 : "sprm 0x" << std::hex << nAktId << std::dec << " longer than remaining bytes, " <<
7360 : nSize << " vs " << nLen << "doc or parser is wrong");
7361 :
7362 19205 : if (nAktId == nId && bValid) // Sprm found
7363 5609 : return pSprms + DistanceToData(nId);
7364 :
7365 : //Clip to available size if wrong
7366 13596 : nSize = std::min(nSize, nLen);
7367 13596 : pSprms += nSize;
7368 13596 : nLen -= nSize;
7369 : }
7370 : // Sprm not found
7371 3534 : return 0;
7372 : }
7373 :
7374 172 : SEPr::SEPr() :
7375 : bkc(2), fTitlePage(0), fAutoPgn(0), nfcPgn(0), fUnlocked(0), cnsPgn(0),
7376 : fPgnRestart(0), fEndNote(1), lnc(0), grpfIhdt(0), nLnnMod(0), dxaLnn(0),
7377 : dxaPgn(720), dyaPgn(720), fLBetween(0), vjc(0), dmBinFirst(0),
7378 : dmBinOther(0), dmPaperReq(0), fPropRMark(0), ibstPropRMark(0),
7379 : dttmPropRMark(0), dxtCharSpace(0), dyaLinePitch(0), clm(0), reserved1(0),
7380 : dmOrientPage(0), iHeadingPgn(0), pgnStart(1), lnnMin(0), wTextFlow(0),
7381 : reserved2(0), pgbApplyTo(0), pgbPageDepth(0), pgbOffsetFrom(0),
7382 : xaPage(lLetterWidth), yaPage(lLetterHeight), xaPageNUp(lLetterWidth), yaPageNUp(lLetterHeight),
7383 : dxaLeft(1800), dxaRight(1800), dyaTop(1440), dyaBottom(1440), dzaGutter(0),
7384 : dyaHdrTop(720), dyaHdrBottom(720), ccolM1(0), fEvenlySpaced(1),
7385 : reserved3(0), fBiDi(0), fFacingCol(0), fRTLGutter(0), fRTLAlignment(0),
7386 : dxaColumns(720), dxaColumnWidth(0), dmOrientFirst(0), fLayout(0),
7387 172 : reserved4(0)
7388 : {
7389 172 : memset(rgdxaColumnWidthSpacing, 0, sizeof(rgdxaColumnWidthSpacing));
7390 172 : }
7391 :
7392 16363 : bool checkSeek(SvStream &rSt, sal_uInt32 nOffset)
7393 : {
7394 16363 : return (rSt.Seek(nOffset) == static_cast<sal_Size>(nOffset));
7395 : }
7396 :
7397 1360 : bool checkRead(SvStream &rSt, void *pDest, sal_uInt32 nLength)
7398 : {
7399 1360 : return (rSt.Read(pDest, nLength) == static_cast<sal_Size>(nLength));
7400 33 : }
7401 :
7402 : #ifdef OSL_BIGENDIAN
7403 : void swapEndian(sal_Unicode *pString)
7404 : {
7405 : for (sal_Unicode *pWork = pString; *pWork; ++pWork)
7406 : *pWork = OSL_SWAPWORD(*pWork);
7407 : }
7408 : #endif
7409 :
7410 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|