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 0 : bool TestBeltAndBraces(SvStream& rStrm)
86 : {
87 0 : bool bRet = false;
88 0 : sal_uInt32 nOldPos = rStrm.Tell();
89 0 : sal_Unicode nBelt(0);
90 0 : rStrm.ReadUInt16( nBelt );
91 0 : nBelt *= sizeof(sal_Unicode);
92 0 : if (rStrm.good() && (rStrm.remainingSize() >= (nBelt + sizeof(sal_Unicode))))
93 : {
94 0 : rStrm.SeekRel(nBelt);
95 0 : if (rStrm.good())
96 : {
97 0 : sal_Unicode cBraces(0);
98 0 : rStrm.ReadUInt16( cBraces );
99 0 : if (rStrm.good() && cBraces == 0)
100 0 : bRet = true;
101 : }
102 : }
103 0 : rStrm.Seek(nOldPos);
104 0 : return bRet;
105 : }
106 : }
107 :
108 0 : inline bool operator==(const SprmInfo &rFirst, const SprmInfo &rSecond)
109 : {
110 0 : return (rFirst.nId == rSecond.nId);
111 : }
112 :
113 0 : 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 0 : static wwSprmSearcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
261 0 : 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 0 : 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 0 : static wwSprmSearcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
783 0 : return &aSprmSrch;
784 : };
785 :
786 0 : wwSprmParser::wwSprmParser(ww::WordVersion eVersion) : meVersion(eVersion)
787 : {
788 : OSL_ENSURE((meVersion >= ww::eWW2 && meVersion <= ww::eWW8),
789 : "Impossible value for version");
790 :
791 0 : mnDelta = (ww::IsSevenMinus(meVersion)) ? 0 : 1;
792 :
793 0 : if (meVersion <= ww::eWW2)
794 0 : mpKnownSprms = GetWW2SprmSearcher();
795 0 : else if (meVersion < ww::eWW8)
796 0 : mpKnownSprms = GetWW6SprmSearcher();
797 : else
798 0 : mpKnownSprms = GetWW8SprmSearcher();
799 0 : }
800 :
801 0 : SprmInfo wwSprmParser::GetSprmInfo(sal_uInt16 nId) const
802 : {
803 : // Find sprm
804 0 : SprmInfo aSrch={0,0,0};
805 0 : aSrch.nId = nId;
806 0 : const SprmInfo* pFound = mpKnownSprms->search(aSrch);
807 0 : if (pFound == 0)
808 : {
809 : OSL_ENSURE(ww::IsEightPlus(meVersion),
810 : "Unknown ww7- sprm, dangerous, report to development");
811 :
812 0 : aSrch.nId = 0;
813 0 : aSrch.nLen = 0;
814 : //All the unknown ww7 sprms appear to be variable (which makes sense)
815 0 : aSrch.nVari = L_VAR;
816 :
817 0 : if (ww::IsEightPlus(meVersion)) //We can recover perfectly in this case
818 : {
819 0 : aSrch.nVari = L_FIX;
820 0 : switch (nId >> 13)
821 : {
822 : case 0:
823 : case 1:
824 0 : aSrch.nLen = 1;
825 0 : break;
826 : case 2:
827 0 : aSrch.nLen = 2;
828 0 : break;
829 : case 3:
830 0 : aSrch.nLen = 4;
831 0 : break;
832 : case 4:
833 : case 5:
834 0 : aSrch.nLen = 2;
835 0 : break;
836 : case 6:
837 0 : aSrch.nLen = 0;
838 0 : aSrch.nVari = L_VAR;
839 0 : break;
840 : case 7:
841 : default:
842 0 : aSrch.nLen = 3;
843 0 : break;
844 : }
845 : }
846 :
847 0 : pFound = &aSrch;
848 : }
849 0 : return *pFound;
850 : }
851 :
852 : //-end
853 :
854 0 : inline sal_uInt8 Get_Byte( sal_uInt8 *& p )
855 : {
856 0 : sal_uInt8 n = *p;
857 0 : p += 1;
858 0 : return n;
859 : }
860 :
861 0 : inline sal_uInt16 Get_UShort( sal_uInt8 *& p )
862 : {
863 0 : sal_uInt16 n = SVBT16ToShort( *(SVBT16*)p );
864 0 : p += 2;
865 0 : return n;
866 : }
867 :
868 0 : inline short Get_Short( sal_uInt8 *& p )
869 : {
870 0 : return Get_UShort(p);
871 : }
872 :
873 0 : inline sal_uLong Get_ULong( sal_uInt8 *& p )
874 : {
875 0 : sal_uLong n = SVBT32ToUInt32( *(SVBT32*)p );
876 0 : p += 4;
877 0 : return n;
878 : }
879 :
880 0 : inline long Get_Long( sal_uInt8 *& p )
881 : {
882 0 : return Get_ULong(p);
883 : }
884 :
885 0 : WW8SprmIter::WW8SprmIter(const sal_uInt8* pSprms_, long nLen_,
886 : const wwSprmParser &rParser)
887 0 : : mrSprmParser(rParser), pSprms( pSprms_), nRemLen( nLen_)
888 : {
889 0 : UpdateMyMembers();
890 0 : }
891 :
892 0 : void WW8SprmIter::SetSprms(const sal_uInt8* pSprms_, long nLen_)
893 : {
894 0 : pSprms = pSprms_;
895 0 : nRemLen = nLen_;
896 0 : UpdateMyMembers();
897 0 : }
898 :
899 0 : void WW8SprmIter::advance()
900 : {
901 0 : if (nRemLen > 0 )
902 : {
903 0 : sal_uInt16 nSize = nAktSize;
904 0 : if (nSize > nRemLen)
905 0 : nSize = nRemLen;
906 0 : pSprms += nSize;
907 0 : nRemLen -= nSize;
908 0 : UpdateMyMembers();
909 : }
910 0 : }
911 :
912 0 : void WW8SprmIter::UpdateMyMembers()
913 : {
914 0 : bool bValid = (pSprms && nRemLen >= mrSprmParser.MinSprmLen());
915 :
916 0 : if (bValid)
917 : {
918 0 : nAktId = mrSprmParser.GetSprmId(pSprms);
919 0 : nAktSize = mrSprmParser.GetSprmSize(nAktId, pSprms);
920 0 : pAktParams = pSprms + mrSprmParser.DistanceToData(nAktId);
921 0 : bValid = nAktSize <= nRemLen;
922 : SAL_WARN_IF(!bValid, "sw.ww8", "sprm longer than remaining bytes, doc or parser is wrong");
923 : }
924 :
925 0 : if (!bValid)
926 : {
927 0 : nAktId = 0;
928 0 : pAktParams = 0;
929 0 : nAktSize = 0;
930 0 : nRemLen = 0;
931 : }
932 0 : }
933 :
934 0 : const sal_uInt8* WW8SprmIter::FindSprm(sal_uInt16 nId)
935 : {
936 0 : while (GetSprms())
937 : {
938 0 : if (GetAktId() == nId)
939 0 : return GetAktParams(); // SPRM found!
940 0 : advance();
941 : }
942 :
943 0 : 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 0 : WW8PLCFx_PCDAttrs::WW8PLCFx_PCDAttrs(ww::WordVersion eVersion,
950 : WW8PLCFx_PCD* pPLCFx_PCD, const WW8ScannerBase* pBase)
951 0 : : WW8PLCFx(eVersion, true), pPcdI(pPLCFx_PCD->GetPLCFIter()),
952 : pPcd(pPLCFx_PCD), pGrpprls(pBase->pPieceGrpprls),
953 0 : nGrpprls(pBase->nPieceGrpprls)
954 : {
955 0 : }
956 :
957 0 : sal_uLong WW8PLCFx_PCDAttrs::GetIdx() const
958 : {
959 0 : return 0;
960 : }
961 :
962 0 : void WW8PLCFx_PCDAttrs::SetIdx( sal_uLong )
963 : {
964 0 : }
965 :
966 0 : bool WW8PLCFx_PCDAttrs::SeekPos(WW8_CP )
967 : {
968 0 : return true;
969 : }
970 :
971 0 : void WW8PLCFx_PCDAttrs::advance()
972 : {
973 0 : }
974 :
975 0 : WW8_CP WW8PLCFx_PCDAttrs::Where()
976 : {
977 0 : return ( pPcd ) ? pPcd->Where() : WW8_CP_MAX;
978 : }
979 :
980 0 : void WW8PLCFx_PCDAttrs::GetSprms(WW8PLCFxDesc* p)
981 : {
982 : void* pData;
983 :
984 0 : p->bRealLineEnd = false;
985 0 : 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 0 : sal_uInt16 nPrm = SVBT16ToShort( ( (WW8_PCD*)pData )->prm );
995 0 : 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 0 : 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 0 : p->pMemPos = 0;
1033 0 : p->nSprmsLen = 0;
1034 0 : sal_uInt8 nSprmListIdx = (sal_uInt8)((nPrm & 0xfe) >> 1);
1035 0 : 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 0 : WW8PLCFx_PCD::WW8PLCFx_PCD(ww::WordVersion eVersion, WW8PLCFpcd* pPLCFpcd,
1136 : WW8_CP nStartCp, bool bVer67P)
1137 0 : : WW8PLCFx(eVersion, false), nClipStart(-1)
1138 : {
1139 : // construct own iterator
1140 0 : pPcdI = new WW8PLCFpcd_Iter(*pPLCFpcd, nStartCp);
1141 0 : bVer67= bVer67P;
1142 0 : }
1143 :
1144 0 : WW8PLCFx_PCD::~WW8PLCFx_PCD()
1145 : {
1146 : // pPcd-Dtor which in called from WW8ScannerBase
1147 0 : delete pPcdI;
1148 0 : }
1149 :
1150 0 : sal_uLong WW8PLCFx_PCD::GetIMax() const
1151 : {
1152 0 : return pPcdI ? pPcdI->GetIMax() : 0;
1153 : }
1154 :
1155 0 : sal_uLong WW8PLCFx_PCD::GetIdx() const
1156 : {
1157 0 : return pPcdI ? pPcdI->GetIdx() : 0;
1158 : }
1159 :
1160 0 : void WW8PLCFx_PCD::SetIdx( sal_uLong nIdx )
1161 : {
1162 0 : if (pPcdI)
1163 0 : pPcdI->SetIdx( nIdx );
1164 0 : }
1165 :
1166 0 : bool WW8PLCFx_PCD::SeekPos(WW8_CP nCpPos)
1167 : {
1168 0 : 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 0 : long WW8PLCFx_PCD::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
1177 : {
1178 : void* pData;
1179 0 : rLen = 0;
1180 :
1181 0 : if ( !pPcdI || !pPcdI->Get(rStart, rEnd, pData) )
1182 : {
1183 0 : rStart = rEnd = WW8_CP_MAX;
1184 0 : return -1;
1185 : }
1186 0 : return pPcdI->GetIdx();
1187 : }
1188 :
1189 0 : void WW8PLCFx_PCD::advance()
1190 : {
1191 : OSL_ENSURE(pPcdI , "missing pPcdI");
1192 0 : if (pPcdI)
1193 0 : pPcdI->advance();
1194 0 : }
1195 :
1196 0 : WW8_FC WW8PLCFx_PCD::AktPieceStartCp2Fc( WW8_CP nCp )
1197 : {
1198 : WW8_CP nCpStart, nCpEnd;
1199 : void* pData;
1200 :
1201 0 : 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 0 : if( nCp < nCpStart )
1211 0 : nCp = nCpStart;
1212 0 : if( nCp >= nCpEnd )
1213 0 : nCp = nCpEnd - 1;
1214 :
1215 0 : bool bIsUnicode = false;
1216 0 : WW8_FC nFC = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
1217 0 : if( !bVer67 )
1218 0 : nFC = WW8PLCFx_PCD::TransformPieceAddress( nFC, bIsUnicode );
1219 :
1220 0 : return nFC + (nCp - nCpStart) * (bIsUnicode ? 2 : 1);
1221 : }
1222 :
1223 0 : void WW8PLCFx_PCD::AktPieceFc2Cp( WW8_CP& rStartPos, WW8_CP& rEndPos,
1224 : const WW8ScannerBase *pSBase )
1225 : {
1226 : //No point going anywhere with this
1227 0 : if ((rStartPos == WW8_CP_MAX) && (rEndPos == WW8_CP_MAX))
1228 0 : return;
1229 :
1230 0 : rStartPos = pSBase->WW8Fc2Cp( rStartPos );
1231 0 : rEndPos = pSBase->WW8Fc2Cp( rEndPos );
1232 : }
1233 :
1234 0 : WW8_CP WW8PLCFx_PCD::AktPieceStartFc2Cp( WW8_FC nStartPos )
1235 : {
1236 : WW8_CP nCpStart, nCpEnd;
1237 : void* pData;
1238 0 : if ( !pPcdI->Get( nCpStart, nCpEnd, pData ) )
1239 : {
1240 : OSL_ENSURE( !this, "AktPieceStartFc2Cp() - error" );
1241 0 : return WW8_CP_MAX;
1242 : }
1243 0 : bool bIsUnicode = false;
1244 0 : sal_Int32 nFcStart = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
1245 0 : if( !bVer67 )
1246 0 : nFcStart = WW8PLCFx_PCD::TransformPieceAddress( nFcStart, bIsUnicode );
1247 :
1248 0 : sal_Int32 nUnicodeFactor = bIsUnicode ? 2 : 1;
1249 :
1250 0 : if( nStartPos < nFcStart )
1251 0 : nStartPos = nFcStart;
1252 :
1253 0 : if( nStartPos >= nFcStart + (nCpEnd - nCpStart) * nUnicodeFactor )
1254 0 : nStartPos = nFcStart + (nCpEnd - nCpStart - 1) * nUnicodeFactor;
1255 :
1256 0 : 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 0 : WW8_BRCVer9::WW8_BRCVer9(const WW8_BRC& brcVer8)
1298 : {
1299 0 : if (brcVer8.isNil()) {
1300 0 : UInt32ToSVBT32(0, aBits1);
1301 0 : UInt32ToSVBT32(0xffffffff, aBits2);
1302 : }
1303 : else
1304 : {
1305 0 : sal_uInt32 _cv = brcVer8.ico() == 0 ? 0xff000000 // "auto" colour
1306 0 : : wwUtility::RGBToBGR(SwWW8ImplReader::GetCol(brcVer8.ico()));
1307 0 : *this = WW8_BRCVer9(_cv, brcVer8.dptLineWidth(), brcVer8.brcType(),
1308 0 : brcVer8.dptSpace(), brcVer8.fShadow(), brcVer8.fFrame());
1309 : }
1310 0 : }
1311 :
1312 0 : short WW8_BRC::DetermineBorderProperties(short *pSpace) const
1313 : {
1314 0 : WW8_BRCVer9 brcVer9(*this);
1315 0 : return brcVer9.DetermineBorderProperties(pSpace);
1316 : }
1317 :
1318 0 : 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 0 : nMSTotalWidth = (short)dptLineWidth() * 20 / 8;
1330 :
1331 : //Figure out the real size of the border according to word
1332 0 : 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 0 : 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 0 : if (pSpace)
1381 0 : *pSpace = (short)dptSpace() * 20; // convert from points to twips
1382 0 : 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 0 : WW8_CP WW8ScannerBase::WW8Fc2Cp( WW8_FC nFcPos ) const
1392 : {
1393 0 : WW8_CP nFallBackCpEnd = WW8_CP_MAX;
1394 0 : if( nFcPos == WW8_FC_MAX )
1395 0 : return nFallBackCpEnd;
1396 :
1397 : bool bIsUnicode;
1398 0 : if (pWw8Fib->nVersion >= 8)
1399 0 : bIsUnicode = false;
1400 : else
1401 0 : bIsUnicode = pWw8Fib->fExtChar ? true : false;
1402 :
1403 0 : if( pPieceIter ) // Complex File ?
1404 : {
1405 0 : sal_uLong nOldPos = pPieceIter->GetIdx();
1406 :
1407 0 : for (pPieceIter->SetIdx(0);
1408 0 : pPieceIter->GetIdx() < pPieceIter->GetIMax(); pPieceIter->advance())
1409 : {
1410 : WW8_CP nCpStart, nCpEnd;
1411 : void* pData;
1412 0 : if( !pPieceIter->Get( nCpStart, nCpEnd, pData ) )
1413 : { // outside PLCFfpcd ?
1414 : OSL_ENSURE( !this, "PLCFpcd-WW8Fc2Cp() went wrong" );
1415 0 : break;
1416 : }
1417 0 : sal_Int32 nFcStart = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
1418 0 : if (pWw8Fib->nVersion >= 8)
1419 : {
1420 : nFcStart = WW8PLCFx_PCD::TransformPieceAddress( nFcStart,
1421 0 : bIsUnicode );
1422 : }
1423 : else
1424 : {
1425 0 : bIsUnicode = pWw8Fib->fExtChar ? true : false;
1426 : }
1427 0 : 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 0 : if (nFcPos >= nFcStart)
1434 : {
1435 : // found
1436 : WW8_CP nTempCp =
1437 0 : nCpStart + ((nFcPos - nFcStart) / (bIsUnicode ? 2 : 1));
1438 0 : if (nFcPos < nFcStart + nLen)
1439 : {
1440 0 : pPieceIter->SetIdx( nOldPos );
1441 0 : return nTempCp;
1442 : }
1443 0 : 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 0 : if (!bIsUnicode)
1463 0 : nFallBackCpEnd = (nFcPos - pWw8Fib->fcMin);
1464 : else
1465 0 : nFallBackCpEnd = (nFcPos - pWw8Fib->fcMin + 1) / 2;
1466 :
1467 0 : return nFallBackCpEnd;
1468 : }
1469 :
1470 0 : WW8_FC WW8ScannerBase::WW8Cp2Fc(WW8_CP nCpPos, bool* pIsUnicode,
1471 : WW8_CP* pNextPieceCp, bool* pTestFlag) const
1472 : {
1473 0 : if( pTestFlag )
1474 0 : *pTestFlag = true;
1475 0 : if( WW8_CP_MAX == nCpPos )
1476 0 : return WW8_CP_MAX;
1477 :
1478 : bool bIsUnicode;
1479 0 : if( !pIsUnicode )
1480 0 : pIsUnicode = &bIsUnicode;
1481 :
1482 0 : if (pWw8Fib->nVersion >= 8)
1483 0 : *pIsUnicode = false;
1484 : else
1485 0 : *pIsUnicode = pWw8Fib->fExtChar ? true : false;
1486 :
1487 0 : if( pPieceIter )
1488 : {
1489 : // Complex File
1490 0 : if( pNextPieceCp )
1491 0 : *pNextPieceCp = WW8_CP_MAX;
1492 :
1493 0 : 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 0 : 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 0 : if( pNextPieceCp )
1514 0 : *pNextPieceCp = nCpEnd;
1515 :
1516 0 : WW8_FC nRet = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
1517 0 : if (pWw8Fib->nVersion >= 8)
1518 0 : nRet = WW8PLCFx_PCD::TransformPieceAddress( nRet, *pIsUnicode );
1519 : else
1520 0 : *pIsUnicode = pWw8Fib->fExtChar ? true : false;
1521 :
1522 0 : nRet += (nCpPos - nCpStart) * (*pIsUnicode ? 2 : 1);
1523 :
1524 0 : return nRet;
1525 : }
1526 :
1527 : // No complex file
1528 0 : return pWw8Fib->fcMin + nCpPos * (*pIsUnicode ? 2 : 1);
1529 : }
1530 :
1531 : // class WW8ScannerBase
1532 0 : WW8PLCFpcd* WW8ScannerBase::OpenPieceTable( SvStream* pStr, const WW8Fib* pWwF )
1533 : {
1534 0 : if ( ((8 > pWw8Fib->nVersion) && !pWwF->fComplex) || !pWwF->lcbClx )
1535 0 : return NULL;
1536 :
1537 0 : WW8_FC nClxPos = pWwF->fcClx;
1538 0 : sal_Int32 nClxLen = pWwF->lcbClx;
1539 0 : sal_Int32 nLeft = nClxLen;
1540 0 : sal_Int16 nGrpprl = 0;
1541 :
1542 0 : if (!checkSeek(*pStr, nClxPos))
1543 0 : return NULL;
1544 :
1545 : while( true ) // Zaehle Zahl der Grpprls
1546 : {
1547 0 : sal_uInt8 clxt(2);
1548 0 : pStr->ReadUChar( clxt );
1549 0 : nLeft--;
1550 0 : if( 2 == clxt ) // PLCFfpcd ?
1551 0 : break; // PLCFfpcd gefunden
1552 0 : if( 1 == clxt ) // clxtGrpprl ?
1553 0 : nGrpprl++;
1554 0 : sal_uInt16 nLen(0);
1555 0 : pStr->ReadUInt16( nLen );
1556 0 : nLeft -= 2 + nLen;
1557 0 : if( nLeft < 0 )
1558 0 : return NULL; // gone wrong
1559 0 : pStr->SeekRel( nLen ); // ueberlies grpprl
1560 : }
1561 :
1562 0 : if (!checkSeek(*pStr, nClxPos))
1563 0 : return NULL;
1564 :
1565 0 : nLeft = nClxLen;
1566 0 : pPieceGrpprls = new sal_uInt8*[nGrpprl + 1];
1567 0 : memset( pPieceGrpprls, 0, ( nGrpprl + 1 ) * sizeof(sal_uInt8 *) );
1568 0 : nPieceGrpprls = nGrpprl;
1569 0 : sal_Int16 nAktGrpprl = 0; // read Grpprls
1570 : while( true )
1571 : {
1572 0 : sal_uInt8 clxt(2);
1573 0 : pStr->ReadUChar( clxt );
1574 0 : nLeft--;
1575 0 : if( 2 == clxt) // PLCFfpcd ?
1576 0 : 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 0 : sal_Int32 nPLCFfLen(0);
1598 0 : 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 0 : pStr->ReadInt32( nPLCFfLen );
1606 : OSL_ENSURE( 65536 > nPLCFfLen, "PLCFfpcd above 64 k" );
1607 0 : return new WW8PLCFpcd( pStr, pStr->Tell(), nPLCFfLen, 8 );
1608 : }
1609 :
1610 0 : void WW8ScannerBase::DeletePieceTable()
1611 : {
1612 0 : if( pPieceGrpprls )
1613 : {
1614 0 : for( sal_uInt8** p = pPieceGrpprls; *p; p++ )
1615 0 : delete[] (*p);
1616 0 : delete[] pPieceGrpprls;
1617 0 : pPieceGrpprls = 0;
1618 : }
1619 0 : }
1620 :
1621 0 : 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 0 : pSubdocs(0), pExtendedAtrds(0), pPieceGrpprls(0)
1626 : {
1627 0 : pPiecePLCF = OpenPieceTable( pTblSt, pWw8Fib ); // Complex
1628 0 : if( pPiecePLCF )
1629 : {
1630 0 : pPieceIter = new WW8PLCFpcd_Iter( *pPiecePLCF );
1631 : pPLCFx_PCD = new WW8PLCFx_PCD(pWwFib->GetFIBVersion(), pPiecePLCF, 0,
1632 0 : IsSevenMinus(pWw8Fib->GetFIBVersion()));
1633 : pPLCFx_PCDAttrs = new WW8PLCFx_PCDAttrs(pWwFib->GetFIBVersion(),
1634 0 : pPLCFx_PCD, this);
1635 : }
1636 : else
1637 : {
1638 0 : pPieceIter = 0;
1639 0 : pPLCFx_PCD = 0;
1640 0 : pPLCFx_PCDAttrs = 0;
1641 : }
1642 :
1643 : // pChpPLCF and pPapPLCF may NOT be created before pPLCFx_PCD !!
1644 0 : pChpPLCF = new WW8PLCFx_Cp_FKP( pSt, pTblSt, pDataSt, *this, CHP ); // CHPX
1645 0 : pPapPLCF = new WW8PLCFx_Cp_FKP( pSt, pTblSt, pDataSt, *this, PAP ); // PAPX
1646 :
1647 0 : 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 0 : pWwFib->lcbPlcffndTxt, 2 );
1653 : // Endnotes
1654 : pEdnPLCF = new WW8PLCFx_SubDoc( pTblSt, pWwFib->GetFIBVersion(), 0,
1655 : pWwFib->fcPlcfendRef, pWwFib->lcbPlcfendRef, pWwFib->fcPlcfendTxt,
1656 0 : pWwFib->lcbPlcfendTxt, 2 );
1657 : // Comments
1658 : pAndPLCF = new WW8PLCFx_SubDoc( pTblSt, pWwFib->GetFIBVersion(), 0,
1659 : pWwFib->fcPlcfandRef, pWwFib->lcbPlcfandRef, pWwFib->fcPlcfandTxt,
1660 0 : pWwFib->lcbPlcfandTxt, IsSevenMinus(pWwFib->GetFIBVersion()) ? 20 : 30);
1661 :
1662 : // Fields Main Text
1663 0 : pFldPLCF = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_MAINTEXT);
1664 : // Fields Header / Footer
1665 0 : pFldHdFtPLCF= new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_HDFT);
1666 : // Fields Footnote
1667 0 : pFldFtnPLCF = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_FTN);
1668 : // Fields Endnote
1669 0 : pFldEdnPLCF = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_EDN);
1670 : // Fields Comments
1671 0 : pFldAndPLCF = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_AND);
1672 : // Fields in Textboxes in Main Text
1673 0 : pFldTxbxPLCF= new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_TXBX);
1674 : // Fields in Textboxes in Header / Footer
1675 0 : pFldTxbxHdFtPLCF = new WW8PLCFx_FLD(pTblSt,*pWwFib,MAN_TXBX_HDFT);
1676 :
1677 : // Note: 6 stands for "6 OR 7", 7 stands for "ONLY 7"
1678 0 : switch( pWw8Fib->nVersion )
1679 : {
1680 : case 6:
1681 : case 7:
1682 0 : if( pWwFib->fcPlcfdoaMom && pWwFib->lcbPlcfdoaMom )
1683 : {
1684 : pMainFdoa = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfdoaMom,
1685 0 : pWwFib->lcbPlcfdoaMom, 6 );
1686 : }
1687 0 : if( pWwFib->fcPlcfdoaHdr && pWwFib->lcbPlcfdoaHdr )
1688 : {
1689 : pHdFtFdoa = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfdoaHdr,
1690 0 : pWwFib->lcbPlcfdoaHdr, 6 );
1691 : }
1692 0 : break;
1693 : case 8:
1694 0 : if( pWwFib->fcPlcfspaMom && pWwFib->lcbPlcfspaMom )
1695 : {
1696 : pMainFdoa = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfspaMom,
1697 0 : pWwFib->lcbPlcfspaMom, 26 );
1698 : }
1699 0 : if( pWwFib->fcPlcfspaHdr && pWwFib->lcbPlcfspaHdr )
1700 : {
1701 : pHdFtFdoa = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfspaHdr,
1702 0 : pWwFib->lcbPlcfspaHdr, 26 );
1703 : }
1704 : // PLCF for TextBox break-descriptors in the main text
1705 0 : if( pWwFib->fcPlcftxbxBkd && pWwFib->lcbPlcftxbxBkd )
1706 : {
1707 : pMainTxbxBkd = new WW8PLCFspecial( pTblSt,
1708 0 : pWwFib->fcPlcftxbxBkd, pWwFib->lcbPlcftxbxBkd, 0);
1709 : }
1710 : // PLCF for TextBox break-descriptors in Header/Footer range
1711 0 : if( pWwFib->fcPlcfHdrtxbxBkd && pWwFib->lcbPlcfHdrtxbxBkd )
1712 : {
1713 : pHdFtTxbxBkd = new WW8PLCFspecial( pTblSt,
1714 0 : pWwFib->fcPlcfHdrtxbxBkd, pWwFib->lcbPlcfHdrtxbxBkd, 0);
1715 : }
1716 : // Sub table cp positions
1717 0 : if (pWwFib->fcPlcfTch && pWwFib->lcbPlcfTch)
1718 : {
1719 : pMagicTables = new WW8PLCFspecial( pTblSt,
1720 0 : pWwFib->fcPlcfTch, pWwFib->lcbPlcfTch, 4);
1721 : }
1722 : // Sub document cp positions
1723 0 : if (pWwFib->fcPlcfwkb && pWwFib->lcbPlcfwkb)
1724 : {
1725 : pSubdocs = new WW8PLCFspecial( pTblSt,
1726 0 : pWwFib->fcPlcfwkb, pWwFib->lcbPlcfwkb, 12);
1727 : }
1728 : // Extended ATRD
1729 0 : if (pWwFib->fcAtrdExtra && pWwFib->lcbAtrdExtra)
1730 : {
1731 0 : sal_Size nOldPos = pTblSt->Tell();
1732 0 : if (checkSeek(*pTblSt, pWwFib->fcAtrdExtra) && (pTblSt->remainingSize() >= pWwFib->lcbAtrdExtra))
1733 : {
1734 0 : pExtendedAtrds = new sal_uInt8[pWwFib->lcbAtrdExtra];
1735 0 : pWwFib->lcbAtrdExtra = pTblSt->Read(pExtendedAtrds, pWwFib->lcbAtrdExtra);
1736 : }
1737 : else
1738 0 : pWwFib->lcbAtrdExtra = 0;
1739 0 : pTblSt->Seek(nOldPos);
1740 : }
1741 :
1742 0 : 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 0 : sal_uInt32 nLenTxBxS = (8 > pWw8Fib->nVersion) ? 0 : 22;
1750 0 : if( pWwFib->fcPlcftxbxTxt && pWwFib->lcbPlcftxbxTxt )
1751 : {
1752 : pMainTxbx = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcftxbxTxt,
1753 0 : pWwFib->lcbPlcftxbxTxt, nLenTxBxS );
1754 : }
1755 :
1756 : // PLCF for TextBox stories in Header/Footer range
1757 0 : if( pWwFib->fcPlcfHdrtxbxTxt && pWwFib->lcbPlcfHdrtxbxTxt )
1758 : {
1759 : pHdFtTxbx = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfHdrtxbxTxt,
1760 0 : pWwFib->lcbPlcfHdrtxbxTxt, nLenTxBxS );
1761 : }
1762 :
1763 0 : pBook = new WW8PLCFx_Book(pTblSt, *pWwFib);
1764 0 : }
1765 :
1766 0 : WW8ScannerBase::~WW8ScannerBase()
1767 : {
1768 0 : DeletePieceTable();
1769 0 : delete pPLCFx_PCDAttrs;
1770 0 : delete pPLCFx_PCD;
1771 0 : delete pPieceIter;
1772 0 : delete pPiecePLCF;
1773 0 : delete pBook;
1774 0 : delete pFldEdnPLCF;
1775 0 : delete pFldFtnPLCF;
1776 0 : delete pFldAndPLCF;
1777 0 : delete pFldHdFtPLCF;
1778 0 : delete pFldPLCF;
1779 0 : delete pFldTxbxPLCF;
1780 0 : delete pFldTxbxHdFtPLCF;
1781 0 : delete pEdnPLCF;
1782 0 : delete pFtnPLCF;
1783 0 : delete pAndPLCF;
1784 0 : delete pSepPLCF;
1785 0 : delete pPapPLCF;
1786 0 : delete pChpPLCF;
1787 : // vergessene Schaeflein
1788 0 : delete pMainFdoa;
1789 0 : delete pHdFtFdoa;
1790 0 : delete pMainTxbx;
1791 0 : delete pMainTxbxBkd;
1792 0 : delete pHdFtTxbx;
1793 0 : delete pHdFtTxbxBkd;
1794 0 : delete pMagicTables;
1795 0 : delete pSubdocs;
1796 0 : delete [] pExtendedAtrds;
1797 0 : }
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 0 : static bool WW8GetFieldPara(WW8PLCFspecial& rPLCF, WW8FieldDesc& rF)
1848 : {
1849 : void* pData;
1850 0 : sal_uLong nOldIdx = rPLCF.GetIdx();
1851 :
1852 0 : rF.nLen = rF.nId = rF.nOpt = rF.bCodeNest = rF.bResNest = false;
1853 :
1854 0 : if( !rPLCF.Get( rF.nSCode, pData ) ) // end of PLCFspecial?
1855 0 : goto Err;
1856 :
1857 0 : rPLCF.advance();
1858 :
1859 0 : if((((sal_uInt8*)pData)[0] & 0x1f ) != 0x13 ) // No beginning?
1860 0 : goto Err;
1861 :
1862 0 : rF.nId = ((sal_uInt8*)pData)[1];
1863 :
1864 0 : if( !rPLCF.Get( rF.nLCode, pData ) )
1865 0 : goto Err;
1866 :
1867 0 : rF.nSRes = rF.nLCode; // Default
1868 0 : rF.nSCode++; // without markers
1869 0 : rF.nLCode -= rF.nSCode; // Pos -> length
1870 :
1871 0 : 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 0 : if ((((sal_uInt8*)pData)[0] & 0x1f ) == 0x14 ) // Field Separator?
1881 : {
1882 0 : rPLCF.advance();
1883 :
1884 0 : if( !rPLCF.Get( rF.nLRes, pData ) )
1885 0 : goto Err;
1886 :
1887 0 : 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 0 : rF.nLen = rF.nLRes - rF.nSCode + 2; // nLRes is still the final position
1896 0 : rF.nLRes -= rF.nSRes; // now: nLRes = length
1897 0 : rF.nSRes++; // Endpos encluding Markers
1898 0 : 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 0 : rPLCF.advance();
1905 0 : if((((sal_uInt8*)pData)[0] & 0x1f ) == 0x15 )
1906 : {
1907 : // Field end ?
1908 : // INDEX-Fld has set Bit7?
1909 0 : rF.nOpt = ((sal_uInt8*)pData)[1]; // yes -> copy flags
1910 : }else{
1911 0 : rF.nId = 0; // no -> Field invalid
1912 : }
1913 :
1914 0 : rPLCF.SetIdx( nOldIdx );
1915 0 : 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 0 : OUString read_uInt16_BeltAndBracesString(SvStream& rStrm)
1929 : {
1930 0 : OUString aRet = read_uInt16_PascalString(rStrm);
1931 0 : rStrm.SeekRel(sizeof(sal_Unicode)); // skip null-byte at end
1932 0 : return aRet;
1933 : }
1934 :
1935 0 : 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 0 : rStr = OUString();
1940 :
1941 0 : long nTotalRead = 0;
1942 0 : WW8_CP nBehindTextCp = nAktStartCp + nTotalLen;
1943 0 : WW8_CP nNextPieceCp = nBehindTextCp; // Initialization, important for Ver6
1944 0 : do
1945 : {
1946 : bool bIsUnicode, bPosOk;
1947 0 : WW8_FC fcAct = WW8Cp2Fc(nAktStartCp,&bIsUnicode,&nNextPieceCp,&bPosOk);
1948 :
1949 : // Probably aimed beyond file end, doesn't matter!
1950 0 : if( !bPosOk )
1951 0 : break;
1952 :
1953 0 : rStrm.Seek( fcAct );
1954 :
1955 0 : long nLen = ( (nNextPieceCp < nBehindTextCp) ? nNextPieceCp
1956 0 : : nBehindTextCp ) - nAktStartCp;
1957 :
1958 0 : if( 0 >= nLen )
1959 0 : break;
1960 :
1961 0 : if( nLen > USHRT_MAX - 1 )
1962 0 : nLen = USHRT_MAX - 1;
1963 :
1964 0 : rStr += bIsUnicode
1965 : ? read_uInt16s_ToOUString(rStrm, nLen)
1966 0 : : read_uInt8s_ToOUString(rStrm, nLen, eEnc);
1967 :
1968 0 : nTotalRead += nLen;
1969 0 : nAktStartCp += nLen;
1970 0 : if ( nTotalRead != rStr.getLength() )
1971 0 : break;
1972 : }
1973 : while( nTotalRead < nTotalLen );
1974 :
1975 0 : return rStr.getLength();
1976 : }
1977 :
1978 0 : WW8PLCFspecial::WW8PLCFspecial(SvStream* pSt, sal_uInt32 nFilePos,
1979 : sal_uInt32 nPLCF, sal_uInt32 nStruct)
1980 0 : : nIdx(0), nStru(nStruct)
1981 : {
1982 0 : const sal_uInt32 nValidMin=4;
1983 :
1984 0 : sal_Size nOldPos = pSt->Tell();
1985 :
1986 0 : bool bValid = checkSeek(*pSt, nFilePos);
1987 0 : sal_Size nRemainingSize = pSt->remainingSize();
1988 0 : if( !(nRemainingSize >= nValidMin && nPLCF >= nValidMin ))
1989 0 : bValid = false;
1990 0 : nPLCF = bValid ? std::min(nRemainingSize, static_cast<sal_Size>(nPLCF)) : nValidMin;
1991 :
1992 : // Pointer to Pos- and Struct-array
1993 0 : pPLCF_PosArray = new sal_Int32[ ( nPLCF + 3 ) / 4 ];
1994 0 : pPLCF_PosArray[0] = 0;
1995 :
1996 0 : nPLCF = bValid ? pSt->Read(pPLCF_PosArray, nPLCF) : nValidMin;
1997 :
1998 0 : nPLCF = std::max(nPLCF, nValidMin);
1999 :
2000 0 : 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 0 : if( nStruct ) // Pointer to content array
2007 0 : pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
2008 : else
2009 0 : pPLCF_Contents = 0; // no content
2010 :
2011 0 : pSt->Seek(nOldPos);
2012 0 : }
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 0 : bool WW8PLCFspecial::SeekPos(long nP)
2019 : {
2020 0 : 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 0 : if( (1 > nIdx) || (nP < pPLCF_PosArray[ nIdx-1 ]) )
2028 0 : nIdx = 1;
2029 :
2030 0 : long nI = nIdx ? nIdx : 1;
2031 0 : long nEnd = nIMax;
2032 :
2033 0 : for(int n = (1==nIdx ? 1 : 2); n; --n )
2034 : {
2035 0 : for( ; nI <=nEnd; ++nI)
2036 : { // search with an index that is incremented by 1
2037 0 : if( nP < pPLCF_PosArray[nI] )
2038 : { // found position
2039 0 : nIdx = nI - 1; // nI - 1 is the correct index
2040 0 : 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 0 : bool WW8PLCFspecial::SeekPosExact(long nP)
2054 : {
2055 0 : if( nP < pPLCF_PosArray[0] )
2056 : {
2057 0 : nIdx = 0;
2058 0 : return false; // Not found: nP less than smallest entry
2059 : }
2060 : // Search from beginning?
2061 0 : if( nP <=pPLCF_PosArray[nIdx] )
2062 0 : nIdx = 0;
2063 :
2064 0 : long nI = nIdx ? nIdx-1 : 0;
2065 0 : long nEnd = nIMax;
2066 :
2067 0 : for(int n = (0==nIdx ? 1 : 2); n; --n )
2068 : {
2069 0 : for( ; nI < nEnd; ++nI)
2070 : {
2071 0 : if( nP <=pPLCF_PosArray[nI] )
2072 : { // found position
2073 0 : nIdx = nI; // nI is the correct index
2074 0 : return true; // done
2075 : }
2076 : }
2077 0 : nI = 0;
2078 0 : nEnd = nIdx;
2079 : }
2080 0 : nIdx = nIMax; // Not found, greater than all entries
2081 0 : return false;
2082 : }
2083 :
2084 0 : bool WW8PLCFspecial::Get(WW8_CP& rPos, void*& rpValue) const
2085 : {
2086 0 : return GetData( nIdx, rPos, rpValue );
2087 : }
2088 :
2089 0 : bool WW8PLCFspecial::GetData(long nInIdx, WW8_CP& rPos, void*& rpValue) const
2090 : {
2091 0 : if ( nInIdx >= nIMax )
2092 : {
2093 0 : rPos = WW8_CP_MAX;
2094 0 : return false;
2095 : }
2096 0 : rPos = pPLCF_PosArray[nInIdx];
2097 0 : rpValue = pPLCF_Contents ? (void*)&pPLCF_Contents[nInIdx * nStru] : 0;
2098 0 : 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 0 : WW8PLCF::WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
2105 0 : WW8_CP nStartPos) : pPLCF_PosArray(0), nIdx(0), nStru(nStruct)
2106 : {
2107 : OSL_ENSURE( nPLCF, "WW8PLCF: nPLCF is zero!" );
2108 :
2109 0 : nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
2110 :
2111 0 : ReadPLCF(rSt, nFilePos, nPLCF);
2112 :
2113 0 : if( nStartPos >= 0 )
2114 0 : SeekPos( nStartPos );
2115 0 : }
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 0 : 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 0 : nStru(nStruct)
2125 : {
2126 0 : nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
2127 :
2128 0 : if( nIMax >= ncpN )
2129 0 : ReadPLCF(rSt, nFilePos, nPLCF);
2130 : else
2131 0 : GeneratePLCF(rSt, nPN, ncpN);
2132 :
2133 0 : if( nStartPos >= 0 )
2134 0 : SeekPos( nStartPos );
2135 0 : }
2136 :
2137 0 : void WW8PLCF::ReadPLCF(SvStream& rSt, WW8_FC nFilePos, sal_uInt32 nPLCF)
2138 : {
2139 0 : sal_Size nOldPos = rSt.Tell();
2140 0 : bool bValid = checkSeek(rSt, nFilePos) && (rSt.remainingSize() >= nPLCF);
2141 :
2142 0 : if (bValid)
2143 : {
2144 : // Pointer to Pos-array
2145 0 : pPLCF_PosArray = new WW8_CP[ ( nPLCF + 3 ) / 4 ];
2146 0 : bValid = checkRead(rSt, pPLCF_PosArray, nPLCF);
2147 : }
2148 :
2149 0 : 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 0 : pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
2158 : }
2159 :
2160 : OSL_ENSURE(bValid, "Document has corrupt PLCF, ignoring it");
2161 :
2162 0 : if (!bValid)
2163 0 : MakeFailedPLCF();
2164 :
2165 0 : rSt.Seek(nOldPos);
2166 0 : }
2167 :
2168 0 : void WW8PLCF::MakeFailedPLCF()
2169 : {
2170 0 : nIMax = 0;
2171 0 : delete[] pPLCF_PosArray;
2172 0 : pPLCF_PosArray = new sal_Int32[2];
2173 0 : pPLCF_PosArray[0] = pPLCF_PosArray[1] = WW8_CP_MAX;
2174 0 : pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
2175 0 : }
2176 :
2177 0 : 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 0 : bool failure = false;
2182 0 : nIMax = ncpN;
2183 :
2184 0 : if ((nIMax < 1) || (nIMax > (WW8_CP_MAX - 4)/6) || ((nPN + ncpN) > USHRT_MAX))
2185 0 : failure = true;
2186 :
2187 0 : 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 0 : 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 0 : 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 0 : if (failure)
2249 0 : MakeFailedPLCF();
2250 0 : }
2251 :
2252 0 : bool WW8PLCF::SeekPos(WW8_CP nPos)
2253 : {
2254 0 : WW8_CP nP = nPos;
2255 :
2256 0 : if( nP < pPLCF_PosArray[0] )
2257 : {
2258 0 : nIdx = 0;
2259 : // not found: nPos less than smallest entry
2260 0 : return false;
2261 : }
2262 :
2263 : // Search from beginning?
2264 0 : if( (1 > nIdx) || (nP < pPLCF_PosArray[ nIdx-1 ]) )
2265 0 : nIdx = 1;
2266 :
2267 0 : sal_Int32 nI = nIdx ? nIdx : 1;
2268 0 : sal_Int32 nEnd = nIMax;
2269 :
2270 0 : for(int n = (1==nIdx ? 1 : 2); n; --n )
2271 : {
2272 0 : for( ; nI <=nEnd; ++nI) // search with an index that is incremented by 1
2273 : {
2274 0 : if( nP < pPLCF_PosArray[nI] ) // found position
2275 : {
2276 0 : nIdx = nI - 1; // nI - 1 is the correct index
2277 0 : return true; // done
2278 : }
2279 : }
2280 0 : nI = 1;
2281 0 : nEnd = nIdx-1;
2282 : }
2283 :
2284 0 : nIdx = nIMax; // not found, greater than all entries
2285 0 : return false;
2286 : }
2287 :
2288 0 : bool WW8PLCF::Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const
2289 : {
2290 0 : if ( nIdx >= nIMax )
2291 : {
2292 0 : rStart = rEnd = WW8_CP_MAX;
2293 0 : return false;
2294 : }
2295 0 : rStart = pPLCF_PosArray[ nIdx ];
2296 0 : rEnd = pPLCF_PosArray[ nIdx + 1 ];
2297 0 : rpValue = (void*)&pPLCF_Contents[nIdx * nStru];
2298 0 : 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 0 : WW8PLCFpcd::WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos,
2310 : sal_uInt32 nPLCF, sal_uInt32 nStruct)
2311 0 : : nStru( nStruct )
2312 : {
2313 0 : const sal_uInt32 nValidMin=4;
2314 :
2315 0 : sal_Size nOldPos = pSt->Tell();
2316 :
2317 0 : bool bValid = checkSeek(*pSt, nFilePos);
2318 0 : sal_Size nRemainingSize = pSt->remainingSize();
2319 0 : if( !(nRemainingSize >= nValidMin && nPLCF >= nValidMin ))
2320 0 : bValid = false;
2321 0 : nPLCF = bValid ? std::min(nRemainingSize, static_cast<sal_Size>(nPLCF)) : nValidMin;
2322 :
2323 0 : pPLCF_PosArray = new sal_Int32[ ( nPLCF + 3 ) / 4 ]; // Pointer to Pos-array
2324 0 : pPLCF_PosArray[0] = 0;
2325 :
2326 0 : nPLCF = bValid ? pSt->Read(pPLCF_PosArray, nPLCF) : nValidMin;
2327 0 : nPLCF = std::max(nPLCF, nValidMin);
2328 :
2329 0 : 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 0 : pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
2337 :
2338 0 : pSt->Seek( nOldPos );
2339 0 : }
2340 :
2341 : // If nStartPos < 0, the first element of PLCFs will be taken
2342 0 : WW8PLCFpcd_Iter::WW8PLCFpcd_Iter( WW8PLCFpcd& rPLCFpcd, long nStartPos )
2343 0 : :rPLCF( rPLCFpcd ), nIdx( 0 )
2344 : {
2345 0 : if( nStartPos >= 0 )
2346 0 : SeekPos( nStartPos );
2347 0 : }
2348 :
2349 0 : bool WW8PLCFpcd_Iter::SeekPos(long nPos)
2350 : {
2351 0 : long nP = nPos;
2352 :
2353 0 : 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 0 : if( (1 > nIdx) || (nP < rPLCF.pPLCF_PosArray[ nIdx-1 ]) )
2360 0 : nIdx = 1;
2361 :
2362 0 : long nI = nIdx ? nIdx : 1;
2363 0 : long nEnd = rPLCF.nIMax;
2364 :
2365 0 : for(int n = (1==nIdx ? 1 : 2); n; --n )
2366 : {
2367 0 : for( ; nI <=nEnd; ++nI)
2368 : { // search with an index that is incremented by 1
2369 0 : if( nP < rPLCF.pPLCF_PosArray[nI] )
2370 : { // found position
2371 0 : nIdx = nI - 1; // nI - 1 is the correct index
2372 0 : return true; // done
2373 : }
2374 : }
2375 0 : nI = 1;
2376 0 : nEnd = nIdx-1;
2377 : }
2378 0 : nIdx = rPLCF.nIMax; // not found, greater than all entries
2379 0 : return false;
2380 : }
2381 :
2382 0 : bool WW8PLCFpcd_Iter::Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const
2383 : {
2384 0 : if( nIdx >= rPLCF.nIMax )
2385 : {
2386 0 : rStart = rEnd = WW8_CP_MAX;
2387 0 : return false;
2388 : }
2389 0 : rStart = rPLCF.pPLCF_PosArray[nIdx];
2390 0 : rEnd = rPLCF.pPLCF_PosArray[nIdx + 1];
2391 0 : rpValue = (void*)&rPLCF.pPLCF_Contents[nIdx * rPLCF.nStru];
2392 0 : 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 0 : bool WW8PLCFx_Fc_FKP::WW8Fkp::Entry::operator<
2404 : (const WW8PLCFx_Fc_FKP::WW8Fkp::Entry& rSecond) const
2405 : {
2406 0 : return (mnFC < rSecond.mnFC);
2407 : }
2408 :
2409 0 : bool IsReplaceAllSprm(sal_uInt16 nSpId)
2410 : {
2411 0 : return (0x6645 == nSpId || 0x6646 == nSpId);
2412 : }
2413 :
2414 0 : bool IsExpandableSprm(sal_uInt16 nSpId)
2415 : {
2416 0 : return 0x646B == nSpId;
2417 : }
2418 :
2419 0 : void WW8PLCFx_Fc_FKP::WW8Fkp::FillEntry(WW8PLCFx_Fc_FKP::WW8Fkp::Entry &rEntry,
2420 : sal_Size nDataOffset, sal_uInt16 nLen)
2421 : {
2422 0 : bool bValidPos = (nDataOffset < sizeof(maRawData));
2423 :
2424 : OSL_ENSURE(bValidPos, "sprm sequence offset is out of range, ignoring");
2425 :
2426 0 : if (!bValidPos)
2427 : {
2428 0 : rEntry.mnLen = 0;
2429 0 : return;
2430 : }
2431 :
2432 0 : sal_uInt16 nAvailableData = sizeof(maRawData)-nDataOffset;
2433 : OSL_ENSURE(nLen <= nAvailableData, "srpm sequence len is out of range, clipping");
2434 0 : rEntry.mnLen = std::min(nLen, nAvailableData);
2435 0 : rEntry.mpData = maRawData + nDataOffset;
2436 : }
2437 :
2438 0 : 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 0 : maSprmParser(eVersion)
2443 : {
2444 0 : memset(maRawData, 0, 512);
2445 :
2446 0 : sal_Size nOldPos = pSt->Tell();
2447 :
2448 0 : bool bCouldSeek = checkSeek(*pSt, nFilePos);
2449 0 : bool bCouldRead = bCouldSeek ? checkRead(*pSt, maRawData, 512) : false;
2450 :
2451 0 : mnIMax = bCouldRead ? maRawData[511] : 0;
2452 :
2453 0 : sal_uInt8 *pStart = maRawData;
2454 : // Offset-Location in maRawData
2455 0 : const size_t nRawDataStart = (mnIMax + 1) * 4;
2456 :
2457 0 : for (mnIdx = 0; mnIdx < mnIMax; ++mnIdx)
2458 : {
2459 0 : const size_t nRawDataOffset = nRawDataStart + mnIdx * nItemSize;
2460 :
2461 : //clip to available data, corrupt fkp
2462 0 : if (nRawDataOffset >= 511)
2463 : {
2464 0 : mnIMax = mnIdx;
2465 0 : break;
2466 : }
2467 :
2468 0 : unsigned int nOfs = maRawData[nRawDataOffset] * 2;
2469 :
2470 : //clip to available data, corrupt fkp
2471 0 : if (nOfs >= 511)
2472 : {
2473 0 : mnIMax = mnIdx;
2474 0 : break;
2475 : }
2476 :
2477 0 : Entry aEntry(Get_Long(pStart));
2478 :
2479 0 : if (nOfs)
2480 : {
2481 0 : switch (ePLCF)
2482 : {
2483 : case CHP:
2484 : {
2485 0 : aEntry.mnLen = maRawData[nOfs];
2486 :
2487 : //len byte
2488 0 : sal_Size nDataOffset = nOfs + 1;
2489 :
2490 0 : FillEntry(aEntry, nDataOffset, aEntry.mnLen);
2491 :
2492 0 : if (aEntry.mnLen && eVersion == ww::eWW2)
2493 : {
2494 0 : Word2CHPX aChpx = ReadWord2Chpx(*pSt, nFilePos + nOfs + 1, static_cast< sal_uInt8 >(aEntry.mnLen));
2495 0 : std::vector<sal_uInt8> aSprms = ChpxToSprms(aChpx);
2496 0 : aEntry.mnLen = static_cast< sal_uInt16 >(aSprms.size());
2497 0 : if (aEntry.mnLen)
2498 : {
2499 0 : aEntry.mpData = new sal_uInt8[aEntry.mnLen];
2500 0 : memcpy(aEntry.mpData, &(aSprms[0]), aEntry.mnLen);
2501 0 : aEntry.mbMustDelete = true;
2502 0 : }
2503 : }
2504 0 : break;
2505 : }
2506 : case PAP:
2507 : {
2508 0 : sal_uInt8 nDelta = 0;
2509 :
2510 0 : aEntry.mnLen = maRawData[nOfs];
2511 0 : if (IsEightPlus(eVersion) && !aEntry.mnLen)
2512 : {
2513 0 : aEntry.mnLen = maRawData[nOfs+1];
2514 0 : nDelta++;
2515 : }
2516 0 : aEntry.mnLen *= 2;
2517 :
2518 : //stylecode, std/istd
2519 0 : if (eVersion == ww::eWW2)
2520 : {
2521 0 : if (aEntry.mnLen >= 1)
2522 : {
2523 0 : aEntry.mnIStd = *(maRawData+nOfs+1+nDelta);
2524 0 : aEntry.mnLen--; //style code
2525 0 : if (aEntry.mnLen >= 6)
2526 : {
2527 0 : aEntry.mnLen-=6; //PHE
2528 : //skipi stc, len byte + 6 byte PHE
2529 0 : unsigned int nOffset = nOfs + 8;
2530 0 : if (nOffset >= 511) //Bad offset
2531 0 : aEntry.mnLen=0;
2532 0 : if (aEntry.mnLen) //start is ok
2533 : {
2534 0 : if (nOffset + aEntry.mnLen > 512) //Bad end, clip
2535 0 : aEntry.mnLen = 512 - nOffset;
2536 0 : aEntry.mpData = maRawData + nOffset;
2537 : }
2538 : }
2539 : else
2540 0 : aEntry.mnLen=0; //Too short
2541 : }
2542 : }
2543 : else
2544 : {
2545 0 : if (aEntry.mnLen >= 2)
2546 : {
2547 : //len byte + optional extra len byte
2548 0 : sal_Size nDataOffset = nOfs + 1 + nDelta;
2549 0 : aEntry.mnIStd = nDataOffset <= sizeof(maRawData)-sizeof(aEntry.mnIStd) ?
2550 0 : SVBT16ToShort(maRawData+nDataOffset) : 0;
2551 0 : aEntry.mnLen-=2; //istd
2552 0 : if (aEntry.mnLen)
2553 : {
2554 : //additional istd
2555 0 : nDataOffset += sizeof(aEntry.mnIStd);
2556 :
2557 0 : FillEntry(aEntry, nDataOffset, aEntry.mnLen);
2558 : }
2559 : }
2560 : else
2561 0 : aEntry.mnLen=0; //Too short, ignore
2562 : }
2563 :
2564 0 : 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 0 : bool bExpand = IsExpandableSprm(nSpId);
2572 0 : if (IsReplaceAllSprm(nSpId) || bExpand)
2573 : {
2574 0 : sal_uInt32 nCurr = pDataSt->Tell();
2575 0 : sal_uInt32 nPos = SVBT32ToUInt32(aEntry.mpData + 2);
2576 0 : if (checkSeek(*pDataSt, nPos))
2577 : {
2578 0 : sal_uInt16 nOrigLen = bExpand ? aEntry.mnLen : 0;
2579 0 : sal_uInt8 *pOrigData = bExpand ? aEntry.mpData : 0;
2580 :
2581 0 : pDataSt->ReadUInt16( aEntry.mnLen );
2582 : aEntry.mpData =
2583 0 : new sal_uInt8[aEntry.mnLen + nOrigLen];
2584 0 : aEntry.mbMustDelete = true;
2585 : aEntry.mnLen =
2586 0 : pDataSt->Read(aEntry.mpData, aEntry.mnLen);
2587 :
2588 0 : pDataSt->Seek( nCurr );
2589 :
2590 0 : if (pOrigData)
2591 : {
2592 0 : memcpy(aEntry.mpData + aEntry.mnLen,
2593 0 : pOrigData, nOrigLen);
2594 0 : aEntry.mnLen = aEntry.mnLen + nOrigLen;
2595 : }
2596 : }
2597 : }
2598 : }
2599 0 : break;
2600 : default:
2601 : OSL_FAIL("sweet god, what have you done!");
2602 0 : break;
2603 : }
2604 : }
2605 :
2606 0 : 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 0 : }
2622 :
2623 : //one more FC than grrpl entries
2624 0 : maEntries.push_back(Entry(Get_Long(pStart)));
2625 :
2626 : //we expect them sorted, but it appears possible for them to arive unsorted
2627 0 : std::sort(maEntries.begin(), maEntries.end());
2628 :
2629 0 : mnIdx = 0;
2630 :
2631 0 : if (nStartFc >= 0)
2632 0 : SeekPos(nStartFc);
2633 :
2634 0 : pSt->Seek(nOldPos);
2635 0 : }
2636 :
2637 0 : WW8PLCFx_Fc_FKP::WW8Fkp::Entry::Entry(const Entry &rEntry)
2638 : : mnFC(rEntry.mnFC), mnLen(rEntry.mnLen), mnIStd(rEntry.mnIStd),
2639 0 : mbMustDelete(rEntry.mbMustDelete)
2640 : {
2641 0 : if (mbMustDelete)
2642 : {
2643 0 : mpData = new sal_uInt8[mnLen];
2644 0 : memcpy(mpData, rEntry.mpData, mnLen);
2645 : }
2646 : else
2647 0 : mpData = rEntry.mpData;
2648 0 : }
2649 :
2650 : WW8PLCFx_Fc_FKP::WW8Fkp::Entry&
2651 0 : WW8PLCFx_Fc_FKP::WW8Fkp::Entry::operator=(const Entry &rEntry)
2652 : {
2653 0 : if (this == &rEntry)
2654 0 : return *this;
2655 :
2656 0 : if (mbMustDelete)
2657 0 : delete[] mpData;
2658 :
2659 0 : mnFC = rEntry.mnFC;
2660 0 : mnLen = rEntry.mnLen;
2661 0 : mnIStd = rEntry.mnIStd;
2662 0 : mbMustDelete = rEntry.mbMustDelete;
2663 :
2664 0 : if (mbMustDelete)
2665 : {
2666 0 : mpData = new sal_uInt8[mnLen];
2667 0 : memcpy(mpData, rEntry.mpData, mnLen);
2668 : }
2669 : else
2670 0 : mpData = rEntry.mpData;
2671 0 : return *this;
2672 : }
2673 :
2674 0 : WW8PLCFx_Fc_FKP::WW8Fkp::Entry::~Entry()
2675 : {
2676 0 : if (mbMustDelete)
2677 0 : delete[] mpData;
2678 0 : }
2679 :
2680 0 : void WW8PLCFx_Fc_FKP::WW8Fkp::Reset(WW8_FC nFc)
2681 : {
2682 0 : SetIdx(0);
2683 0 : if (nFc >= 0)
2684 0 : SeekPos(nFc);
2685 0 : }
2686 :
2687 0 : bool WW8PLCFx_Fc_FKP::WW8Fkp::SeekPos(WW8_FC nFc)
2688 : {
2689 0 : 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 0 : if ((1 > mnIdx) || (nFc < maEntries[mnIdx-1].mnFC))
2697 0 : mnIdx = 1;
2698 :
2699 0 : sal_uInt8 nI = mnIdx ? mnIdx : 1;
2700 0 : sal_uInt8 nEnd = mnIMax;
2701 :
2702 0 : for(sal_uInt8 n = (1==mnIdx ? 1 : 2); n; --n )
2703 : {
2704 0 : for( ; nI <=nEnd; ++nI)
2705 : { // search with an index that is incremented by 1
2706 0 : if (nFc < maEntries[nI].mnFC)
2707 : { // found position
2708 0 : mnIdx = nI - 1; // nI - 1 is the correct index
2709 0 : return true; // done
2710 : }
2711 : }
2712 0 : nI = 1;
2713 0 : nEnd = mnIdx-1;
2714 : }
2715 0 : mnIdx = mnIMax; // not found, greater than all entries
2716 0 : return false;
2717 : }
2718 :
2719 0 : sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::Get(WW8_FC& rStart, WW8_FC& rEnd, sal_Int32& rLen)
2720 : const
2721 : {
2722 0 : rLen = 0;
2723 :
2724 0 : if (mnIdx >= mnIMax)
2725 : {
2726 0 : rStart = WW8_FC_MAX;
2727 0 : return 0;
2728 : }
2729 :
2730 0 : rStart = maEntries[mnIdx].mnFC;
2731 0 : rEnd = maEntries[mnIdx + 1].mnFC;
2732 :
2733 0 : sal_uInt8* pSprms = GetLenAndIStdAndSprms( rLen );
2734 0 : return pSprms;
2735 : }
2736 :
2737 0 : bool WW8PLCFx_Fc_FKP::WW8Fkp::SetIdx(sal_uInt8 nI)
2738 : {
2739 0 : if (nI < mnIMax)
2740 : {
2741 0 : mnIdx = nI;
2742 0 : return true;
2743 : }
2744 0 : return false;
2745 : }
2746 :
2747 0 : sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::GetLenAndIStdAndSprms(sal_Int32& rLen) const
2748 : {
2749 0 : rLen = maEntries[mnIdx].mnLen;
2750 0 : return maEntries[mnIdx].mpData;
2751 : }
2752 :
2753 0 : const sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm( sal_uInt16 nId )
2754 : {
2755 0 : if (mnIdx >= mnIMax)
2756 0 : return 0;
2757 :
2758 : sal_Int32 nLen;
2759 0 : sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen );
2760 :
2761 0 : WW8SprmIter aIter(pSprms, nLen, maSprmParser);
2762 0 : 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 0 : sal_uLong WW8PLCFx::GetIdx2() const
2805 : {
2806 0 : return 0;
2807 : }
2808 :
2809 0 : void WW8PLCFx::SetIdx2(sal_uLong )
2810 : {
2811 0 : }
2812 :
2813 : class SamePos :
2814 : public std::unary_function<const WW8PLCFx_Fc_FKP::WW8Fkp *, bool>
2815 : {
2816 : private:
2817 : long mnPo;
2818 : public:
2819 0 : SamePos(long nPo) : mnPo(nPo) {}
2820 0 : bool operator()(const WW8PLCFx_Fc_FKP::WW8Fkp *pFkp)
2821 0 : {return mnPo == pFkp->GetFilePos();}
2822 : };
2823 :
2824 0 : 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 0 : switch (GetFIBVersion())
2844 : {
2845 : case ww::eWW2:
2846 0 : pFkpSizeTab = WW8FkpSizeTabVer2;
2847 0 : break;
2848 : case ww::eWW6:
2849 : case ww::eWW7:
2850 0 : pFkpSizeTab = WW8FkpSizeTabVer6;
2851 0 : break;
2852 : case ww::eWW8:
2853 0 : pFkpSizeTab = WW8FkpSizeTabVer8;
2854 0 : break;
2855 : default:
2856 : // program error!
2857 : OSL_ENSURE( !this, "Someone forgot to encode nVersion!" );
2858 0 : return false;
2859 : }
2860 :
2861 0 : if (!pPLCF->Get( nPLCFStart, nPLCFEnd, pPage ))
2862 : {
2863 0 : pFkp = 0;
2864 0 : return false; // PLCF completely processed
2865 : }
2866 0 : pPLCF->advance();
2867 0 : long nPo = SVBT16ToShort( (sal_uInt8 *)pPage );
2868 0 : nPo <<= 9; // shift as LONG
2869 :
2870 0 : long nAktFkpFilePos = pFkp ? pFkp->GetFilePos() : -1;
2871 0 : if (nAktFkpFilePos == nPo)
2872 0 : pFkp->Reset(GetStartFc());
2873 : else
2874 : {
2875 : myiter aIter =
2876 0 : std::find_if(maFkpCache.begin(), maFkpCache.end(), SamePos(nPo));
2877 0 : if (aIter != maFkpCache.end())
2878 : {
2879 0 : pFkp = *aIter;
2880 0 : pFkp->Reset(GetStartFc());
2881 : }
2882 0 : else if (0 != (pFkp = new WW8Fkp(GetFIBVersion(), pFKPStrm, pDataStrm, nPo,
2883 0 : pFkpSizeTab[ ePLCF ], ePLCF, GetStartFc())))
2884 : {
2885 0 : maFkpCache.push_back(pFkp);
2886 :
2887 0 : if (maFkpCache.size() > eMaxCache)
2888 : {
2889 0 : delete maFkpCache.front();
2890 0 : maFkpCache.pop_front();
2891 : }
2892 : }
2893 : }
2894 :
2895 0 : SetStartFc( -1 ); // only the first time
2896 0 : return true;
2897 : }
2898 :
2899 0 : 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 0 : pFkp(0), ePLCF(ePl), pPCDAttrs(0)
2903 : {
2904 0 : SetStartFc(nStartFcL);
2905 0 : long nLenStruct = (8 > rFib.nVersion) ? 2 : 4;
2906 0 : if (ePl == CHP)
2907 : {
2908 : pPLCF = new WW8PLCF(*pTblSt, rFib.fcPlcfbteChpx, rFib.lcbPlcfbteChpx,
2909 0 : nLenStruct, GetStartFc(), rFib.pnChpFirst, rFib.cpnBteChp);
2910 : }
2911 : else
2912 : {
2913 : pPLCF = new WW8PLCF(*pTblSt, rFib.fcPlcfbtePapx, rFib.lcbPlcfbtePapx,
2914 0 : nLenStruct, GetStartFc(), rFib.pnPapFirst, rFib.cpnBtePap);
2915 : }
2916 0 : }
2917 :
2918 0 : WW8PLCFx_Fc_FKP::~WW8PLCFx_Fc_FKP()
2919 : {
2920 0 : myiter aEnd = maFkpCache.end();
2921 0 : for (myiter aIter = maFkpCache.begin(); aIter != aEnd; ++aIter)
2922 0 : delete *aIter;
2923 0 : delete pPLCF;
2924 0 : delete pPCDAttrs;
2925 0 : }
2926 :
2927 0 : sal_uLong WW8PLCFx_Fc_FKP::GetIdx() const
2928 : {
2929 0 : sal_uLong u = pPLCF->GetIdx() << 8;
2930 0 : if (pFkp)
2931 0 : u |= pFkp->GetIdx();
2932 0 : return u;
2933 : }
2934 :
2935 0 : void WW8PLCFx_Fc_FKP::SetIdx( sal_uLong nIdx )
2936 : {
2937 0 : if( !( nIdx & 0xffffff00L ) )
2938 : {
2939 0 : pPLCF->SetIdx( nIdx >> 8 );
2940 0 : pFkp = 0;
2941 : }
2942 : else
2943 : { // there was a Fkp
2944 : // Set PLCF one position back to retrieve the address of the Fkp
2945 0 : pPLCF->SetIdx( ( nIdx >> 8 ) - 1 );
2946 0 : if (NewFkp()) // read Fkp again
2947 : {
2948 0 : sal_uInt8 nFkpIdx = static_cast<sal_uInt8>(nIdx & 0xff);
2949 0 : pFkp->SetIdx(nFkpIdx); // set Fkp-Pos again
2950 : }
2951 : }
2952 0 : }
2953 :
2954 0 : bool WW8PLCFx_Fc_FKP::SeekPos(WW8_FC nFcPos)
2955 : {
2956 : // StartPos for next Where()
2957 0 : SetStartFc( nFcPos );
2958 :
2959 : // find StartPos for next pPLCF->Get()
2960 0 : bool bRet = pPLCF->SeekPos(nFcPos);
2961 :
2962 : // make FKP invalid?
2963 : WW8_CP nPLCFStart, nPLCFEnd;
2964 : void* pPage;
2965 0 : if( pFkp && pPLCF->Get( nPLCFStart, nPLCFEnd, pPage ) )
2966 : {
2967 0 : long nPo = SVBT16ToShort( (sal_uInt8 *)pPage );
2968 0 : nPo <<= 9; // shift as LONG
2969 0 : if (nPo != pFkp->GetFilePos())
2970 0 : pFkp = 0;
2971 : else
2972 0 : pFkp->SeekPos( nFcPos );
2973 : }
2974 0 : return bRet;
2975 : }
2976 :
2977 0 : WW8_FC WW8PLCFx_Fc_FKP::Where()
2978 : {
2979 0 : if( !pFkp )
2980 : {
2981 0 : if( !NewFkp() )
2982 0 : return WW8_FC_MAX;
2983 : }
2984 0 : WW8_FC nP = pFkp ? pFkp->Where() : WW8_FC_MAX;
2985 0 : if( nP != WW8_FC_MAX )
2986 0 : return nP;
2987 :
2988 0 : pFkp = 0; // FKP finished -> get new
2989 0 : return Where(); // easiest way: do it recursively
2990 : }
2991 :
2992 0 : sal_uInt8* WW8PLCFx_Fc_FKP::GetSprmsAndPos(WW8_FC& rStart, WW8_FC& rEnd, sal_Int32& rLen)
2993 : {
2994 0 : rLen = 0; // Default
2995 0 : rStart = rEnd = WW8_FC_MAX;
2996 :
2997 0 : if( !pFkp ) // Fkp not there ?
2998 : {
2999 0 : if( !NewFkp() )
3000 0 : return 0;
3001 : }
3002 :
3003 0 : sal_uInt8* pPos = pFkp ? pFkp->Get( rStart, rEnd, rLen ) : NULL;
3004 0 : if( rStart == WW8_FC_MAX ) //Not found
3005 0 : return 0;
3006 0 : 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 0 : sal_uInt16 WW8PLCFx_Fc_FKP::GetIstd() const
3026 : {
3027 0 : return pFkp ? pFkp->GetIstd() : 0xFFFF;
3028 : }
3029 :
3030 0 : void WW8PLCFx_Fc_FKP::GetPCDSprms( WW8PLCFxDesc& rDesc )
3031 : {
3032 0 : rDesc.pMemPos = 0;
3033 0 : rDesc.nSprmsLen = 0;
3034 0 : if( pPCDAttrs )
3035 : {
3036 0 : if( !pFkp )
3037 : {
3038 : OSL_FAIL("+Problem: GetPCDSprms: NewFkp necessary (not possible!)" );
3039 0 : if( !NewFkp() )
3040 0 : return;
3041 : }
3042 0 : pPCDAttrs->GetSprms(&rDesc);
3043 : }
3044 : }
3045 :
3046 0 : 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 0 : 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 0 : if (!pFkp)
3058 0 : return 0;
3059 :
3060 0 : const sal_uInt8* pRes = pFkp->HasSprm( nId );
3061 :
3062 0 : if( !pRes )
3063 : {
3064 0 : WW8PLCFxDesc aDesc;
3065 0 : GetPCDSprms( aDesc );
3066 :
3067 0 : 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 0 : 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 0 : 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 0 : bComplex( (7 < rBase.pWw8Fib->nVersion) || rBase.pWw8Fib->fComplex )
3117 : {
3118 0 : ResetAttrStartEnd();
3119 :
3120 0 : pPcd = rSBase.pPiecePLCF ? new WW8PLCFx_PCD(GetFIBVersion(),
3121 0 : 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 0 : if (pPcd)
3130 : {
3131 : pPCDAttrs = rSBase.pPLCFx_PCDAttrs ? new WW8PLCFx_PCDAttrs(
3132 0 : rSBase.pWw8Fib->GetFIBVersion(), pPcd, &rSBase) : 0;
3133 : }
3134 :
3135 0 : pPieceIter = rSBase.pPieceIter;
3136 0 : }
3137 :
3138 0 : WW8PLCFx_Cp_FKP::~WW8PLCFx_Cp_FKP()
3139 : {
3140 0 : delete pPcd;
3141 0 : }
3142 :
3143 0 : void WW8PLCFx_Cp_FKP::ResetAttrStartEnd()
3144 : {
3145 0 : nAttrStart = -1;
3146 0 : nAttrEnd = -1;
3147 0 : bLineEnd = false;
3148 0 : }
3149 :
3150 0 : sal_uLong WW8PLCFx_Cp_FKP::GetPCDIMax() const
3151 : {
3152 0 : return pPcd ? pPcd->GetIMax() : 0;
3153 : }
3154 :
3155 0 : sal_uLong WW8PLCFx_Cp_FKP::GetPCDIdx() const
3156 : {
3157 0 : return pPcd ? pPcd->GetIdx() : 0;
3158 : }
3159 :
3160 0 : void WW8PLCFx_Cp_FKP::SetPCDIdx( sal_uLong nIdx )
3161 : {
3162 0 : if( pPcd )
3163 0 : pPcd->SetIdx( nIdx );
3164 0 : }
3165 :
3166 0 : bool WW8PLCFx_Cp_FKP::SeekPos(WW8_CP nCpPos)
3167 : {
3168 0 : if( pPcd ) // Complex
3169 : {
3170 0 : if( !pPcd->SeekPos( nCpPos ) ) // set piece
3171 0 : return false;
3172 0 : if (pPCDAttrs && !pPCDAttrs->GetIter()->SeekPos(nCpPos))
3173 0 : return false;
3174 0 : return WW8PLCFx_Fc_FKP::SeekPos(pPcd->AktPieceStartCp2Fc(nCpPos));
3175 : }
3176 : // NO piece table !!!
3177 0 : return WW8PLCFx_Fc_FKP::SeekPos( rSBase.WW8Cp2Fc(nCpPos) );
3178 : }
3179 :
3180 0 : WW8_CP WW8PLCFx_Cp_FKP::Where()
3181 : {
3182 0 : WW8_FC nFc = WW8PLCFx_Fc_FKP::Where();
3183 0 : if( pPcd )
3184 0 : return pPcd->AktPieceStartFc2Cp( nFc ); // identify piece
3185 0 : return rSBase.WW8Fc2Cp( nFc ); // NO piece table !!!
3186 : }
3187 :
3188 0 : void WW8PLCFx_Cp_FKP::GetSprms(WW8PLCFxDesc* p)
3189 : {
3190 0 : WW8_CP nOrigCp = p->nStartPos;
3191 :
3192 0 : if (!GetDirty()) //Normal case
3193 : {
3194 : p->pMemPos = WW8PLCFx_Fc_FKP::GetSprmsAndPos(p->nStartPos, p->nEndPos,
3195 0 : 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 0 : if( !pPieceIter )
3211 0 : return;
3212 0 : sal_uLong nOldPos = pPieceIter->GetIdx();
3213 0 : bool bOk = pPieceIter->SeekPos(nOrigCp);
3214 0 : pPieceIter->SetIdx( nOldPos );
3215 0 : if (!bOk)
3216 0 : return;
3217 : }
3218 :
3219 0 : if( pPcd ) // piece table available
3220 : {
3221 : // Init ( no ++ called, yet )
3222 0 : if( (nAttrStart > nAttrEnd) || (nAttrStart == -1) )
3223 : {
3224 0 : p->bRealLineEnd = (ePLCF == PAP);
3225 :
3226 0 : if ( ((ePLCF == PAP ) || (ePLCF == CHP)) && (nOrigCp != WW8_CP_MAX) )
3227 : {
3228 0 : 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 0 : sal_uLong nOldPos = pPieceIter->GetIdx();
3240 0 : p->nStartPos = nOrigCp;
3241 0 : 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 0 : 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 0 : void* pData=NULL;
3263 0 : pPieceIter->Get(nCpStart, nCpEnd, pData);
3264 :
3265 0 : WW8_FC nLimitFC = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
3266 0 : WW8_FC nBeginLimitFC = nLimitFC;
3267 0 : if (IsEightPlus(GetFIBVersion()))
3268 : {
3269 : nBeginLimitFC =
3270 : WW8PLCFx_PCD::TransformPieceAddress(nLimitFC,
3271 0 : bIsUnicode);
3272 : }
3273 :
3274 : nLimitFC = nBeginLimitFC +
3275 0 : (nCpEnd - nCpStart) * (bIsUnicode ? 2 : 1);
3276 :
3277 0 : if (nOldEndPos <= nLimitFC)
3278 : {
3279 0 : p->nEndPos = nCpEnd -
3280 0 : (nLimitFC-nOldEndPos) / (bIsUnicode ? 2 : 1);
3281 : }
3282 : else
3283 : {
3284 0 : if (ePLCF == CHP)
3285 0 : 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 0 : pPieceIter->advance();
3307 :
3308 0 : for (;pPieceIter->GetIdx() < pPieceIter->GetIMax();
3309 0 : pPieceIter->advance())
3310 : {
3311 0 : if( !pPieceIter->Get( nCpStart, nCpEnd, pData ) )
3312 : {
3313 : OSL_ENSURE( !this, "piece iter broken!" );
3314 0 : break;
3315 : }
3316 0 : bIsUnicode = false;
3317 0 : sal_Int32 nFcStart=SVBT32ToUInt32(((WW8_PCD*)pData)->fc);
3318 :
3319 0 : if (IsEightPlus(GetFIBVersion()))
3320 : {
3321 : nFcStart =
3322 : WW8PLCFx_PCD::TransformPieceAddress(
3323 0 : nFcStart,bIsUnicode );
3324 : }
3325 :
3326 0 : nLimitFC = nFcStart + (nCpEnd - nCpStart) *
3327 0 : (bIsUnicode ? 2 : 1);
3328 :
3329 : //if it doesn't exist, skip it
3330 0 : if (!SeekPos(nCpStart))
3331 0 : continue;
3332 :
3333 : WW8_FC nOne,nSmallest;
3334 : p->pMemPos = WW8PLCFx_Fc_FKP::GetSprmsAndPos(nOne,
3335 0 : nSmallest, p->nSprmsLen);
3336 :
3337 0 : if (nSmallest <= nLimitFC)
3338 : {
3339 0 : WW8_CP nEndPos = nCpEnd -
3340 0 : (nLimitFC-nSmallest) / (bIsUnicode ? 2 : 1);
3341 :
3342 : OSL_ENSURE(nEndPos >= p->nStartPos, "EndPos before StartPos");
3343 :
3344 0 : if (nEndPos >= p->nStartPos)
3345 0 : p->nEndPos = nEndPos;
3346 :
3347 0 : break;
3348 : }
3349 : }
3350 : }
3351 : }
3352 0 : pPieceIter->SetIdx( nOldPos );
3353 : }
3354 : else
3355 0 : 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 0 : p->nStartPos = rSBase.WW8Fc2Cp( p->nStartPos );
3367 0 : p->nEndPos = rSBase.WW8Fc2Cp( p->nEndPos );
3368 0 : 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 0 : WW8PLCFx_SEPX::WW8PLCFx_SEPX(SvStream* pSt, SvStream* pTblSt,
3394 : const WW8Fib& rFib, WW8_CP nStartCp)
3395 : : WW8PLCFx(rFib.GetFIBVersion(), true), maSprmParser(rFib.GetFIBVersion()),
3396 0 : pStrm(pSt), nArrMax(256), nSprmSiz(0)
3397 : {
3398 : pPLCF = rFib.lcbPlcfsed
3399 : ? new WW8PLCF(*pTblSt, rFib.fcPlcfsed, rFib.lcbPlcfsed,
3400 0 : GetFIBVersion() <= ww::eWW2 ? 6 : 12, nStartCp)
3401 0 : : 0;
3402 :
3403 0 : pSprms = new sal_uInt8[nArrMax]; // maximum length
3404 0 : }
3405 :
3406 0 : WW8PLCFx_SEPX::~WW8PLCFx_SEPX()
3407 : {
3408 0 : delete pPLCF;
3409 0 : delete[] pSprms;
3410 0 : }
3411 :
3412 0 : sal_uLong WW8PLCFx_SEPX::GetIdx() const
3413 : {
3414 0 : return pPLCF ? pPLCF->GetIdx() : 0;
3415 : }
3416 :
3417 0 : void WW8PLCFx_SEPX::SetIdx( sal_uLong nIdx )
3418 : {
3419 0 : if( pPLCF ) pPLCF->SetIdx( nIdx );
3420 0 : }
3421 :
3422 0 : bool WW8PLCFx_SEPX::SeekPos(WW8_CP nCpPos)
3423 : {
3424 0 : 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 0 : void WW8PLCFx_SEPX::GetSprms(WW8PLCFxDesc* p)
3433 : {
3434 0 : if( !pPLCF ) return;
3435 :
3436 : void* pData;
3437 :
3438 0 : p->bRealLineEnd = false;
3439 0 : if (!pPLCF->Get( p->nStartPos, p->nEndPos, pData ))
3440 : {
3441 0 : p->nStartPos = p->nEndPos = WW8_CP_MAX; // PLCF completely processed
3442 0 : p->pMemPos = 0;
3443 0 : p->nSprmsLen = 0;
3444 : }
3445 : else
3446 : {
3447 0 : sal_uInt32 nPo = SVBT32ToUInt32( (sal_uInt8*)pData+2 );
3448 0 : 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 0 : pStrm->Seek( nPo );
3457 :
3458 : // read len
3459 0 : if (GetFIBVersion() <= ww::eWW2) // eWW6 ?, docs say yes, but...
3460 : {
3461 0 : sal_uInt8 nSiz(0);
3462 0 : pStrm->ReadUChar( nSiz );
3463 0 : nSprmSiz = nSiz;
3464 : }
3465 : else
3466 0 : pStrm->ReadUInt16( nSprmSiz );
3467 :
3468 0 : 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 0 : nSprmSiz = pStrm->Read(pSprms, nSprmSiz); // read Sprms
3475 :
3476 0 : p->nSprmsLen = nSprmSiz;
3477 0 : p->pMemPos = pSprms; // return Position
3478 : }
3479 : }
3480 : }
3481 :
3482 0 : void WW8PLCFx_SEPX::advance()
3483 : {
3484 0 : if (pPLCF)
3485 0 : pPLCF->advance();
3486 0 : }
3487 :
3488 0 : const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId ) const
3489 : {
3490 0 : return HasSprm( nId, pSprms, nSprmSiz);
3491 : }
3492 :
3493 0 : const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, const sal_uInt8* pOtherSprms,
3494 : long nOtherSprmSiz ) const
3495 : {
3496 0 : const sal_uInt8 *pRet = 0;
3497 0 : if (pPLCF)
3498 : {
3499 0 : WW8SprmIter aIter(pOtherSprms, nOtherSprmSiz, maSprmParser);
3500 0 : pRet = aIter.FindSprm(nId);
3501 : }
3502 0 : return pRet;
3503 : }
3504 :
3505 0 : 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 0 : if( !pPLCF )
3509 0 : return false;
3510 :
3511 0 : bool bFound = false;
3512 0 : p1 = 0;
3513 0 : p2 = 0;
3514 0 : p3 = 0;
3515 0 : p4 = 0;
3516 :
3517 0 : sal_uInt8* pSp = pSprms;
3518 0 : sal_uInt16 i=0;
3519 0 : while (i + maSprmParser.MinSprmLen() <= nSprmSiz)
3520 : {
3521 : // Sprm found?
3522 0 : sal_uInt16 nAktId = maSprmParser.GetSprmId(pSp);
3523 0 : bool bOk = true;
3524 0 : if( nAktId == nId1 )
3525 0 : p1 = pSp + maSprmParser.DistanceToData(nId1);
3526 0 : else if( nAktId == nId2 )
3527 0 : p2 = pSp + maSprmParser.DistanceToData(nId2);
3528 0 : else if( nAktId == nId3 )
3529 0 : p3 = pSp + maSprmParser.DistanceToData(nId3);
3530 0 : else if( nAktId == nId4 )
3531 0 : p4 = pSp + maSprmParser.DistanceToData(nId4);
3532 : else
3533 0 : bOk = false;
3534 0 : bFound |= bOk;
3535 : // increment pointer so that it points to next SPRM
3536 0 : sal_uInt16 x = maSprmParser.GetSprmSize(nAktId, pSp);
3537 0 : i = i + x;
3538 0 : pSp += x;
3539 : }
3540 0 : return bFound;
3541 : }
3542 :
3543 0 : const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const
3544 : {
3545 0 : if( !pPLCF )
3546 0 : return 0;
3547 :
3548 0 : sal_uInt8* pSp = pSprms;
3549 :
3550 0 : sal_uInt16 i=0;
3551 0 : while (i + maSprmParser.MinSprmLen() <= nSprmSiz)
3552 : {
3553 : // Sprm found?
3554 0 : sal_uInt16 nAktId = maSprmParser.GetSprmId(pSp);
3555 0 : if (nAktId == nId)
3556 : {
3557 0 : sal_uInt8 *pRet = pSp + maSprmParser.DistanceToData(nId);
3558 0 : if (*pRet == n2nd)
3559 0 : return pRet;
3560 : }
3561 : // increment pointer so that it points to next SPRM
3562 0 : sal_uInt16 x = maSprmParser.GetSprmSize(nAktId, pSp);
3563 0 : i = i + x;
3564 0 : pSp += x;
3565 : }
3566 :
3567 0 : return 0; // Sprm not found
3568 : }
3569 :
3570 0 : 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 0 : : WW8PLCFx(eVersion, true), pRef(0), pTxt(0)
3574 : {
3575 0 : if( nLenRef && nLenTxt )
3576 : {
3577 0 : pRef = new WW8PLCF(*pSt, nFcRef, nLenRef, nStruct, nStartCp);
3578 0 : pTxt = new WW8PLCF(*pSt, nFcTxt, nLenTxt, 0, nStartCp);
3579 : }
3580 0 : }
3581 :
3582 0 : WW8PLCFx_SubDoc::~WW8PLCFx_SubDoc()
3583 : {
3584 0 : delete pRef;
3585 0 : delete pTxt;
3586 0 : }
3587 :
3588 0 : sal_uLong WW8PLCFx_SubDoc::GetIdx() const
3589 : {
3590 : // Probably pTxt ... no need for it
3591 0 : if( pRef )
3592 0 : return ( pRef->GetIdx() << 16 | pTxt->GetIdx() );
3593 0 : return 0;
3594 : }
3595 :
3596 0 : void WW8PLCFx_SubDoc::SetIdx( sal_uLong nIdx )
3597 : {
3598 0 : if( pRef )
3599 : {
3600 0 : pRef->SetIdx( nIdx >> 16 );
3601 : // Probably pTxt ... no need for it
3602 0 : pTxt->SetIdx( nIdx & 0xFFFF );
3603 : }
3604 0 : }
3605 :
3606 0 : bool WW8PLCFx_SubDoc::SeekPos( WW8_CP nCpPos )
3607 : {
3608 0 : 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 0 : void WW8PLCFx_SubDoc::GetSprms(WW8PLCFxDesc* p)
3617 : {
3618 0 : p->nStartPos = p->nEndPos = WW8_CP_MAX;
3619 0 : p->pMemPos = 0;
3620 0 : p->nSprmsLen = 0;
3621 0 : p->bRealLineEnd = false;
3622 :
3623 0 : if (!pRef)
3624 0 : return;
3625 :
3626 0 : sal_uLong nNr = pRef->GetIdx();
3627 :
3628 : void *pData;
3629 : WW8_CP nFoo;
3630 0 : if (!pRef->Get(p->nStartPos, nFoo, pData))
3631 : {
3632 0 : p->nEndPos = p->nStartPos = WW8_CP_MAX;
3633 0 : return;
3634 : }
3635 :
3636 0 : p->nEndPos = p->nStartPos + 1;
3637 :
3638 0 : if (!pTxt)
3639 0 : return;
3640 :
3641 0 : pTxt->SetIdx(nNr);
3642 :
3643 0 : 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 0 : p->nSprmsLen -= p->nCp2OrIdx;
3651 : }
3652 :
3653 0 : void WW8PLCFx_SubDoc::advance()
3654 : {
3655 0 : if (pRef && pTxt)
3656 : {
3657 0 : pRef->advance();
3658 0 : pTxt->advance();
3659 : }
3660 0 : }
3661 :
3662 : // fields
3663 0 : WW8PLCFx_FLD::WW8PLCFx_FLD( SvStream* pSt, const WW8Fib& rMyFib, short nType)
3664 0 : : WW8PLCFx(rMyFib.GetFIBVersion(), true), pPLCF(0), rFib(rMyFib)
3665 : {
3666 : long nFc, nLen;
3667 :
3668 0 : switch( nType )
3669 : {
3670 : case MAN_HDFT:
3671 0 : nFc = rFib.fcPlcffldHdr;
3672 0 : nLen = rFib.lcbPlcffldHdr;
3673 0 : break;
3674 : case MAN_FTN:
3675 0 : nFc = rFib.fcPlcffldFtn;
3676 0 : nLen = rFib.lcbPlcffldFtn;
3677 0 : break;
3678 : case MAN_EDN:
3679 0 : nFc = rFib.fcPlcffldEdn;
3680 0 : nLen = rFib.lcbPlcffldEdn;
3681 0 : break;
3682 : case MAN_AND:
3683 0 : nFc = rFib.fcPlcffldAtn;
3684 0 : nLen = rFib.lcbPlcffldAtn;
3685 0 : break;
3686 : case MAN_TXBX:
3687 0 : nFc = rFib.fcPlcffldTxbx;
3688 0 : nLen = rFib.lcbPlcffldTxbx;
3689 0 : break;
3690 : case MAN_TXBX_HDFT:
3691 0 : nFc = rFib.fcPlcffldHdrTxbx;
3692 0 : nLen = rFib.lcbPlcffldHdrTxbx;
3693 0 : break;
3694 : default:
3695 0 : nFc = rFib.fcPlcffldMom;
3696 0 : nLen = rFib.lcbPlcffldMom;
3697 0 : break;
3698 : }
3699 :
3700 0 : if( nLen )
3701 0 : pPLCF = new WW8PLCFspecial( pSt, nFc, nLen, 2 );
3702 0 : }
3703 :
3704 0 : WW8PLCFx_FLD::~WW8PLCFx_FLD()
3705 : {
3706 0 : delete pPLCF;
3707 0 : }
3708 :
3709 0 : sal_uLong WW8PLCFx_FLD::GetIdx() const
3710 : {
3711 0 : return pPLCF ? pPLCF->GetIdx() : 0;
3712 : }
3713 :
3714 0 : void WW8PLCFx_FLD::SetIdx( sal_uLong nIdx )
3715 : {
3716 0 : if( pPLCF )
3717 0 : pPLCF->SetIdx( nIdx );
3718 0 : }
3719 :
3720 0 : bool WW8PLCFx_FLD::SeekPos(WW8_CP nCpPos)
3721 : {
3722 0 : 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 0 : bool WW8PLCFx_FLD::StartPosIsFieldStart()
3731 : {
3732 : void* pData;
3733 : sal_Int32 nTest;
3734 0 : if (
3735 0 : (!pPLCF || !pPLCF->Get(nTest, pData) ||
3736 0 : ((((sal_uInt8*)pData)[0] & 0x1f) != 0x13))
3737 : )
3738 0 : return false;
3739 0 : return true;
3740 : }
3741 :
3742 0 : bool WW8PLCFx_FLD::EndPosIsFieldEnd(WW8_CP& nCP)
3743 : {
3744 0 : bool bRet = false;
3745 :
3746 0 : if (pPLCF)
3747 : {
3748 0 : long n = pPLCF->GetIdx();
3749 :
3750 0 : pPLCF->advance();
3751 :
3752 : void* pData;
3753 : sal_Int32 nTest;
3754 0 : if ( pPLCF->Get(nTest, pData) && ((((sal_uInt8*)pData)[0] & 0x1f) == 0x15) )
3755 : {
3756 0 : nCP = nTest;
3757 0 : bRet = true;
3758 : }
3759 :
3760 0 : pPLCF->SetIdx(n);
3761 : }
3762 :
3763 0 : return bRet;
3764 : }
3765 :
3766 0 : void WW8PLCFx_FLD::GetSprms(WW8PLCFxDesc* p)
3767 : {
3768 0 : p->nStartPos = p->nEndPos = WW8_CP_MAX;
3769 0 : p->pMemPos = 0;
3770 0 : p->nSprmsLen = 0;
3771 0 : p->bRealLineEnd = false;
3772 :
3773 0 : if (!pPLCF)
3774 : {
3775 0 : p->nStartPos = WW8_CP_MAX; // there are no fields
3776 0 : return;
3777 : }
3778 :
3779 0 : long n = pPLCF->GetIdx();
3780 :
3781 : sal_Int32 nP;
3782 : void *pData;
3783 0 : if (!pPLCF->Get(nP, pData)) // end of PLCFspecial?
3784 : {
3785 0 : p->nStartPos = WW8_CP_MAX; // PLCF completely processed
3786 0 : return;
3787 : }
3788 :
3789 0 : p->nStartPos = nP;
3790 :
3791 0 : pPLCF->advance();
3792 0 : if (!pPLCF->Get(nP, pData)) // end of PLCFspecial?
3793 : {
3794 0 : p->nStartPos = WW8_CP_MAX; // PLCF completely processed
3795 0 : return;
3796 : }
3797 :
3798 0 : p->nEndPos = nP;
3799 :
3800 0 : pPLCF->SetIdx(n);
3801 :
3802 0 : p->nCp2OrIdx = pPLCF->GetIdx();
3803 : }
3804 :
3805 0 : void WW8PLCFx_FLD::advance()
3806 : {
3807 0 : pPLCF->advance();
3808 0 : }
3809 :
3810 0 : bool WW8PLCFx_FLD::GetPara(long nIdx, WW8FieldDesc& rF)
3811 : {
3812 : OSL_ENSURE( pPLCF, "Call without PLCFspecial field" );
3813 0 : if( !pPLCF )
3814 0 : return false;
3815 :
3816 0 : long n = pPLCF->GetIdx();
3817 0 : pPLCF->SetIdx(nIdx);
3818 :
3819 0 : bool bOk = WW8GetFieldPara(*pPLCF, rF);
3820 :
3821 0 : pPLCF->SetIdx(n);
3822 0 : return bOk;
3823 : }
3824 :
3825 : // WW8PLCF_Book
3826 :
3827 : /* to be optimized like this: */
3828 0 : 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 0 : if (nLen==0) // Handle Empty STTBF
3833 0 : return;
3834 :
3835 0 : sal_Size nOldPos = rStrm.Tell();
3836 0 : if (checkSeek(rStrm, nStart))
3837 : {
3838 0 : sal_uInt16 nLen2(0);
3839 0 : rStrm.ReadUInt16( nLen2 ); // bVer67: total length of structure
3840 : // bVer8 : count of strings
3841 :
3842 0 : if( bVer8 )
3843 : {
3844 0 : sal_uInt16 nStrings(0);
3845 0 : bool bUnicode = (0xFFFF == nLen2);
3846 0 : if (bUnicode)
3847 0 : rStrm.ReadUInt16( nStrings );
3848 : else
3849 0 : nStrings = nLen2;
3850 :
3851 0 : rStrm.ReadUInt16( nExtraLen );
3852 :
3853 0 : for (sal_uInt16 i=0; i < nStrings; ++i)
3854 : {
3855 0 : if (bUnicode)
3856 0 : rArray.push_back(read_uInt16_PascalString(rStrm));
3857 : else
3858 : {
3859 0 : OString aTmp = read_uInt8_lenPrefixed_uInt8s_ToOString(rStrm);
3860 0 : rArray.push_back(OStringToOUString(aTmp, eCS));
3861 : }
3862 :
3863 : // Skip the extra data
3864 0 : if (nExtraLen)
3865 : {
3866 0 : if (pExtraArray)
3867 : {
3868 0 : ww::bytes extraData;
3869 0 : for (sal_uInt16 j = 0; j < nExtraLen; ++j)
3870 : {
3871 0 : sal_uInt8 iTmp(0);
3872 0 : rStrm.ReadUChar( iTmp );
3873 0 : extraData.push_back(iTmp);
3874 : }
3875 0 : 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 0 : 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 0 : rStrm.Seek(nOldPos);
3946 : }
3947 :
3948 0 : WW8PLCFx_Book::WW8PLCFx_Book(SvStream* pTblSt, const WW8Fib& rFib)
3949 0 : : WW8PLCFx(rFib.GetFIBVersion(), false), pStatus(0), nIsEnd(0), nBookmarkId(1)
3950 : {
3951 0 : if( !rFib.fcPlcfbkf || !rFib.lcbPlcfbkf || !rFib.fcPlcfbkl ||
3952 0 : !rFib.lcbPlcfbkl || !rFib.fcSttbfbkmk || !rFib.lcbSttbfbkmk )
3953 : {
3954 0 : pBook[0] = pBook[1] = 0;
3955 0 : nIMax = 0;
3956 : }
3957 : else
3958 : {
3959 0 : pBook[0] = new WW8PLCFspecial(pTblSt,rFib.fcPlcfbkf,rFib.lcbPlcfbkf,4);
3960 :
3961 0 : pBook[1] = new WW8PLCFspecial(pTblSt,rFib.fcPlcfbkl,rFib.lcbPlcfbkl,0);
3962 :
3963 0 : rtl_TextEncoding eStructChrSet = WW8Fib::GetFIBCharset(rFib.chseTables);
3964 :
3965 : WW8ReadSTTBF( (7 < rFib.nVersion), *pTblSt, rFib.fcSttbfbkmk,
3966 0 : rFib.lcbSttbfbkmk, 0, eStructChrSet, aBookNames );
3967 :
3968 0 : nIMax = aBookNames.size();
3969 :
3970 0 : if( pBook[0]->GetIMax() < nIMax ) // Count of Bookmarks
3971 0 : nIMax = pBook[0]->GetIMax();
3972 0 : if( pBook[1]->GetIMax() < nIMax )
3973 0 : nIMax = pBook[1]->GetIMax();
3974 0 : pStatus = new eBookStatus[ nIMax ];
3975 0 : memset( pStatus, 0, nIMax * sizeof( eBookStatus ) );
3976 : }
3977 0 : }
3978 :
3979 0 : WW8PLCFx_Book::~WW8PLCFx_Book()
3980 : {
3981 0 : delete[] pStatus;
3982 0 : delete pBook[1];
3983 0 : delete pBook[0];
3984 0 : }
3985 :
3986 0 : sal_uLong WW8PLCFx_Book::GetIdx() const
3987 : {
3988 0 : return nIMax ? pBook[0]->GetIdx() : 0;
3989 : }
3990 :
3991 0 : void WW8PLCFx_Book::SetIdx( sal_uLong nI )
3992 : {
3993 0 : if( nIMax )
3994 0 : pBook[0]->SetIdx( nI );
3995 0 : }
3996 :
3997 0 : sal_uLong WW8PLCFx_Book::GetIdx2() const
3998 : {
3999 0 : return nIMax ? ( pBook[1]->GetIdx() | ( ( nIsEnd ) ? 0x80000000 : 0 ) ) : 0;
4000 : }
4001 :
4002 0 : void WW8PLCFx_Book::SetIdx2( sal_uLong nI )
4003 : {
4004 0 : if( nIMax )
4005 : {
4006 0 : pBook[1]->SetIdx( nI & 0x7fffffff );
4007 0 : nIsEnd = (sal_uInt16)( ( nI >> 31 ) & 1 ); // 0 oder 1
4008 : }
4009 0 : }
4010 :
4011 0 : bool WW8PLCFx_Book::SeekPos(WW8_CP nCpPos)
4012 : {
4013 0 : if( !pBook[0] )
4014 0 : return false;
4015 :
4016 0 : bool bOk = pBook[0]->SeekPosExact( nCpPos );
4017 0 : bOk &= pBook[1]->SeekPosExact( nCpPos );
4018 0 : nIsEnd = 0;
4019 :
4020 0 : return bOk;
4021 : }
4022 :
4023 0 : WW8_CP WW8PLCFx_Book::Where()
4024 : {
4025 0 : return pBook[nIsEnd]->Where();
4026 : }
4027 :
4028 0 : long WW8PLCFx_Book::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
4029 : {
4030 : void* pData;
4031 0 : rEnd = WW8_CP_MAX;
4032 0 : rLen = 0;
4033 :
4034 0 : if (!pBook[0] || !pBook[1] || !nIMax || (pBook[nIsEnd]->GetIdx()) >= nIMax)
4035 : {
4036 0 : rStart = rEnd = WW8_CP_MAX;
4037 0 : return -1;
4038 : }
4039 :
4040 0 : pBook[nIsEnd]->Get( rStart, pData ); // query position
4041 0 : 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 0 : void WW8PLCFx_Book::advance()
4056 : {
4057 0 : if( pBook[0] && pBook[1] && nIMax )
4058 : {
4059 0 : (*pBook[nIsEnd]).advance();
4060 :
4061 0 : sal_uLong l0 = pBook[0]->Where();
4062 0 : sal_uLong l1 = pBook[1]->Where();
4063 0 : if( l0 < l1 )
4064 0 : nIsEnd = 0;
4065 0 : else if( l1 < l0 )
4066 0 : nIsEnd = 1;
4067 : else
4068 : {
4069 0 : const void * p = pBook[0]->GetData(pBook[0]->GetIdx());
4070 0 : long nPairFor = (p == NULL)? 0L : SVBT16ToShort(*((SVBT16*) p));
4071 0 : if (nPairFor == pBook[1]->GetIdx())
4072 0 : nIsEnd = 0;
4073 : else
4074 0 : nIsEnd = ( nIsEnd ) ? 0 : 1;
4075 : }
4076 : }
4077 0 : }
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 0 : eBookStatus WW8PLCFx_Book::GetStatus() const
4106 : {
4107 0 : if( !pStatus )
4108 0 : return BOOK_NORMAL;
4109 0 : long nEndIdx = GetHandle();
4110 0 : return ( nEndIdx < nIMax ) ? pStatus[nEndIdx] : BOOK_NORMAL;
4111 : }
4112 :
4113 0 : long WW8PLCFx_Book::GetHandle() const
4114 : {
4115 0 : if( !pBook[0] || !pBook[1] )
4116 0 : return LONG_MAX;
4117 :
4118 0 : if( nIsEnd )
4119 0 : return pBook[1]->GetIdx();
4120 : else
4121 : {
4122 0 : if (const void* p = pBook[0]->GetData(pBook[0]->GetIdx()))
4123 0 : return SVBT16ToShort( *((SVBT16*)p) );
4124 : else
4125 0 : return LONG_MAX;
4126 : }
4127 : }
4128 :
4129 0 : OUString WW8PLCFx_Book::GetBookmark(long nStart,long nEnd, sal_uInt16 &nIndex)
4130 : {
4131 0 : bool bFound = false;
4132 0 : sal_uInt16 i = 0;
4133 0 : 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 0 : return bFound ? aBookNames[i] : OUString();
4162 : }
4163 :
4164 0 : OUString WW8PLCFx_Book::GetUniqueBookmarkName(const OUString &rSuggestedName)
4165 : {
4166 0 : OUString aRet(rSuggestedName.isEmpty() ? OUString("Unnamed") : rSuggestedName);
4167 0 : size_t i = 0;
4168 0 : 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 0 : return aRet;
4183 : }
4184 :
4185 0 : bool WW8PLCFx_Book::MapName(OUString& rName)
4186 : {
4187 0 : if( !pBook[0] || !pBook[1] )
4188 0 : return false;
4189 :
4190 0 : bool bFound = false;
4191 0 : sal_uInt16 i = 0;
4192 0 : do
4193 : {
4194 0 : if (rName.equalsIgnoreAsciiCase(aBookNames[i]))
4195 : {
4196 0 : rName = aBookNames[i];
4197 0 : bFound = true;
4198 : }
4199 0 : ++i;
4200 : }
4201 0 : while (!bFound && i < pBook[0]->GetIMax());
4202 0 : return bFound;
4203 : }
4204 :
4205 0 : const OUString* WW8PLCFx_Book::GetName() const
4206 : {
4207 0 : const OUString *pRet = 0;
4208 0 : if (!nIsEnd && (pBook[0]->GetIdx() < nIMax))
4209 0 : pRet = &(aBookNames[pBook[0]->GetIdx()]);
4210 0 : 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 0 : 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 0 : rDesc.nOrigEndPos = rDesc.nEndPos;
4223 0 : 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 0 : if (GetDoingDrawTextBox())
4233 0 : return;
4234 :
4235 0 : if ( (&rDesc == pPap) && rDesc.bRealLineEnd )
4236 : {
4237 0 : if ( pPap->nEndPos != WW8_CP_MAX ) // Para adjust
4238 : {
4239 0 : nLineEnd = pPap->nEndPos;// nLineEnd zeigt *hinter* das <CR>
4240 0 : 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 0 : if (pChp->nEndPos == nLineEnd)
4245 0 : pChp->nEndPos--;
4246 :
4247 : // gibt es bereits ein Sep-Ende, das auf das jetzige Absatzende
4248 : // zeigt ? ... dann auch um 1 Zeichen verkuerzen
4249 0 : if( pSep->nEndPos == nLineEnd )
4250 0 : pSep->nEndPos--;
4251 : }
4252 : }
4253 0 : else if ( (&rDesc == pChp) || (&rDesc == pSep) )
4254 : {
4255 : // Char Adjust oder Sep Adjust Wenn Ende Char-Attr == Absatzende ...
4256 0 : if( (rDesc.nEndPos == nLineEnd) && (rDesc.nEndPos > rDesc.nStartPos) )
4257 0 : rDesc.nEndPos--; // ... dann um 1 Zeichen verkuerzen
4258 : }
4259 : }
4260 :
4261 0 : void WW8PLCFxDesc::ReduceByOffset()
4262 : {
4263 : OSL_ENSURE((WW8_CP_MAX == nStartPos) || (nStartPos <= nEndPos),
4264 : "Attr-Anfang und -Ende ueber Kreuz" );
4265 :
4266 0 : 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 0 : if (nCpOfs > nStartPos)
4275 0 : nStartPos = 0;
4276 : else
4277 0 : nStartPos -= nCpOfs;
4278 : }
4279 0 : if( nEndPos != WW8_CP_MAX )
4280 : {
4281 : OSL_ENSURE(nCpOfs <= nEndPos,
4282 : "oh oh, so much for the subdocument piece theory");
4283 0 : nEndPos -= nCpOfs;
4284 : }
4285 0 : }
4286 :
4287 0 : void WW8PLCFMan::GetNewSprms( WW8PLCFxDesc& rDesc )
4288 : {
4289 0 : rDesc.pPLCFx->GetSprms(&rDesc);
4290 0 : rDesc.ReduceByOffset();
4291 :
4292 0 : rDesc.bFirstSprm = true;
4293 0 : AdjustEnds( rDesc );
4294 0 : rDesc.nOrigSprmsLen = rDesc.nSprmsLen;
4295 0 : }
4296 :
4297 0 : void WW8PLCFMan::GetNewNoSprms( WW8PLCFxDesc& rDesc )
4298 : {
4299 : rDesc.nCp2OrIdx = rDesc.pPLCFx->GetNoSprms(rDesc.nStartPos, rDesc.nEndPos,
4300 0 : rDesc.nSprmsLen);
4301 :
4302 : OSL_ENSURE((WW8_CP_MAX == rDesc.nStartPos) || (rDesc.nStartPos <= rDesc.nEndPos),
4303 : "Attr-Anfang und -Ende ueber Kreuz" );
4304 :
4305 0 : rDesc.ReduceByOffset();
4306 :
4307 0 : rDesc.bFirstSprm = true;
4308 0 : rDesc.nOrigSprmsLen = rDesc.nSprmsLen;
4309 0 : }
4310 :
4311 0 : sal_uInt16 WW8PLCFMan::GetId(const WW8PLCFxDesc* p) const
4312 : {
4313 0 : sal_uInt16 nId = 0; // Id = 0 for empty attributes
4314 :
4315 0 : if (p == pFld)
4316 0 : nId = eFLD;
4317 0 : else if (p == pFtn)
4318 0 : nId = eFTN;
4319 0 : else if (p == pEdn)
4320 0 : nId = eEDN;
4321 0 : else if (p == pAnd)
4322 0 : nId = eAND;
4323 0 : else if (p->nSprmsLen >= maSprmParser.MinSprmLen())
4324 0 : nId = maSprmParser.GetSprmId(p->pMemPos);
4325 :
4326 0 : return nId;
4327 : }
4328 :
4329 0 : WW8PLCFMan::WW8PLCFMan(WW8ScannerBase* pBase, ManTypes nType, long nStartCp,
4330 : bool bDoingDrawTextBox)
4331 : : maSprmParser(pBase->pWw8Fib->GetFIBVersion()),
4332 0 : mbDoingDrawTextBox(bDoingDrawTextBox)
4333 : {
4334 0 : pWwFib = pBase->pWw8Fib;
4335 :
4336 0 : nLastWhereIdxCp = 0;
4337 0 : memset( aD, 0, sizeof( aD ) );
4338 0 : nLineEnd = WW8_CP_MAX;
4339 0 : nManType = nType;
4340 : sal_uInt16 i;
4341 :
4342 0 : if( MAN_MAINTEXT == nType )
4343 : {
4344 : // Suchreihenfolge der Attribute
4345 0 : nPLCF = MAN_ANZ_PLCF;
4346 0 : pFld = &aD[0];
4347 0 : pBkm = &aD[1];
4348 0 : pEdn = &aD[2];
4349 0 : pFtn = &aD[3];
4350 0 : pAnd = &aD[4];
4351 :
4352 0 : pPcd = ( pBase->pPLCFx_PCD ) ? &aD[5] : 0;
4353 : //pPcdA index == pPcd index + 1
4354 0 : pPcdA = ( pBase->pPLCFx_PCDAttrs ) ? &aD[6] : 0;
4355 :
4356 0 : pChp = &aD[7];
4357 0 : pPap = &aD[8];
4358 0 : pSep = &aD[9];
4359 :
4360 0 : pSep->pPLCFx = pBase->pSepPLCF;
4361 0 : pFtn->pPLCFx = pBase->pFtnPLCF;
4362 0 : pEdn->pPLCFx = pBase->pEdnPLCF;
4363 0 : pBkm->pPLCFx = pBase->pBook;
4364 0 : pAnd->pPLCFx = pBase->pAndPLCF;
4365 :
4366 : }
4367 : else
4368 : {
4369 : // Suchreihenfolge der Attribute
4370 0 : nPLCF = 7;
4371 0 : pFld = &aD[0];
4372 0 : pBkm = ( pBase->pBook ) ? &aD[1] : 0;
4373 :
4374 0 : pPcd = ( pBase->pPLCFx_PCD ) ? &aD[2] : 0;
4375 : //pPcdA index == pPcd index + 1
4376 0 : pPcdA= ( pBase->pPLCFx_PCDAttrs ) ? &aD[3] : 0;
4377 :
4378 0 : pChp = &aD[4];
4379 0 : pPap = &aD[5];
4380 0 : pSep = &aD[6]; // Dummy
4381 :
4382 0 : pAnd = pFtn = pEdn = 0; // unbenutzt bei SpezText
4383 : }
4384 :
4385 0 : pChp->pPLCFx = pBase->pChpPLCF;
4386 0 : pPap->pPLCFx = pBase->pPapPLCF;
4387 0 : if( pPcd )
4388 0 : pPcd->pPLCFx = pBase->pPLCFx_PCD;
4389 0 : if( pPcdA )
4390 0 : pPcdA->pPLCFx= pBase->pPLCFx_PCDAttrs;
4391 0 : if( pBkm )
4392 0 : pBkm->pPLCFx = pBase->pBook;
4393 :
4394 0 : pMagicTables = pBase->pMagicTables;
4395 0 : pSubdocs = pBase->pSubdocs;
4396 0 : pExtendedAtrds = pBase->pExtendedAtrds;
4397 :
4398 0 : switch( nType ) // Feld-Initialisierung
4399 : {
4400 : case MAN_HDFT:
4401 0 : pFld->pPLCFx = pBase->pFldHdFtPLCF;
4402 0 : pFdoa = pBase->pHdFtFdoa;
4403 0 : pTxbx = pBase->pHdFtTxbx;
4404 0 : pTxbxBkd = pBase->pHdFtTxbxBkd;
4405 0 : break;
4406 : case MAN_FTN:
4407 0 : pFld->pPLCFx = pBase->pFldFtnPLCF;
4408 0 : pFdoa = pTxbx = pTxbxBkd = 0;
4409 0 : 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 0 : pFld->pPLCFx = pBase->pFldAndPLCF;
4416 0 : pFdoa = pTxbx = pTxbxBkd = 0;
4417 0 : break;
4418 : case MAN_TXBX:
4419 0 : pFld->pPLCFx = pBase->pFldTxbxPLCF;
4420 0 : pTxbx = pBase->pMainTxbx;
4421 0 : pTxbxBkd = pBase->pMainTxbxBkd;
4422 0 : pFdoa = 0;
4423 0 : 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 0 : pFld->pPLCFx = pBase->pFldPLCF;
4432 0 : pFdoa = pBase->pMainFdoa;
4433 0 : pTxbx = pBase->pMainTxbx;
4434 0 : pTxbxBkd = pBase->pMainTxbxBkd;
4435 0 : break;
4436 : }
4437 :
4438 0 : nCpO = pWwFib->GetBaseCp(nType);
4439 :
4440 0 : if( nStartCp || nCpO )
4441 0 : SeekPos( nStartCp ); // PLCFe auf Text-StartPos einstellen
4442 :
4443 : // initialisieren der Member-Vars Low-Level
4444 0 : GetChpPLCF()->ResetAttrStartEnd();
4445 0 : GetPapPLCF()->ResetAttrStartEnd();
4446 0 : for( i=0; i < nPLCF; i++)
4447 : {
4448 0 : 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 0 : p->nCpOfs = ( p == pChp || p == pPap || p == pBkm || p == pPcd ||
4458 0 : p == pPcdA ) ? nCpO : 0;
4459 :
4460 0 : p->nCp2OrIdx = 0;
4461 0 : p->bFirstSprm = false;
4462 0 : p->pIdStk = 0;
4463 :
4464 0 : if ((p == pChp) || (p == pPap))
4465 0 : p->nStartPos = p->nEndPos = nStartCp;
4466 : else
4467 0 : p->nStartPos = p->nEndPos = WW8_CP_MAX;
4468 : }
4469 :
4470 : // initialisieren der Member-Vars High-Level
4471 0 : for( i=0; i<nPLCF; i++){
4472 0 : WW8PLCFxDesc* p = &aD[i];
4473 :
4474 0 : if( !p->pPLCFx )
4475 : {
4476 0 : p->nStartPos = p->nEndPos = WW8_CP_MAX;
4477 0 : continue;
4478 : }
4479 :
4480 0 : if( p->pPLCFx->IsSprm() )
4481 : {
4482 : // Vorsicht: nEndPos muss bereits
4483 0 : p->pIdStk = new std::stack<sal_uInt16>;
4484 0 : if ((p == pChp) || (p == pPap))
4485 : {
4486 0 : WW8_CP nTemp = p->nEndPos+p->nCpOfs;
4487 0 : p->pMemPos = 0;
4488 0 : p->nSprmsLen = 0;
4489 0 : p->nStartPos = nTemp;
4490 0 : if (!(*p->pPLCFx).SeekPos(p->nStartPos))
4491 0 : p->nEndPos = p->nStartPos = WW8_CP_MAX;
4492 : else
4493 0 : GetNewSprms( *p );
4494 : }
4495 : else
4496 0 : GetNewSprms( *p ); // bei allen PLCFen initialisiert sein
4497 : }
4498 0 : else if( p->pPLCFx )
4499 0 : GetNewNoSprms( *p );
4500 : }
4501 0 : }
4502 :
4503 0 : WW8PLCFMan::~WW8PLCFMan()
4504 : {
4505 0 : for( sal_uInt16 i=0; i<nPLCF; i++)
4506 0 : delete aD[i].pIdStk;
4507 0 : }
4508 :
4509 : // 0. welche Attr.-Klasse,
4510 : // 1. ob ein Attr.-Start ist,
4511 : // 2. CP, wo ist naechste Attr.-Aenderung
4512 0 : sal_uInt16 WW8PLCFMan::WhereIdx(bool* pbStart, long* pPos) const
4513 : {
4514 : OSL_ENSURE(nPLCF,"What the hell");
4515 0 : long nNext = LONG_MAX; // SuchReihenfolge:
4516 0 : sal_uInt16 nNextIdx = nPLCF;// first ending found ( CHP, PAP, ( SEP ) ),
4517 0 : bool bStart = true; // dann Anfaenge finden ( ( SEP ), PAP, CHP )
4518 : sal_uInt16 i;
4519 : const WW8PLCFxDesc* pD;
4520 0 : for (i=0; i < nPLCF; i++)
4521 : {
4522 0 : pD = &aD[i];
4523 0 : if (pD != pPcdA)
4524 : {
4525 0 : if( (pD->nEndPos < nNext) && (pD->nStartPos == WW8_CP_MAX) )
4526 : {
4527 : // sonst ist Anfang = Ende
4528 0 : nNext = pD->nEndPos;
4529 0 : nNextIdx = i;
4530 0 : bStart = false;
4531 : }
4532 : }
4533 : }
4534 0 : for (i=nPLCF; i > 0; i--)
4535 : {
4536 0 : pD = &aD[i-1];
4537 0 : if (pD != pPcdA)
4538 : {
4539 0 : if( pD->nStartPos < nNext )
4540 : {
4541 0 : nNext = pD->nStartPos;
4542 0 : nNextIdx = i-1;
4543 0 : bStart = true;
4544 : }
4545 : }
4546 : }
4547 0 : if( pPos )
4548 0 : *pPos = nNext;
4549 0 : if( pbStart )
4550 0 : *pbStart = bStart;
4551 0 : return nNextIdx;
4552 : }
4553 :
4554 : // gibt die CP-Pos der naechsten Attribut-Aenderung zurueck
4555 0 : WW8_CP WW8PLCFMan::Where() const
4556 : {
4557 : long l;
4558 0 : WhereIdx(0, &l);
4559 0 : return l;
4560 : }
4561 :
4562 0 : void WW8PLCFMan::SeekPos( long nNewCp )
4563 : {
4564 0 : pChp->pPLCFx->SeekPos( nNewCp + nCpO ); // Attribute neu
4565 0 : pPap->pPLCFx->SeekPos( nNewCp + nCpO ); // aufsetzen
4566 0 : pFld->pPLCFx->SeekPos( nNewCp );
4567 0 : if( pPcd )
4568 0 : pPcd->pPLCFx->SeekPos( nNewCp + nCpO );
4569 0 : if( pBkm )
4570 0 : pBkm->pPLCFx->SeekPos( nNewCp + nCpO );
4571 0 : }
4572 :
4573 0 : void WW8PLCFMan::SaveAllPLCFx( WW8PLCFxSaveAll& rSave ) const
4574 : {
4575 0 : sal_uInt16 i, n=0;
4576 0 : if( pPcd )
4577 0 : pPcd->Save( rSave.aS[n++] );
4578 0 : if( pPcdA )
4579 0 : pPcdA->Save( rSave.aS[n++] );
4580 :
4581 0 : for(i=0; i<nPLCF; ++i)
4582 0 : if( pPcd != &aD[i] && pPcdA != &aD[i] )
4583 0 : aD[i].Save( rSave.aS[n++] );
4584 0 : }
4585 :
4586 0 : void WW8PLCFMan::RestoreAllPLCFx( const WW8PLCFxSaveAll& rSave )
4587 : {
4588 0 : sal_uInt16 i, n=0;
4589 0 : if( pPcd )
4590 0 : pPcd->Restore( rSave.aS[n++] );
4591 0 : if( pPcdA )
4592 0 : pPcdA->Restore( rSave.aS[n++] );
4593 :
4594 0 : for(i=0; i<nPLCF; ++i)
4595 0 : if( pPcd != &aD[i] && pPcdA != &aD[i] )
4596 0 : aD[i].Restore( rSave.aS[n++] );
4597 0 : }
4598 :
4599 0 : void WW8PLCFMan::GetSprmStart( short nIdx, WW8PLCFManResult* pRes ) const
4600 : {
4601 0 : memset( pRes, 0, sizeof( WW8PLCFManResult ) );
4602 :
4603 : // Pruefen !!!
4604 :
4605 0 : pRes->nMemLen = 0;
4606 :
4607 0 : const WW8PLCFxDesc* p = &aD[nIdx];
4608 :
4609 : // first Sprm in a Group
4610 0 : if( p->bFirstSprm )
4611 : {
4612 0 : if( p == pPap )
4613 0 : pRes->nFlags |= MAN_MASK_NEW_PAP;
4614 0 : else if( p == pSep )
4615 0 : pRes->nFlags |= MAN_MASK_NEW_SEP;
4616 : }
4617 0 : pRes->pMemPos = p->pMemPos;
4618 0 : pRes->nSprmId = GetId(p);
4619 0 : pRes->nCp2OrIdx = p->nCp2OrIdx;
4620 0 : if ((p == pFtn) || (p == pEdn) || (p == pAnd))
4621 0 : pRes->nMemLen = p->nSprmsLen;
4622 0 : else if (p->nSprmsLen >= maSprmParser.MinSprmLen()) //Normal
4623 : {
4624 : // Length of actual sprm
4625 0 : pRes->nMemLen = maSprmParser.GetSprmSize(pRes->nSprmId, pRes->pMemPos);
4626 : }
4627 0 : }
4628 :
4629 0 : void WW8PLCFMan::GetSprmEnd( short nIdx, WW8PLCFManResult* pRes ) const
4630 : {
4631 0 : memset( pRes, 0, sizeof( WW8PLCFManResult ) );
4632 :
4633 0 : const WW8PLCFxDesc* p = &aD[nIdx];
4634 :
4635 0 : if (!(p->pIdStk->empty()))
4636 0 : 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 0 : }
4643 :
4644 0 : void WW8PLCFMan::GetNoSprmStart( short nIdx, WW8PLCFManResult* pRes ) const
4645 : {
4646 0 : const WW8PLCFxDesc* p = &aD[nIdx];
4647 :
4648 0 : pRes->nCpPos = p->nStartPos;
4649 0 : pRes->nMemLen = p->nSprmsLen;
4650 0 : pRes->nCp2OrIdx = p->nCp2OrIdx;
4651 :
4652 0 : if( p == pFld )
4653 0 : pRes->nSprmId = eFLD;
4654 0 : else if( p == pFtn )
4655 0 : pRes->nSprmId = eFTN;
4656 0 : else if( p == pEdn )
4657 0 : pRes->nSprmId = eEDN;
4658 0 : else if( p == pBkm )
4659 0 : pRes->nSprmId = eBKN;
4660 0 : else if( p == pAnd )
4661 0 : pRes->nSprmId = eAND;
4662 0 : 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 0 : GetSprmStart( nIdx+1, pRes );
4667 : }
4668 : else
4669 0 : pRes->nSprmId = 0; // default: not found
4670 0 : }
4671 :
4672 0 : void WW8PLCFMan::GetNoSprmEnd( short nIdx, WW8PLCFManResult* pRes ) const
4673 : {
4674 0 : pRes->nMemLen = -1; // Ende-Kennzeichen
4675 :
4676 0 : if( &aD[nIdx] == pBkm )
4677 0 : pRes->nSprmId = eBKN;
4678 0 : 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 0 : GetSprmEnd( nIdx+1, pRes );
4683 : }
4684 : else
4685 0 : pRes->nSprmId = 0;
4686 0 : }
4687 :
4688 0 : bool WW8PLCFMan::TransferOpenSprms(std::stack<sal_uInt16> &rStack)
4689 : {
4690 0 : for (int i = 0; i < nPLCF; ++i)
4691 : {
4692 0 : WW8PLCFxDesc* p = &aD[i];
4693 0 : if (!p || !p->pIdStk)
4694 0 : continue;
4695 0 : while (!p->pIdStk->empty())
4696 : {
4697 0 : rStack.push(p->pIdStk->top());
4698 0 : p->pIdStk->pop();
4699 : }
4700 : }
4701 0 : return rStack.empty();
4702 : }
4703 :
4704 0 : void WW8PLCFMan::AdvSprm(short nIdx, bool bStart)
4705 : {
4706 0 : WW8PLCFxDesc* p = &aD[nIdx]; // Sprm-Klasse(!) ermitteln
4707 :
4708 0 : p->bFirstSprm = false;
4709 0 : if( bStart )
4710 : {
4711 0 : sal_uInt16 nLastId = GetId(p);
4712 0 : p->pIdStk->push(nLastId); // merke Id fuer Attribut-Ende
4713 :
4714 0 : if( p->nSprmsLen )
4715 : { /*
4716 : Pruefe, ob noch Sprm(s) abzuarbeiten sind
4717 : */
4718 0 : if( p->pMemPos )
4719 : {
4720 : // Length of last sprm
4721 0 : sal_uInt16 nSprmL = maSprmParser.GetSprmSize(nLastId, p->pMemPos);
4722 :
4723 : // Gesamtlaenge Sprms um SprmLaenge verringern
4724 0 : p->nSprmsLen -= nSprmL;
4725 :
4726 : // Pos des evtl. naechsten Sprm
4727 0 : if (p->nSprmsLen < maSprmParser.MinSprmLen())
4728 : {
4729 : // sicherheitshalber auf Null setzen, da Enden folgen!
4730 0 : p->pMemPos = 0;
4731 0 : p->nSprmsLen = 0;
4732 : }
4733 : else
4734 0 : p->pMemPos += nSprmL;
4735 : }
4736 : else
4737 0 : p->nSprmsLen = 0;
4738 : }
4739 0 : if (p->nSprmsLen < maSprmParser.MinSprmLen())
4740 0 : p->nStartPos = WW8_CP_MAX; // es folgen Enden
4741 : }
4742 : else
4743 : {
4744 0 : if (!(p->pIdStk->empty()))
4745 0 : p->pIdStk->pop();
4746 0 : if (p->pIdStk->empty())
4747 : {
4748 0 : if ( (p == pChp) || (p == pPap) )
4749 : {
4750 0 : p->pMemPos = 0;
4751 0 : p->nSprmsLen = 0;
4752 0 : 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 0 : if (!(*p->pPLCFx).SeekPos(p->nStartPos))
4761 : {
4762 0 : p->nEndPos = WW8_CP_MAX;
4763 0 : p->pPLCFx->SetDirty(true);
4764 : }
4765 0 : if (!p->pPLCFx->GetDirty() || pPcd)
4766 0 : GetNewSprms( *p );
4767 0 : 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 0 : if (pPcd && ((p->nStartPos > pPcd->nStartPos) ||
4793 0 : (pPcd->nStartPos == WW8_CP_MAX)) &&
4794 0 : (pPcd->nEndPos != p->nStartPos))
4795 : {
4796 0 : pPcd->nEndPos = p->nStartPos;
4797 : ((WW8PLCFx_PCD *)(pPcd->pPLCFx))->SetClipStart(
4798 0 : p->nStartPos);
4799 : }
4800 :
4801 : }
4802 : else
4803 : {
4804 0 : p->pPLCFx->advance(); // next Group of Sprms
4805 0 : p->pMemPos = 0; // !!!
4806 0 : p->nSprmsLen = 0;
4807 0 : GetNewSprms( *p );
4808 : }
4809 : OSL_ENSURE( p->nStartPos <= p->nEndPos, "Attribut ueber Kreuz" );
4810 : }
4811 : }
4812 0 : }
4813 :
4814 0 : 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 0 : WW8PLCFxDesc* p = &aD[nIdx];
4823 :
4824 0 : if( p == pPcd )
4825 : {
4826 0 : AdvSprm(nIdx+1,bStart);
4827 0 : if( bStart )
4828 0 : p->nStartPos = aD[nIdx+1].nStartPos;
4829 : else
4830 : {
4831 0 : if (aD[nIdx+1].pIdStk->empty())
4832 : {
4833 0 : 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 0 : if (pTemp->GetClipStart() == -1)
4842 0 : p->pPLCFx->advance();
4843 0 : p->pMemPos = 0;
4844 0 : p->nSprmsLen = 0;
4845 0 : GetNewSprms( aD[nIdx+1] );
4846 0 : GetNewNoSprms( *p );
4847 0 : 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 0 : p->nStartPos = pTemp->GetClipStart();
4856 0 : pTemp->SetClipStart(-1);
4857 : }
4858 : }
4859 : }
4860 : }
4861 : else
4862 : { // NoSprm ohne Ende
4863 0 : p->pPLCFx->advance();
4864 0 : p->pMemPos = 0; // MemPos ungueltig
4865 0 : p->nSprmsLen = 0;
4866 0 : GetNewNoSprms( *p );
4867 : }
4868 0 : }
4869 :
4870 0 : void WW8PLCFMan::advance()
4871 : {
4872 : bool bStart;
4873 0 : sal_uInt16 nIdx = WhereIdx(&bStart);
4874 0 : if (nIdx < nPLCF)
4875 : {
4876 0 : WW8PLCFxDesc* p = &aD[nIdx];
4877 :
4878 0 : p->bFirstSprm = true; // Default
4879 :
4880 0 : if( p->pPLCFx->IsSprm() )
4881 0 : AdvSprm( nIdx, bStart );
4882 : else // NoSprm
4883 0 : AdvNoSprm( nIdx, bStart );
4884 : }
4885 0 : }
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 0 : bool WW8PLCFMan::Get(WW8PLCFManResult* pRes) const
4892 : {
4893 0 : memset( pRes, 0, sizeof( WW8PLCFManResult ) );
4894 : bool bStart;
4895 0 : sal_uInt16 nIdx = WhereIdx(&bStart);
4896 :
4897 0 : if( nIdx >= nPLCF )
4898 : {
4899 : OSL_ENSURE( !this, "Position not found" );
4900 0 : return true;
4901 : }
4902 :
4903 0 : if( aD[nIdx].pPLCFx->IsSprm() )
4904 : {
4905 0 : if( bStart )
4906 : {
4907 0 : GetSprmStart( nIdx, pRes );
4908 0 : return true;
4909 : }
4910 : else
4911 : {
4912 0 : GetSprmEnd( nIdx, pRes );
4913 0 : return false;
4914 : }
4915 : }
4916 : else
4917 : {
4918 0 : if( bStart )
4919 : {
4920 0 : GetNoSprmStart( nIdx, pRes );
4921 0 : return true;
4922 : }
4923 : else
4924 : {
4925 0 : GetNoSprmEnd( nIdx, pRes );
4926 0 : return false;
4927 : }
4928 : }
4929 : }
4930 :
4931 0 : sal_uInt16 WW8PLCFMan::GetColl() const
4932 : {
4933 0 : if( pPap->pPLCFx )
4934 0 : return pPap->pPLCFx->GetIstd();
4935 : else
4936 : {
4937 : OSL_ENSURE( !this, "GetColl ohne PLCF_Pap" );
4938 0 : return 0;
4939 : }
4940 : }
4941 :
4942 0 : WW8PLCFx_FLD* WW8PLCFMan::GetFld() const
4943 : {
4944 0 : return (WW8PLCFx_FLD*)pFld->pPLCFx;
4945 : }
4946 :
4947 0 : const sal_uInt8* WW8PLCFMan::HasParaSprm( sal_uInt16 nId ) const
4948 : {
4949 0 : return ((WW8PLCFx_Cp_FKP*)pPap->pPLCFx)->HasSprm( nId );
4950 : }
4951 :
4952 0 : const sal_uInt8* WW8PLCFMan::HasCharSprm( sal_uInt16 nId ) const
4953 : {
4954 0 : 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 0 : void WW8PLCFx::Save( WW8PLCFxSave1& rSave ) const
4966 : {
4967 0 : rSave.nPLCFxPos = GetIdx();
4968 0 : rSave.nPLCFxPos2 = GetIdx2();
4969 0 : rSave.nPLCFxMemOfs = 0;
4970 0 : rSave.nStartFC = GetStartFc();
4971 0 : }
4972 :
4973 0 : void WW8PLCFx::Restore( const WW8PLCFxSave1& rSave )
4974 : {
4975 0 : SetIdx( rSave.nPLCFxPos );
4976 0 : SetIdx2( rSave.nPLCFxPos2 );
4977 0 : SetStartFc( rSave.nStartFC );
4978 0 : }
4979 :
4980 0 : sal_uLong WW8PLCFx_Cp_FKP::GetIdx2() const
4981 : {
4982 0 : return GetPCDIdx();
4983 : }
4984 :
4985 0 : void WW8PLCFx_Cp_FKP::SetIdx2( sal_uLong nIdx )
4986 : {
4987 0 : SetPCDIdx( nIdx );
4988 0 : }
4989 :
4990 0 : void WW8PLCFx_Cp_FKP::Save( WW8PLCFxSave1& rSave ) const
4991 : {
4992 0 : WW8PLCFx::Save( rSave );
4993 :
4994 0 : rSave.nAttrStart = nAttrStart;
4995 0 : rSave.nAttrEnd = nAttrEnd;
4996 0 : rSave.bLineEnd = bLineEnd;
4997 0 : }
4998 :
4999 0 : void WW8PLCFx_Cp_FKP::Restore( const WW8PLCFxSave1& rSave )
5000 : {
5001 0 : WW8PLCFx::Restore( rSave );
5002 :
5003 0 : nAttrStart = rSave.nAttrStart;
5004 0 : nAttrEnd = rSave.nAttrEnd;
5005 0 : bLineEnd = rSave.bLineEnd;
5006 0 : }
5007 :
5008 0 : void WW8PLCFxDesc::Save( WW8PLCFxSave1& rSave ) const
5009 : {
5010 0 : if( pPLCFx )
5011 : {
5012 0 : pPLCFx->Save( rSave );
5013 0 : if( pPLCFx->IsSprm() )
5014 : {
5015 0 : WW8PLCFxDesc aD;
5016 0 : aD.nStartPos = nOrigStartPos+nCpOfs;
5017 0 : aD.nCpOfs = rSave.nCpOfs = nCpOfs;
5018 0 : if (!(pPLCFx->SeekPos(aD.nStartPos)))
5019 : {
5020 0 : aD.nEndPos = WW8_CP_MAX;
5021 0 : pPLCFx->SetDirty(true);
5022 : }
5023 0 : pPLCFx->GetSprms(&aD);
5024 0 : pPLCFx->SetDirty(false);
5025 0 : aD.ReduceByOffset();
5026 0 : rSave.nStartCp = aD.nStartPos;
5027 0 : rSave.nPLCFxMemOfs = nOrigSprmsLen - nSprmsLen;
5028 : }
5029 : }
5030 0 : }
5031 :
5032 0 : void WW8PLCFxDesc::Restore( const WW8PLCFxSave1& rSave )
5033 : {
5034 0 : if( pPLCFx )
5035 : {
5036 0 : pPLCFx->Restore( rSave );
5037 0 : if( pPLCFx->IsSprm() )
5038 : {
5039 0 : WW8PLCFxDesc aD;
5040 0 : aD.nStartPos = rSave.nStartCp+rSave.nCpOfs;
5041 0 : nCpOfs = aD.nCpOfs = rSave.nCpOfs;
5042 0 : if (!(pPLCFx->SeekPos(aD.nStartPos)))
5043 : {
5044 0 : aD.nEndPos = WW8_CP_MAX;
5045 0 : pPLCFx->SetDirty(true);
5046 : }
5047 0 : pPLCFx->GetSprms(&aD);
5048 0 : pPLCFx->SetDirty(false);
5049 0 : aD.ReduceByOffset();
5050 0 : pMemPos = aD.pMemPos + rSave.nPLCFxMemOfs;
5051 : }
5052 : }
5053 0 : }
5054 :
5055 : namespace
5056 : {
5057 0 : sal_uInt32 Readcb(SvStream& rSt, ww::WordVersion eVer)
5058 : {
5059 0 : if (eVer <= ww::eWW2)
5060 : {
5061 : sal_uInt16 nShort;
5062 0 : rSt.ReadUInt16( nShort );
5063 0 : return nShort;
5064 : }
5065 : else
5066 : {
5067 : sal_uInt32 nLong;
5068 0 : rSt.ReadUInt32( nLong );
5069 0 : return nLong;
5070 : }
5071 : }
5072 : }
5073 :
5074 0 : WW8_CP WW8Fib::GetBaseCp(ManTypes nType) const
5075 : {
5076 0 : WW8_CP nOffset = 0;
5077 :
5078 0 : switch( nType )
5079 : {
5080 : default:
5081 : case MAN_MAINTEXT:
5082 0 : break;
5083 : case MAN_FTN:
5084 0 : nOffset = ccpText;
5085 0 : break;
5086 : case MAN_HDFT:
5087 0 : nOffset = ccpText + ccpFtn;
5088 0 : 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 0 : nOffset = ccpText + ccpFtn + ccpHdr + ccpMcr;
5101 0 : break;
5102 : case MAN_EDN:
5103 0 : nOffset = ccpText + ccpFtn + ccpHdr + ccpMcr + ccpAtn;
5104 0 : break;
5105 : case MAN_TXBX:
5106 0 : nOffset = ccpText + ccpFtn + ccpHdr + ccpMcr + ccpAtn + ccpEdn;
5107 0 : break;
5108 : case MAN_TXBX_HDFT:
5109 0 : nOffset = ccpText + ccpFtn + ccpHdr + ccpMcr + ccpAtn + ccpEdn +
5110 0 : ccpTxbx;
5111 0 : break;
5112 : }
5113 0 : return nOffset;
5114 : }
5115 :
5116 0 : ww::WordVersion WW8Fib::GetFIBVersion() const
5117 : {
5118 0 : 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 0 : if (wIdent == 0xa5db)
5136 0 : eVer = ww::eWW2;
5137 : else
5138 : {
5139 0 : 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 0 : eVer = ww::eWW8;
5149 0 : break;
5150 : }
5151 : }
5152 0 : return eVer;
5153 : }
5154 :
5155 0 : WW8Fib::WW8Fib(SvStream& rSt, sal_uInt8 nWantedVersion, sal_uInt32 nOffset)
5156 0 : : nFibError( 0 )
5157 : {
5158 0 : memset(this, 0, sizeof(*this));
5159 : sal_uInt8 aBits1;
5160 : sal_uInt8 aBits2;
5161 : sal_uInt8 aVer8Bits1; // nur ab WinWord 8 benutzt
5162 0 : rSt.Seek( nOffset );
5163 : /*
5164 : Wunsch-Nr vermerken, File-Versionsnummer ermitteln
5165 : und gegen Wunsch-Nr. checken !
5166 : */
5167 0 : nVersion = nWantedVersion;
5168 0 : rSt.ReadUInt16( wIdent );
5169 0 : rSt.ReadUInt16( nFib );
5170 0 : rSt.ReadUInt16( nProduct );
5171 0 : 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 0 : ww::WordVersion eVer = GetFIBVersion();
5208 :
5209 : // Hilfs-Varis fuer Ver67:
5210 0 : sal_Int16 pnChpFirst_Ver67=0;
5211 0 : sal_Int16 pnPapFirst_Ver67=0;
5212 0 : sal_Int16 cpnBteChp_Ver67=0;
5213 0 : sal_Int16 cpnBtePap_Ver67=0;
5214 :
5215 : // und auf gehts: FIB einlesen
5216 0 : rSt.ReadInt16( lid );
5217 0 : rSt.ReadInt16( pnNext );
5218 0 : rSt.ReadUChar( aBits1 );
5219 0 : rSt.ReadUChar( aBits2 );
5220 0 : rSt.ReadUInt16( nFibBack );
5221 0 : rSt.ReadUInt16( nHash );
5222 0 : rSt.ReadUInt16( nKey );
5223 0 : rSt.ReadUChar( envr );
5224 0 : 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 0 : rSt.ReadUInt16( chse );
5234 0 : rSt.ReadUInt16( chseTables );
5235 0 : rSt.ReadInt32( fcMin );
5236 0 : rSt.ReadInt32( fcMac );
5237 :
5238 : // Einschub fuer WW8 *****************************************************
5239 0 : if (IsEightPlus(eVer))
5240 : {
5241 0 : rSt.ReadUInt16( csw );
5242 :
5243 : // Marke: "rgsw" Beginning of the array of shorts
5244 0 : rSt.ReadUInt16( wMagicCreated );
5245 0 : rSt.ReadUInt16( wMagicRevised );
5246 0 : rSt.ReadUInt16( wMagicCreatedPrivate );
5247 0 : rSt.ReadUInt16( wMagicRevisedPrivate );
5248 0 : 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 0 : rSt.ReadInt16( lidFE );
5263 0 : rSt.ReadUInt16( clw );
5264 : }
5265 :
5266 : // Ende des Einschubs fuer WW8 *******************************************
5267 :
5268 : // Marke: "rglw" Beginning of the array of longs
5269 0 : rSt.ReadInt32( cbMac );
5270 :
5271 : // 2 Longs uebergehen, da unwichtiger Quatsch
5272 0 : rSt.SeekRel( 2 * sizeof( sal_Int32) );
5273 :
5274 : // weitere 2 Longs nur bei Ver67 ueberspringen
5275 0 : if (IsSevenMinus(eVer))
5276 0 : rSt.SeekRel( 2 * sizeof( sal_Int32) );
5277 :
5278 0 : rSt.ReadInt32( ccpText );
5279 0 : rSt.ReadInt32( ccpFtn );
5280 0 : rSt.ReadInt32( ccpHdr );
5281 0 : rSt.ReadInt32( ccpMcr );
5282 0 : rSt.ReadInt32( ccpAtn );
5283 0 : rSt.ReadInt32( ccpEdn );
5284 0 : rSt.ReadInt32( ccpTxbx );
5285 0 : rSt.ReadInt32( ccpHdrTxbx );
5286 :
5287 : // weiteres Long nur bei Ver67 ueberspringen
5288 0 : if (IsSevenMinus(eVer))
5289 0 : rSt.SeekRel( 1 * sizeof( sal_Int32) );
5290 : else
5291 : {
5292 : // Einschub fuer WW8 *****************************************************
5293 0 : rSt.ReadInt32( pnFbpChpFirst );
5294 0 : rSt.ReadInt32( pnChpFirst );
5295 0 : rSt.ReadInt32( cpnBteChp );
5296 0 : rSt.ReadInt32( pnFbpPapFirst );
5297 0 : rSt.ReadInt32( pnPapFirst );
5298 0 : rSt.ReadInt32( cpnBtePap );
5299 0 : rSt.ReadInt32( pnFbpLvcFirst );
5300 0 : rSt.ReadInt32( pnLvcFirst );
5301 0 : rSt.ReadInt32( cpnBteLvc );
5302 0 : rSt.ReadInt32( fcIslandFirst );
5303 0 : rSt.ReadInt32( fcIslandLim );
5304 0 : rSt.ReadUInt16( cfclcb );
5305 : }
5306 :
5307 : // Ende des Einschubs fuer WW8 *******************************************
5308 :
5309 : // Marke: "rgfclcb" Beginning of array of FC/LCB pairs.
5310 0 : rSt.ReadInt32( fcStshfOrig );
5311 0 : lcbStshfOrig = Readcb(rSt, eVer);
5312 0 : rSt.ReadInt32( fcStshf );
5313 0 : lcbStshf = Readcb(rSt, eVer);
5314 0 : rSt.ReadInt32( fcPlcffndRef );
5315 0 : lcbPlcffndRef = Readcb(rSt, eVer);
5316 0 : rSt.ReadInt32( fcPlcffndTxt );
5317 0 : lcbPlcffndTxt = Readcb(rSt, eVer);
5318 0 : rSt.ReadInt32( fcPlcfandRef );
5319 0 : lcbPlcfandRef = Readcb(rSt, eVer);
5320 0 : rSt.ReadInt32( fcPlcfandTxt );
5321 0 : lcbPlcfandTxt = Readcb(rSt, eVer);
5322 0 : rSt.ReadInt32( fcPlcfsed );
5323 0 : lcbPlcfsed = Readcb(rSt, eVer);
5324 0 : rSt.ReadInt32( fcPlcfpad );
5325 0 : lcbPlcfpad = Readcb(rSt, eVer);
5326 0 : rSt.ReadInt32( fcPlcfphe );
5327 0 : lcbPlcfphe = Readcb(rSt, eVer);
5328 0 : rSt.ReadInt32( fcSttbfglsy );
5329 0 : lcbSttbfglsy = Readcb(rSt, eVer);
5330 0 : rSt.ReadInt32( fcPlcfglsy );
5331 0 : lcbPlcfglsy = Readcb(rSt, eVer);
5332 0 : rSt.ReadInt32( fcPlcfhdd );
5333 0 : lcbPlcfhdd = Readcb(rSt, eVer);
5334 0 : rSt.ReadInt32( fcPlcfbteChpx );
5335 0 : lcbPlcfbteChpx = Readcb(rSt, eVer);
5336 0 : rSt.ReadInt32( fcPlcfbtePapx );
5337 0 : lcbPlcfbtePapx = Readcb(rSt, eVer);
5338 0 : rSt.ReadInt32( fcPlcfsea );
5339 0 : lcbPlcfsea = Readcb(rSt, eVer);
5340 0 : rSt.ReadInt32( fcSttbfffn );
5341 0 : lcbSttbfffn = Readcb(rSt, eVer);
5342 0 : rSt.ReadInt32( fcPlcffldMom );
5343 0 : lcbPlcffldMom = Readcb(rSt, eVer);
5344 0 : rSt.ReadInt32( fcPlcffldHdr );
5345 0 : lcbPlcffldHdr = Readcb(rSt, eVer);
5346 0 : rSt.ReadInt32( fcPlcffldFtn );
5347 0 : lcbPlcffldFtn = Readcb(rSt, eVer);
5348 0 : rSt.ReadInt32( fcPlcffldAtn );
5349 0 : lcbPlcffldAtn = Readcb(rSt, eVer);
5350 0 : rSt.ReadInt32( fcPlcffldMcr );
5351 0 : lcbPlcffldMcr = Readcb(rSt, eVer);
5352 0 : rSt.ReadInt32( fcSttbfbkmk );
5353 0 : lcbSttbfbkmk = Readcb(rSt, eVer);
5354 0 : rSt.ReadInt32( fcPlcfbkf );
5355 0 : lcbPlcfbkf = Readcb(rSt, eVer);
5356 0 : rSt.ReadInt32( fcPlcfbkl );
5357 0 : lcbPlcfbkl = Readcb(rSt, eVer);
5358 0 : rSt.ReadInt32( fcCmds );
5359 0 : lcbCmds = Readcb(rSt, eVer);
5360 0 : rSt.ReadInt32( fcPlcfmcr );
5361 0 : lcbPlcfmcr = Readcb(rSt, eVer);
5362 0 : rSt.ReadInt32( fcSttbfmcr );
5363 0 : lcbSttbfmcr = Readcb(rSt, eVer);
5364 0 : rSt.ReadInt32( fcPrDrvr );
5365 0 : lcbPrDrvr = Readcb(rSt, eVer);
5366 0 : rSt.ReadInt32( fcPrEnvPort );
5367 0 : lcbPrEnvPort = Readcb(rSt, eVer);
5368 0 : rSt.ReadInt32( fcPrEnvLand );
5369 0 : lcbPrEnvLand = Readcb(rSt, eVer);
5370 0 : rSt.ReadInt32( fcWss );
5371 0 : lcbWss = Readcb(rSt, eVer);
5372 0 : rSt.ReadInt32( fcDop );
5373 0 : lcbDop = Readcb(rSt, eVer);
5374 0 : rSt.ReadInt32( fcSttbfAssoc );
5375 0 : lcbSttbfAssoc = Readcb(rSt, eVer);
5376 0 : rSt.ReadInt32( fcClx );
5377 0 : lcbClx = Readcb(rSt, eVer);
5378 0 : rSt.ReadInt32( fcPlcfpgdFtn );
5379 0 : lcbPlcfpgdFtn = Readcb(rSt, eVer);
5380 0 : rSt.ReadInt32( fcAutosaveSource );
5381 0 : lcbAutosaveSource = Readcb(rSt, eVer);
5382 0 : rSt.ReadInt32( fcGrpStAtnOwners );
5383 0 : lcbGrpStAtnOwners = Readcb(rSt, eVer);
5384 0 : rSt.ReadInt32( fcSttbfAtnbkmk );
5385 0 : lcbSttbfAtnbkmk = Readcb(rSt, eVer);
5386 :
5387 : // weiteres short nur bei Ver67 ueberspringen
5388 0 : if (IsSevenMinus(eVer))
5389 : {
5390 0 : rSt.SeekRel( 1*sizeof( sal_Int16) );
5391 :
5392 : // folgende 4 Shorts existieren nur bei Ver67;
5393 0 : rSt.ReadInt16( pnChpFirst_Ver67 );
5394 0 : rSt.ReadInt16( pnPapFirst_Ver67 );
5395 0 : rSt.ReadInt16( cpnBteChp_Ver67 );
5396 0 : rSt.ReadInt16( cpnBtePap_Ver67 );
5397 : }
5398 :
5399 0 : if (eVer > ww::eWW2)
5400 : {
5401 0 : rSt.ReadInt32( fcPlcfdoaMom );
5402 0 : rSt.ReadInt32( lcbPlcfdoaMom );
5403 0 : rSt.ReadInt32( fcPlcfdoaHdr );
5404 0 : rSt.ReadInt32( lcbPlcfdoaHdr );
5405 0 : rSt.ReadInt32( fcPlcfspaMom );
5406 0 : rSt.ReadInt32( lcbPlcfspaMom );
5407 0 : rSt.ReadInt32( fcPlcfspaHdr );
5408 0 : rSt.ReadInt32( lcbPlcfspaHdr );
5409 :
5410 0 : rSt.ReadInt32( fcPlcfAtnbkf );
5411 0 : rSt.ReadInt32( lcbPlcfAtnbkf );
5412 0 : rSt.ReadInt32( fcPlcfAtnbkl );
5413 0 : rSt.ReadInt32( lcbPlcfAtnbkl );
5414 0 : rSt.ReadInt32( fcPms );
5415 0 : rSt.ReadInt32( lcbPMS );
5416 0 : rSt.ReadInt32( fcFormFldSttbf );
5417 0 : rSt.ReadInt32( lcbFormFldSttbf );
5418 0 : rSt.ReadInt32( fcPlcfendRef );
5419 0 : rSt.ReadInt32( lcbPlcfendRef );
5420 0 : rSt.ReadInt32( fcPlcfendTxt );
5421 0 : rSt.ReadInt32( lcbPlcfendTxt );
5422 0 : rSt.ReadInt32( fcPlcffldEdn );
5423 0 : rSt.ReadInt32( lcbPlcffldEdn );
5424 0 : rSt.ReadInt32( fcPlcfpgdEdn );
5425 0 : rSt.ReadInt32( lcbPlcfpgdEdn );
5426 0 : rSt.ReadInt32( fcDggInfo );
5427 0 : rSt.ReadInt32( lcbDggInfo );
5428 0 : rSt.ReadInt32( fcSttbfRMark );
5429 0 : rSt.ReadInt32( lcbSttbfRMark );
5430 0 : rSt.ReadInt32( fcSttbfCaption );
5431 0 : rSt.ReadInt32( lcbSttbfCaption );
5432 0 : rSt.ReadInt32( fcSttbAutoCaption );
5433 0 : rSt.ReadInt32( lcbSttbAutoCaption );
5434 0 : rSt.ReadInt32( fcPlcfwkb );
5435 0 : rSt.ReadInt32( lcbPlcfwkb );
5436 0 : rSt.ReadInt32( fcPlcfspl );
5437 0 : rSt.ReadInt32( lcbPlcfspl );
5438 0 : rSt.ReadInt32( fcPlcftxbxTxt );
5439 0 : rSt.ReadInt32( lcbPlcftxbxTxt );
5440 0 : rSt.ReadInt32( fcPlcffldTxbx );
5441 0 : rSt.ReadInt32( lcbPlcffldTxbx );
5442 0 : rSt.ReadInt32( fcPlcfHdrtxbxTxt );
5443 0 : rSt.ReadInt32( lcbPlcfHdrtxbxTxt );
5444 0 : rSt.ReadInt32( fcPlcffldHdrTxbx );
5445 0 : rSt.ReadInt32( lcbPlcffldHdrTxbx );
5446 0 : rSt.ReadInt32( fcStwUser );
5447 0 : rSt.ReadUInt32( lcbStwUser );
5448 0 : rSt.ReadInt32( fcSttbttmbd );
5449 0 : rSt.ReadUInt32( lcbSttbttmbd );
5450 : }
5451 :
5452 0 : if( 0 == rSt.GetError() )
5453 : {
5454 : // Bit-Flags setzen
5455 0 : fDot = aBits1 & 0x01 ;
5456 0 : fGlsy = ( aBits1 & 0x02 ) >> 1;
5457 0 : fComplex = ( aBits1 & 0x04 ) >> 2;
5458 0 : fHasPic = ( aBits1 & 0x08 ) >> 3;
5459 0 : cQuickSaves = ( aBits1 & 0xf0 ) >> 4;
5460 0 : fEncrypted = aBits2 & 0x01 ;
5461 0 : fWhichTblStm= ( aBits2 & 0x02 ) >> 1;
5462 0 : fReadOnlyRecommended = (aBits2 & 0x4) >> 2;
5463 0 : fWriteReservation = (aBits2 & 0x8) >> 3;
5464 0 : fExtChar = ( aBits2 & 0x10 ) >> 4;
5465 : // dummy = ( aBits2 & 0x20 ) >> 5;
5466 0 : 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 0 : if (IsSevenMinus(eVer))
5474 : {
5475 0 : pnChpFirst = pnChpFirst_Ver67;
5476 0 : pnPapFirst = pnPapFirst_Ver67;
5477 0 : cpnBteChp = cpnBteChp_Ver67;
5478 0 : cpnBtePap = cpnBtePap_Ver67;
5479 : }
5480 0 : else if (IsEightPlus(eVer))
5481 : {
5482 0 : fMac = aVer8Bits1 & 0x01 ;
5483 0 : fEmptySpecial = ( aVer8Bits1 & 0x02 ) >> 1;
5484 0 : fLoadOverridePage = ( aVer8Bits1 & 0x04 ) >> 2;
5485 0 : fFuturesavedUndo = ( aVer8Bits1 & 0x08 ) >> 3;
5486 0 : fWord97Saved = ( aVer8Bits1 & 0x10 ) >> 4;
5487 0 : 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 0 : long nOldPos = rSt.Tell();
5495 :
5496 0 : rSt.Seek( 0x02da );
5497 0 : rSt.ReadInt32( fcSttbFnm );
5498 0 : rSt.ReadInt32( lcbSttbFnm );
5499 0 : rSt.ReadInt32( fcPlcfLst );
5500 0 : rSt.ReadInt32( lcbPlcfLst );
5501 0 : rSt.ReadInt32( fcPlfLfo );
5502 0 : rSt.ReadInt32( lcbPlfLfo );
5503 0 : rSt.ReadInt32( fcPlcftxbxBkd );
5504 0 : rSt.ReadInt32( lcbPlcftxbxBkd );
5505 0 : rSt.ReadInt32( fcPlcfHdrtxbxBkd );
5506 0 : rSt.ReadInt32( lcbPlcfHdrtxbxBkd );
5507 0 : if( 0 != rSt.GetError() )
5508 : {
5509 0 : nFibError = ERR_SWG_READ_ERROR;
5510 : }
5511 :
5512 0 : rSt.Seek( 0x372 ); // fcSttbListNames
5513 0 : rSt.ReadInt32( fcSttbListNames );
5514 0 : rSt.ReadInt32( lcbSttbListNames );
5515 :
5516 0 : if (cfclcb > 93)
5517 : {
5518 0 : rSt.Seek( 0x382 ); // MagicTables
5519 0 : rSt.ReadInt32( fcPlcfTch );
5520 0 : rSt.ReadInt32( lcbPlcfTch );
5521 : }
5522 :
5523 0 : if (cfclcb > 113)
5524 : {
5525 0 : rSt.Seek( 0x41A ); // new ATRD
5526 0 : rSt.ReadInt32( fcAtrdExtra );
5527 0 : rSt.ReadUInt32( lcbAtrdExtra );
5528 : }
5529 :
5530 0 : if( 0 != rSt.GetError() )
5531 0 : nFibError = ERR_SWG_READ_ERROR;
5532 :
5533 0 : rSt.Seek( 0x5bc ); // Actual nFib introduced in Word 2003
5534 0 : rSt.ReadUInt16( nFib_actual );
5535 :
5536 0 : rSt.Seek( nOldPos );
5537 : }
5538 : }
5539 : else
5540 : {
5541 0 : nFibError = ERR_SWG_READ_ERROR; // Error melden
5542 : }
5543 : }
5544 :
5545 0 : WW8Fib::WW8Fib(sal_uInt8 nVer, bool bDot)
5546 : {
5547 0 : memset(this, 0, sizeof(*this));
5548 0 : nVersion = nVer;
5549 0 : if (8 == nVer)
5550 : {
5551 0 : fcMin = 0x800;
5552 0 : wIdent = 0xa5ec;
5553 0 : nFib = 0x0101;
5554 0 : nFibBack = 0xbf;
5555 0 : nProduct = 0x204D;
5556 0 : fDot = bDot;
5557 :
5558 0 : csw = 0x0e; // muss das sein ???
5559 0 : cfclcb = 0x88; // -""-
5560 0 : clw = 0x16; // -""-
5561 0 : pnFbpChpFirst = pnFbpPapFirst = pnFbpLvcFirst = 0x000fffff;
5562 0 : fExtChar = true;
5563 0 : fWord97Saved = fWord2000Saved = true;
5564 :
5565 0 : wMagicCreated = 0x6143;
5566 0 : wMagicRevised = 0x6C6F;
5567 0 : wMagicCreatedPrivate = 0x6E61;
5568 0 : 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 0 : cQuickSaves = nFib >= 0x00D9 ? 0xF : 0;
5580 :
5581 : // --> #i90932#
5582 0 : lid = 0x409; // LANGUAGE_ENGLISH_US
5583 :
5584 0 : LanguageType nLang = Application::GetSettings().GetLanguageTag().getLanguageType();
5585 0 : fFarEast = MsLangId::isCJK(nLang);
5586 0 : if (fFarEast)
5587 0 : lidFE = nLang;
5588 : else
5589 0 : lidFE = lid;
5590 :
5591 0 : LanguageTag aLanguageTag( lid );
5592 0 : LocaleDataWrapper aLocaleWrapper( aLanguageTag );
5593 0 : nNumDecimalSep = aLocaleWrapper.getNumDecimalSep()[0];
5594 0 : }
5595 :
5596 0 : sal_Unicode WW8Fib::getNumDecimalSep() const
5597 : {
5598 0 : return nNumDecimalSep;
5599 : }
5600 :
5601 0 : bool WW8Fib::WriteHeader(SvStream& rStrm)
5602 : {
5603 0 : bool bVer8 = 8 == nVersion;
5604 :
5605 0 : size_t nUnencryptedHdr = bVer8 ? 0x44 : 0x24;
5606 0 : sal_uInt8 *pDataPtr = new sal_uInt8[ nUnencryptedHdr ];
5607 0 : sal_uInt8 *pData = pDataPtr;
5608 0 : memset( pData, 0, nUnencryptedHdr );
5609 :
5610 0 : sal_uLong nPos = rStrm.Tell();
5611 0 : cbMac = rStrm.Seek( STREAM_SEEK_TO_END );
5612 0 : rStrm.Seek( nPos );
5613 :
5614 0 : Set_UInt16( pData, wIdent );
5615 0 : Set_UInt16( pData, nFib );
5616 0 : Set_UInt16( pData, nProduct );
5617 0 : Set_UInt16( pData, lid );
5618 0 : Set_UInt16( pData, pnNext );
5619 :
5620 0 : sal_uInt16 nBits16 = 0;
5621 0 : if( fDot ) nBits16 |= 0x0001;
5622 0 : if( fGlsy) nBits16 |= 0x0002;
5623 0 : if( fComplex ) nBits16 |= 0x0004;
5624 0 : if( fHasPic ) nBits16 |= 0x0008;
5625 0 : nBits16 |= (0xf0 & ( cQuickSaves << 4 ));
5626 0 : if( fEncrypted ) nBits16 |= 0x0100;
5627 0 : if( fWhichTblStm ) nBits16 |= 0x0200;
5628 :
5629 0 : if (fReadOnlyRecommended)
5630 0 : nBits16 |= 0x0400;
5631 0 : if (fWriteReservation)
5632 0 : nBits16 |= 0x0800;
5633 :
5634 0 : if( fExtChar ) nBits16 |= 0x1000;
5635 0 : if( fFarEast ) nBits16 |= 0x4000; // #i90932#
5636 0 : if( fObfuscated ) nBits16 |= 0x8000;
5637 0 : Set_UInt16( pData, nBits16 );
5638 :
5639 0 : Set_UInt16( pData, nFibBack );
5640 0 : Set_UInt16( pData, nHash );
5641 0 : Set_UInt16( pData, nKey );
5642 0 : Set_UInt8( pData, envr );
5643 :
5644 0 : sal_uInt8 nBits8 = 0;
5645 0 : if( bVer8 )
5646 : {
5647 0 : if( fMac ) nBits8 |= 0x0001;
5648 0 : if( fEmptySpecial ) nBits8 |= 0x0002;
5649 0 : if( fLoadOverridePage ) nBits8 |= 0x0004;
5650 0 : if( fFuturesavedUndo ) nBits8 |= 0x0008;
5651 0 : if( fWord97Saved ) nBits8 |= 0x0010;
5652 0 : if( fWord2000Saved ) nBits8 |= 0x0020;
5653 : }
5654 : // unter Ver67 these are only reserved
5655 0 : Set_UInt8( pData, nBits8 );
5656 :
5657 0 : Set_UInt16( pData, chse );
5658 0 : Set_UInt16( pData, chseTables );
5659 0 : Set_UInt32( pData, fcMin );
5660 0 : Set_UInt32( pData, fcMac );
5661 :
5662 : // Einschub fuer WW8 *****************************************************
5663 :
5664 : // Marke: "rgsw" Beginning of the array of shorts
5665 0 : if( bVer8 )
5666 : {
5667 0 : Set_UInt16( pData, csw );
5668 0 : Set_UInt16( pData, wMagicCreated );
5669 0 : Set_UInt16( pData, wMagicRevised );
5670 0 : Set_UInt16( pData, wMagicCreatedPrivate );
5671 0 : Set_UInt16( pData, wMagicRevisedPrivate );
5672 0 : pData += 9 * sizeof( sal_Int16 );
5673 0 : Set_UInt16( pData, lidFE );
5674 0 : Set_UInt16( pData, clw );
5675 : }
5676 :
5677 : // Ende des Einschubs fuer WW8 *******************************************
5678 :
5679 : // Marke: "rglw" Beginning of the array of longs
5680 0 : Set_UInt32( pData, cbMac );
5681 :
5682 0 : rStrm.Write( pDataPtr, nUnencryptedHdr );
5683 0 : delete[] pDataPtr;
5684 0 : return 0 == rStrm.GetError();
5685 : }
5686 :
5687 0 : bool WW8Fib::Write(SvStream& rStrm)
5688 : {
5689 0 : bool bVer8 = 8 == nVersion;
5690 :
5691 0 : WriteHeader( rStrm );
5692 :
5693 0 : size_t nUnencryptedHdr = bVer8 ? 0x44 : 0x24;
5694 :
5695 0 : sal_uInt8 *pDataPtr = new sal_uInt8[ fcMin - nUnencryptedHdr ];
5696 0 : sal_uInt8 *pData = pDataPtr;
5697 0 : memset( pData, 0, fcMin - nUnencryptedHdr );
5698 :
5699 0 : sal_uLong nPos = rStrm.Tell();
5700 0 : cbMac = rStrm.Seek( STREAM_SEEK_TO_END );
5701 0 : rStrm.Seek( nPos );
5702 :
5703 : // 2 Longs uebergehen, da unwichtiger Quatsch
5704 0 : pData += 2 * sizeof( sal_Int32);
5705 :
5706 : // weitere 2 Longs nur bei Ver67 ueberspringen
5707 0 : if( !bVer8 )
5708 0 : pData += 2 * sizeof( sal_Int32);
5709 :
5710 0 : Set_UInt32( pData, ccpText );
5711 0 : Set_UInt32( pData, ccpFtn );
5712 0 : Set_UInt32( pData, ccpHdr );
5713 0 : Set_UInt32( pData, ccpMcr );
5714 0 : Set_UInt32( pData, ccpAtn );
5715 0 : Set_UInt32( pData, ccpEdn );
5716 0 : Set_UInt32( pData, ccpTxbx );
5717 0 : Set_UInt32( pData, ccpHdrTxbx );
5718 :
5719 : // weiteres Long nur bei Ver67 ueberspringen
5720 0 : if( !bVer8 )
5721 0 : pData += 1 * sizeof( sal_Int32);
5722 :
5723 : // Einschub fuer WW8 *****************************************************
5724 0 : if( bVer8 )
5725 : {
5726 0 : Set_UInt32( pData, pnFbpChpFirst );
5727 0 : Set_UInt32( pData, pnChpFirst );
5728 0 : Set_UInt32( pData, cpnBteChp );
5729 0 : Set_UInt32( pData, pnFbpPapFirst );
5730 0 : Set_UInt32( pData, pnPapFirst );
5731 0 : Set_UInt32( pData, cpnBtePap );
5732 0 : Set_UInt32( pData, pnFbpLvcFirst );
5733 0 : Set_UInt32( pData, pnLvcFirst );
5734 0 : Set_UInt32( pData, cpnBteLvc );
5735 0 : Set_UInt32( pData, fcIslandFirst );
5736 0 : Set_UInt32( pData, fcIslandLim );
5737 0 : Set_UInt16( pData, cfclcb );
5738 : }
5739 : // Ende des Einschubs fuer WW8 *******************************************
5740 :
5741 : // Marke: "rgfclcb" Beginning of array of FC/LCB pairs.
5742 0 : Set_UInt32( pData, fcStshfOrig );
5743 0 : Set_UInt32( pData, lcbStshfOrig );
5744 0 : Set_UInt32( pData, fcStshf );
5745 0 : Set_UInt32( pData, lcbStshf );
5746 0 : Set_UInt32( pData, fcPlcffndRef );
5747 0 : Set_UInt32( pData, lcbPlcffndRef );
5748 0 : Set_UInt32( pData, fcPlcffndTxt );
5749 0 : Set_UInt32( pData, lcbPlcffndTxt );
5750 0 : Set_UInt32( pData, fcPlcfandRef );
5751 0 : Set_UInt32( pData, lcbPlcfandRef );
5752 0 : Set_UInt32( pData, fcPlcfandTxt );
5753 0 : Set_UInt32( pData, lcbPlcfandTxt );
5754 0 : Set_UInt32( pData, fcPlcfsed );
5755 0 : Set_UInt32( pData, lcbPlcfsed );
5756 0 : Set_UInt32( pData, fcPlcfpad );
5757 0 : Set_UInt32( pData, lcbPlcfpad );
5758 0 : Set_UInt32( pData, fcPlcfphe );
5759 0 : Set_UInt32( pData, lcbPlcfphe );
5760 0 : Set_UInt32( pData, fcSttbfglsy );
5761 0 : Set_UInt32( pData, lcbSttbfglsy );
5762 0 : Set_UInt32( pData, fcPlcfglsy );
5763 0 : Set_UInt32( pData, lcbPlcfglsy );
5764 0 : Set_UInt32( pData, fcPlcfhdd );
5765 0 : Set_UInt32( pData, lcbPlcfhdd );
5766 0 : Set_UInt32( pData, fcPlcfbteChpx );
5767 0 : Set_UInt32( pData, lcbPlcfbteChpx );
5768 0 : Set_UInt32( pData, fcPlcfbtePapx );
5769 0 : Set_UInt32( pData, lcbPlcfbtePapx );
5770 0 : Set_UInt32( pData, fcPlcfsea );
5771 0 : Set_UInt32( pData, lcbPlcfsea );
5772 0 : Set_UInt32( pData, fcSttbfffn );
5773 0 : Set_UInt32( pData, lcbSttbfffn );
5774 0 : Set_UInt32( pData, fcPlcffldMom );
5775 0 : Set_UInt32( pData, lcbPlcffldMom );
5776 0 : Set_UInt32( pData, fcPlcffldHdr );
5777 0 : Set_UInt32( pData, lcbPlcffldHdr );
5778 0 : Set_UInt32( pData, fcPlcffldFtn );
5779 0 : Set_UInt32( pData, lcbPlcffldFtn );
5780 0 : Set_UInt32( pData, fcPlcffldAtn );
5781 0 : Set_UInt32( pData, lcbPlcffldAtn );
5782 0 : Set_UInt32( pData, fcPlcffldMcr );
5783 0 : Set_UInt32( pData, lcbPlcffldMcr );
5784 0 : Set_UInt32( pData, fcSttbfbkmk );
5785 0 : Set_UInt32( pData, lcbSttbfbkmk );
5786 0 : Set_UInt32( pData, fcPlcfbkf );
5787 0 : Set_UInt32( pData, lcbPlcfbkf );
5788 0 : Set_UInt32( pData, fcPlcfbkl );
5789 0 : Set_UInt32( pData, lcbPlcfbkl );
5790 0 : Set_UInt32( pData, fcCmds );
5791 0 : Set_UInt32( pData, lcbCmds );
5792 0 : Set_UInt32( pData, fcPlcfmcr );
5793 0 : Set_UInt32( pData, lcbPlcfmcr );
5794 0 : Set_UInt32( pData, fcSttbfmcr );
5795 0 : Set_UInt32( pData, lcbSttbfmcr );
5796 0 : Set_UInt32( pData, fcPrDrvr );
5797 0 : Set_UInt32( pData, lcbPrDrvr );
5798 0 : Set_UInt32( pData, fcPrEnvPort );
5799 0 : Set_UInt32( pData, lcbPrEnvPort );
5800 0 : Set_UInt32( pData, fcPrEnvLand );
5801 0 : Set_UInt32( pData, lcbPrEnvLand );
5802 0 : Set_UInt32( pData, fcWss );
5803 0 : Set_UInt32( pData, lcbWss );
5804 0 : Set_UInt32( pData, fcDop );
5805 0 : Set_UInt32( pData, lcbDop );
5806 0 : Set_UInt32( pData, fcSttbfAssoc );
5807 0 : Set_UInt32( pData, lcbSttbfAssoc );
5808 0 : Set_UInt32( pData, fcClx );
5809 0 : Set_UInt32( pData, lcbClx );
5810 0 : Set_UInt32( pData, fcPlcfpgdFtn );
5811 0 : Set_UInt32( pData, lcbPlcfpgdFtn );
5812 0 : Set_UInt32( pData, fcAutosaveSource );
5813 0 : Set_UInt32( pData, lcbAutosaveSource );
5814 0 : Set_UInt32( pData, fcGrpStAtnOwners );
5815 0 : Set_UInt32( pData, lcbGrpStAtnOwners );
5816 0 : Set_UInt32( pData, fcSttbfAtnbkmk );
5817 0 : Set_UInt32( pData, lcbSttbfAtnbkmk );
5818 :
5819 : // weiteres short nur bei Ver67 ueberspringen
5820 0 : 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 0 : Set_UInt32( pData, fcPlcfdoaMom ); // nur bei Ver67, in Ver8 unused
5830 0 : Set_UInt32( pData, lcbPlcfdoaMom ); // nur bei Ver67, in Ver8 unused
5831 0 : Set_UInt32( pData, fcPlcfdoaHdr ); // nur bei Ver67, in Ver8 unused
5832 0 : Set_UInt32( pData, lcbPlcfdoaHdr ); // nur bei Ver67, in Ver8 unused
5833 :
5834 0 : Set_UInt32( pData, fcPlcfspaMom ); // in Ver67 leere Reserve
5835 0 : Set_UInt32( pData, lcbPlcfspaMom ); // in Ver67 leere Reserve
5836 0 : Set_UInt32( pData, fcPlcfspaHdr ); // in Ver67 leere Reserve
5837 0 : Set_UInt32( pData, lcbPlcfspaHdr ); // in Ver67 leere Reserve
5838 :
5839 0 : Set_UInt32( pData, fcPlcfAtnbkf );
5840 0 : Set_UInt32( pData, lcbPlcfAtnbkf );
5841 0 : Set_UInt32( pData, fcPlcfAtnbkl );
5842 0 : Set_UInt32( pData, lcbPlcfAtnbkl );
5843 0 : Set_UInt32( pData, fcPms );
5844 0 : Set_UInt32( pData, lcbPMS );
5845 0 : Set_UInt32( pData, fcFormFldSttbf );
5846 0 : Set_UInt32( pData, lcbFormFldSttbf );
5847 0 : Set_UInt32( pData, fcPlcfendRef );
5848 0 : Set_UInt32( pData, lcbPlcfendRef );
5849 0 : Set_UInt32( pData, fcPlcfendTxt );
5850 0 : Set_UInt32( pData, lcbPlcfendTxt );
5851 0 : Set_UInt32( pData, fcPlcffldEdn );
5852 0 : Set_UInt32( pData, lcbPlcffldEdn );
5853 0 : Set_UInt32( pData, fcPlcfpgdEdn );
5854 0 : Set_UInt32( pData, lcbPlcfpgdEdn );
5855 0 : Set_UInt32( pData, fcDggInfo ); // in Ver67 leere Reserve
5856 0 : Set_UInt32( pData, lcbDggInfo ); // in Ver67 leere Reserve
5857 0 : Set_UInt32( pData, fcSttbfRMark );
5858 0 : Set_UInt32( pData, lcbSttbfRMark );
5859 0 : Set_UInt32( pData, fcSttbfCaption );
5860 0 : Set_UInt32( pData, lcbSttbfCaption );
5861 0 : Set_UInt32( pData, fcSttbAutoCaption );
5862 0 : Set_UInt32( pData, lcbSttbAutoCaption );
5863 0 : Set_UInt32( pData, fcPlcfwkb );
5864 0 : Set_UInt32( pData, lcbPlcfwkb );
5865 0 : Set_UInt32( pData, fcPlcfspl ); // in Ver67 leere Reserve
5866 0 : Set_UInt32( pData, lcbPlcfspl ); // in Ver67 leere Reserve
5867 0 : Set_UInt32( pData, fcPlcftxbxTxt );
5868 0 : Set_UInt32( pData, lcbPlcftxbxTxt );
5869 0 : Set_UInt32( pData, fcPlcffldTxbx );
5870 0 : Set_UInt32( pData, lcbPlcffldTxbx );
5871 0 : Set_UInt32( pData, fcPlcfHdrtxbxTxt );
5872 0 : Set_UInt32( pData, lcbPlcfHdrtxbxTxt );
5873 0 : Set_UInt32( pData, fcPlcffldHdrTxbx );
5874 0 : Set_UInt32( pData, lcbPlcffldHdrTxbx );
5875 :
5876 0 : if( bVer8 )
5877 : {
5878 0 : pData += 0x2da - 0x27a; // Pos + Offset (fcPlcfLst - fcStwUser)
5879 0 : Set_UInt32( pData, fcSttbFnm);
5880 0 : Set_UInt32( pData, lcbSttbFnm);
5881 0 : Set_UInt32( pData, fcPlcfLst );
5882 0 : Set_UInt32( pData, lcbPlcfLst );
5883 0 : Set_UInt32( pData, fcPlfLfo );
5884 0 : Set_UInt32( pData, lcbPlfLfo );
5885 0 : Set_UInt32( pData, fcPlcftxbxBkd );
5886 0 : Set_UInt32( pData, lcbPlcftxbxBkd );
5887 0 : Set_UInt32( pData, fcPlcfHdrtxbxBkd );
5888 0 : Set_UInt32( pData, lcbPlcfHdrtxbxBkd );
5889 :
5890 0 : pData += 0x372 - 0x302; // Pos + Offset (fcSttbListNames - fcDocUndo)
5891 0 : Set_UInt32( pData, fcSttbListNames );
5892 0 : Set_UInt32( pData, lcbSttbListNames );
5893 :
5894 0 : pData += 0x382 - 0x37A;
5895 0 : Set_UInt32( pData, fcPlcfTch );
5896 0 : Set_UInt32( pData, lcbPlcfTch );
5897 :
5898 0 : pData += 0x3FA - 0x38A;
5899 0 : Set_UInt16( pData, (sal_uInt16)0x0002);
5900 0 : Set_UInt16( pData, (sal_uInt16)0x00D9);
5901 :
5902 0 : pData += 0x41A - 0x3FE;
5903 0 : Set_UInt32( pData, fcAtrdExtra );
5904 0 : Set_UInt32( pData, lcbAtrdExtra );
5905 :
5906 0 : pData += 0x4DA - 0x422;
5907 0 : Set_UInt32( pData, fcHplxsdr );
5908 0 : Set_UInt32( pData, 0);
5909 : }
5910 :
5911 0 : rStrm.Write( pDataPtr, fcMin - nUnencryptedHdr );
5912 0 : delete[] pDataPtr;
5913 0 : return 0 == rStrm.GetError();
5914 : }
5915 :
5916 0 : 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 0 : : rtl_getTextEncodingFromWindowsCharset( static_cast<sal_uInt8>(chs) );
5923 0 : return eCharSet;
5924 : }
5925 :
5926 0 : 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 0 : , ftcAsci(0), ftcFE(0), ftcOther(0), ftcBi(0)
5930 : {
5931 0 : if (!checkSeek(rSt, rFib.fcStshf))
5932 0 : return;
5933 :
5934 0 : sal_uInt16 cbStshi = 0; // 2 bytes size of the following STSHI structure
5935 0 : sal_uInt32 nRemaining = rFib.lcbStshf;
5936 0 : const sal_uInt32 nMinValidStshi = 4;
5937 :
5938 0 : if (rFib.GetFIBVersion() <= ww::eWW2)
5939 : {
5940 0 : cbStshi = 0;
5941 0 : cstd = 256;
5942 : }
5943 : else
5944 : {
5945 0 : if (rFib.nFib < 67) // old Version ? (need to find this again to fix)
5946 0 : cbStshi = nMinValidStshi;
5947 : else // new version
5948 : {
5949 0 : if (nRemaining < sizeof(cbStshi))
5950 0 : return;
5951 : // lies die Laenge der in der Datei gespeicherten Struktur
5952 0 : rSt.ReadUInt16( cbStshi );
5953 0 : nRemaining-=2;
5954 : }
5955 : }
5956 :
5957 0 : cbStshi = std::min(static_cast<sal_uInt32>(cbStshi), nRemaining);
5958 0 : if (cbStshi < nMinValidStshi)
5959 0 : return;
5960 :
5961 0 : sal_uInt16 nRead = cbStshi;
5962 : do
5963 : {
5964 : sal_uInt16 a16Bit;
5965 :
5966 0 : rSt.ReadUInt16( cstd );
5967 :
5968 0 : rSt.ReadUInt16( cbSTDBaseInFile );
5969 :
5970 0 : if( 6 > nRead ) break;
5971 0 : rSt.ReadUInt16( a16Bit );
5972 0 : fStdStylenamesWritten = a16Bit & 0x0001;
5973 :
5974 0 : if( 8 > nRead ) break;
5975 0 : rSt.ReadUInt16( stiMaxWhenSaved );
5976 :
5977 0 : if( 10 > nRead ) break;
5978 0 : rSt.ReadUInt16( istdMaxFixedWhenSaved );
5979 :
5980 0 : if( 12 > nRead ) break;
5981 0 : rSt.ReadUInt16( nVerBuiltInNamesWhenSaved );
5982 :
5983 0 : if( 14 > nRead ) break;
5984 0 : rSt.ReadUInt16( ftcAsci );
5985 :
5986 0 : if( 16 > nRead ) break;
5987 0 : rSt.ReadUInt16( ftcFE );
5988 :
5989 0 : if ( 18 > nRead ) break;
5990 0 : rSt.ReadUInt16( ftcOther );
5991 :
5992 0 : ftcBi = ftcOther;
5993 :
5994 0 : if ( 20 > nRead ) break;
5995 0 : rSt.ReadUInt16( ftcBi );
5996 :
5997 : // ggfs. den Rest ueberlesen
5998 0 : if( 20 < nRead )
5999 0 : 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 0 : 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 0 : const sal_uInt32 nMinRecordSize = sizeof(sal_uInt16);
6009 0 : sal_uInt16 nMaxPossibleRecords = nRemaining/nMinRecordSize;
6010 :
6011 : OSL_ENSURE(cstd <= nMaxPossibleRecords,
6012 : "allegedly more styles that available data\n");
6013 0 : 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 0 : WW8_STD* WW8Style::Read1STDFixed( short& rSkip, short* pcbStd )
6021 : {
6022 0 : WW8_STD* pStd = 0;
6023 :
6024 0 : sal_uInt16 cbStd(0);
6025 0 : rSt.ReadUInt16( cbStd ); // lies Laenge
6026 :
6027 0 : sal_uInt16 nRead = cbSTDBaseInFile;
6028 0 : if( cbStd >= cbSTDBaseInFile )
6029 : {
6030 : // Fixed part vollst. vorhanden
6031 :
6032 : // read fixed part of STD
6033 0 : pStd = new WW8_STD;
6034 0 : memset( pStd, 0, sizeof( *pStd ) );
6035 :
6036 : do
6037 : {
6038 : sal_uInt16 a16Bit;
6039 :
6040 0 : if( 2 > nRead ) break;
6041 0 : a16Bit = 0;
6042 0 : rSt.ReadUInt16( a16Bit );
6043 0 : pStd->sti = a16Bit & 0x0fff ;
6044 0 : pStd->fScratch = sal_uInt16(0 != ( a16Bit & 0x1000 ));
6045 0 : pStd->fInvalHeight = sal_uInt16(0 != ( a16Bit & 0x2000 ));
6046 0 : pStd->fHasUpe = sal_uInt16(0 != ( a16Bit & 0x4000 ));
6047 0 : pStd->fMassCopy = sal_uInt16(0 != ( a16Bit & 0x8000 ));
6048 :
6049 0 : if( 4 > nRead ) break;
6050 0 : a16Bit = 0;
6051 0 : rSt.ReadUInt16( a16Bit );
6052 0 : pStd->sgc = a16Bit & 0x000f ;
6053 0 : pStd->istdBase = ( a16Bit & 0xfff0 ) >> 4;
6054 :
6055 0 : if( 6 > nRead ) break;
6056 0 : a16Bit = 0;
6057 0 : rSt.ReadUInt16( a16Bit );
6058 0 : pStd->cupx = a16Bit & 0x000f ;
6059 0 : pStd->istdNext = ( a16Bit & 0xfff0 ) >> 4;
6060 :
6061 0 : if( 8 > nRead ) break;
6062 0 : a16Bit = 0;
6063 0 : rSt.ReadUInt16( pStd->bchUpe );
6064 :
6065 : // ab Ver8 sollten diese beiden Felder dazukommen:
6066 0 : if(10 > nRead ) break;
6067 0 : a16Bit = 0;
6068 0 : rSt.ReadUInt16( a16Bit );
6069 0 : pStd->fAutoRedef = a16Bit & 0x0001 ;
6070 0 : pStd->fHidden = ( a16Bit & 0x0002 ) >> 1;
6071 :
6072 : // man kann nie wissen: vorsichtshalber ueberlesen
6073 : // wir eventuelle Fuellsel, die noch zum BASE-Part gehoeren...
6074 0 : if( 10 < nRead )
6075 0 : 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 0 : if( (0 != rSt.GetError()) || !nRead )
6081 0 : DELETEZ( pStd ); // per NULL den Error melden
6082 :
6083 0 : rSkip = cbStd - cbSTDBaseInFile;
6084 : }
6085 : else
6086 : { // Fixed part zu kurz
6087 0 : if( cbStd )
6088 0 : rSt.SeekRel( cbStd ); // ueberlies Reste
6089 0 : rSkip = 0;
6090 : }
6091 0 : if( pcbStd )
6092 0 : *pcbStd = cbStd;
6093 0 : return pStd;
6094 : }
6095 :
6096 0 : 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 0 : WW8_STD* pStd = Read1STDFixed( rSkip, pcbStd ); // lese STD
6102 :
6103 : // String gewuenscht ?
6104 0 : if( pString )
6105 : { // echter Style ?
6106 0 : if ( pStd )
6107 : {
6108 0 : 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 0 : if (TestBeltAndBraces(rSt))
6121 : {
6122 0 : *pString = read_uInt16_BeltAndBracesString(rSt);
6123 0 : 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 0 : 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 0 : 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 0 : 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 0 : OUStringBuffer aBuf(sString);
6193 0 : const sal_Int32 nLen = aBuf.getLength();
6194 0 : bool bFound = false;
6195 0 : for ( sal_Int32 n = 0; n < nLen; ++n )
6196 : {
6197 0 : if ( aBuf[n] < 0x20 )
6198 : {
6199 0 : aBuf[n] = 1;
6200 0 : bFound = true;
6201 : }
6202 : }
6203 0 : sString = aBuf.makeStringAndClear();
6204 :
6205 : // if anything was found, remove \u0001 + leading/trailing ';'
6206 0 : if( bFound )
6207 : {
6208 0 : sString = comphelper::string::strip(sString.replaceAll("\001", ""), ';');
6209 0 : }
6210 0 : }
6211 :
6212 : namespace
6213 : {
6214 0 : sal_uInt16 calcMaxFonts(sal_uInt8 *p, sal_Int32 nFFn)
6215 : {
6216 : // Figure out the max number of fonts defined here
6217 0 : sal_uInt16 nMax = 0;
6218 0 : sal_Int32 nRemaining = nFFn;
6219 0 : while (nRemaining)
6220 : {
6221 : //p[0] is cbFfnM1, the alleged total length of FFN - 1.
6222 : //i.e. length after cbFfnM1
6223 0 : sal_uInt16 cbFfnM1 = *p++;
6224 0 : --nRemaining;
6225 :
6226 0 : if (cbFfnM1 > nRemaining)
6227 0 : break;
6228 :
6229 0 : nMax++;
6230 0 : nRemaining -= cbFfnM1;
6231 0 : p += cbFfnM1;
6232 : }
6233 0 : return nMax;
6234 : }
6235 : }
6236 :
6237 0 : WW8Fonts::WW8Fonts( SvStream& rSt, WW8Fib& rFib )
6238 0 : : pFontA(0), nMax(0)
6239 : {
6240 : // Attention: MacWord-Documents have their Fontnames
6241 : // always in ANSI, even if eStructCharSet == CHARSET_MAC !!
6242 0 : if( rFib.lcbSttbfffn <= 2 )
6243 : {
6244 : OSL_ENSURE( !this, "Fonttabelle kaputt! (rFib.lcbSttbfffn < 2)" );
6245 0 : return;
6246 : }
6247 :
6248 0 : if (!checkSeek(rSt, rFib.fcSttbfffn))
6249 0 : return;
6250 :
6251 0 : sal_Int32 nFFn = rFib.lcbSttbfffn - 2;
6252 :
6253 : // allocate Font Array
6254 0 : sal_uInt8* pA = new sal_uInt8[nFFn];
6255 0 : memset(pA, 0, nFFn);
6256 :
6257 0 : ww::WordVersion eVersion = rFib.GetFIBVersion();
6258 :
6259 0 : if( eVersion >= ww::eWW8 )
6260 : {
6261 : // bVer8: read the count of strings in nMax
6262 0 : 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 0 : rSt.SeekRel( 2 );
6269 :
6270 : // read all font information
6271 0 : nFFn = rSt.Read(pA, nFFn);
6272 0 : sal_uInt16 nCalcMax = calcMaxFonts(pA, nFFn);
6273 :
6274 0 : 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 0 : nMax = std::min(nMax, nCalcMax);
6281 : }
6282 :
6283 0 : if( nMax )
6284 : {
6285 : // allocate Index Array
6286 0 : pFontA = new WW8_FFN[ nMax ];
6287 0 : WW8_FFN* p = pFontA;
6288 :
6289 0 : 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 0 : 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 0 : const sal_uInt8 cbMinFFNPayload = 41;
6365 0 : sal_uInt16 nValidFonts = 0;
6366 0 : sal_Int32 nRemainingFFn = nFFn;
6367 0 : sal_uInt8* pRaw = pA;
6368 0 : 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 0 : sal_uInt8 cbFfnM1 = *pRaw++;
6373 0 : --nRemainingFFn;
6374 :
6375 0 : if (cbFfnM1 > nRemainingFFn)
6376 0 : break;
6377 :
6378 0 : if (cbFfnM1 < cbMinFFNPayload)
6379 0 : break;
6380 :
6381 0 : p->cbFfnM1 = cbFfnM1;
6382 :
6383 0 : sal_uInt8 *pVer8 = pRaw;
6384 :
6385 0 : sal_uInt8 c2 = *pVer8++;
6386 0 : --cbFfnM1;
6387 :
6388 0 : p->prg = c2 & 0x02;
6389 0 : p->fTrueType = (c2 & 0x04) >> 2;
6390 : // ein Reserve-Bit ueberspringen
6391 0 : p->ff = (c2 & 0x70) >> 4;
6392 :
6393 0 : p->wWeight = SVBT16ToShort(*(SVBT16*)pVer8);
6394 0 : pVer8+=2;
6395 0 : cbFfnM1-=2;
6396 :
6397 0 : p->chs = *pVer8++;
6398 0 : --cbFfnM1;
6399 :
6400 0 : p->ibszAlt = *pVer8++;
6401 0 : --cbFfnM1;
6402 :
6403 0 : pVer8 += 10; //PANOSE
6404 0 : cbFfnM1-=10;
6405 0 : pVer8 += 24; //FONTSIGNATURE
6406 0 : cbFfnM1-=24;
6407 :
6408 : OSL_ASSERT(cbFfnM1 >= 2);
6409 :
6410 0 : sal_uInt8 nMaxNullTerminatedPossible = cbFfnM1/2 - 1;
6411 0 : sal_Unicode *pPrimary = reinterpret_cast<sal_Unicode*>(pVer8);
6412 0 : pPrimary[nMaxNullTerminatedPossible] = 0;
6413 : #ifdef OSL_BIGENDIAN
6414 : swapEndian(pPrimary);
6415 : #endif
6416 0 : p->sFontname = pPrimary;
6417 0 : if (p->ibszAlt && p->ibszAlt < nMaxNullTerminatedPossible)
6418 : {
6419 0 : sal_Unicode *pSecondary = pPrimary + p->ibszAlt;
6420 : #ifdef OSL_BIGENDIAN
6421 : swapEndian(pSecondary);
6422 : #endif
6423 0 : p->sFontname += ";" + OUString(pSecondary);
6424 : }
6425 :
6426 : // #i43762# check font name for illegal characters
6427 0 : lcl_checkFontname( p->sFontname );
6428 :
6429 : // Zeiger auf Ursprungsarray einen Font nach hinten setzen
6430 0 : pRaw += p->cbFfnM1;
6431 0 : nRemainingFFn -= p->cbFfnM1;
6432 0 : ++nValidFonts;
6433 : }
6434 : OSL_ENSURE(nMax == nValidFonts, "Font count differs with availability");
6435 0 : nMax = std::min(nMax, nValidFonts);
6436 : }
6437 : }
6438 0 : delete[] pA;
6439 : }
6440 :
6441 0 : const WW8_FFN* WW8Fonts::GetFont( sal_uInt16 nNum ) const
6442 : {
6443 0 : if( !pFontA || nNum >= nMax )
6444 0 : return 0;
6445 :
6446 0 : 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 0 : WW8PLCF_HdFt::WW8PLCF_HdFt( SvStream* pSt, WW8Fib& rFib, WW8Dop& rDop )
6463 0 : : aPLCF(*pSt, rFib.fcPlcfhdd , rFib.lcbPlcfhdd , 0)
6464 : {
6465 0 : 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 0 : for( sal_uInt8 nI = 0x1; nI <= 0x20; nI <<= 1 )
6480 0 : if( nI & rDop.grpfIhdt ) // Bit gesetzt ?
6481 0 : nIdxOffset++;
6482 :
6483 0 : nTextOfs = rFib.ccpText + rFib.ccpFtn; // Groesse des Haupttextes
6484 : // und der Fussnoten
6485 0 : }
6486 :
6487 0 : bool WW8PLCF_HdFt::GetTextPos(sal_uInt8 grpfIhdt, sal_uInt8 nWhich, WW8_CP& rStart,
6488 : long& rLen)
6489 : {
6490 0 : sal_uInt8 nI = 0x01;
6491 0 : short nIdx = nIdxOffset;
6492 : while (true)
6493 : {
6494 0 : if( nI & nWhich )
6495 0 : break; // found
6496 0 : if( grpfIhdt & nI )
6497 0 : nIdx++; // uninteresting Header / Footer
6498 0 : nI <<= 1; // text next bit
6499 0 : if( nI > 0x20 )
6500 0 : return false; // not found
6501 : }
6502 : // nIdx ist HdFt-Index
6503 : WW8_CP nEnd;
6504 : void* pData;
6505 :
6506 0 : aPLCF.SetIdx( nIdx ); // Lookup suitable CP
6507 0 : aPLCF.Get( rStart, nEnd, pData );
6508 0 : rLen = nEnd - rStart;
6509 0 : aPLCF.advance();
6510 :
6511 0 : return true;
6512 : }
6513 :
6514 0 : bool WW8PLCF_HdFt::GetTextPosExact(short nIdx, WW8_CP& rStart, long& rLen)
6515 : {
6516 : WW8_CP nEnd;
6517 : void* pData;
6518 :
6519 0 : aPLCF.SetIdx( nIdx ); // Lookup suitable CP
6520 0 : aPLCF.Get( rStart, nEnd, pData );
6521 0 : rLen = nEnd - rStart;
6522 0 : return true;
6523 : }
6524 :
6525 0 : void WW8PLCF_HdFt::UpdateIndex( sal_uInt8 grpfIhdt )
6526 : {
6527 : // Caution: Description is not correct
6528 0 : for( sal_uInt8 nI = 0x01; nI <= 0x20; nI <<= 1 )
6529 0 : if( nI & grpfIhdt )
6530 0 : nIdxOffset++;
6531 0 : }
6532 :
6533 : // WW8Dop
6534 :
6535 0 : WW8Dop::WW8Dop(SvStream& rSt, sal_Int16 nFib, sal_Int32 nPos, sal_uInt32 nSize) : bUseThaiLineBreakingRules(false)
6536 : {
6537 0 : memset( &nDataStart, 0, (&nDataEnd - &nDataStart) );
6538 0 : fDontUseHTMLAutoSpacing = true; //default
6539 0 : fAcetateShowAtn = true; //default
6540 0 : const sal_uInt32 nMaxDopSize = 0x268;
6541 0 : sal_uInt8* pDataPtr = new sal_uInt8[ nMaxDopSize ];
6542 0 : sal_uInt8* pData = pDataPtr;
6543 :
6544 0 : sal_uInt32 nRead = nMaxDopSize < nSize ? nMaxDopSize : nSize;
6545 0 : rSt.Seek( nPos );
6546 0 : if (2 > nSize || nRead != rSt.Read(pData, nRead))
6547 0 : nDopError = ERR_SWG_READ_ERROR; // Error melden
6548 : else
6549 : {
6550 0 : if (nMaxDopSize > nRead)
6551 0 : 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 0 : a16Bit = Get_UShort( pData ); // 0 0x00
6559 0 : fFacingPages = 0 != ( a16Bit & 0x0001 ) ;
6560 0 : fWidowControl = 0 != ( a16Bit & 0x0002 ) ;
6561 0 : fPMHMainDoc = 0 != ( a16Bit & 0x0004 ) ;
6562 0 : grfSuppression = ( a16Bit & 0x0018 ) >> 3;
6563 0 : fpc = ( a16Bit & 0x0060 ) >> 5;
6564 0 : grpfIhdt = ( a16Bit & 0xff00 ) >> 8;
6565 :
6566 0 : a16Bit = Get_UShort( pData ); // 2 0x02
6567 0 : rncFtn = a16Bit & 0x0003 ;
6568 0 : nFtn = ( a16Bit & ~0x0003 ) >> 2 ;
6569 :
6570 0 : a8Bit = Get_Byte( pData ); // 4 0x04
6571 0 : fOutlineDirtySave = 0 != ( a8Bit & 0x01 );
6572 :
6573 0 : a8Bit = Get_Byte( pData ); // 5 0x05
6574 0 : fOnlyMacPics = 0 != ( a8Bit & 0x01 );
6575 0 : fOnlyWinPics = 0 != ( a8Bit & 0x02 );
6576 0 : fLabelDoc = 0 != ( a8Bit & 0x04 );
6577 0 : fHyphCapitals = 0 != ( a8Bit & 0x08 );
6578 0 : fAutoHyphen = 0 != ( a8Bit & 0x10 );
6579 0 : fFormNoFields = 0 != ( a8Bit & 0x20 );
6580 0 : fLinkStyles = 0 != ( a8Bit & 0x40 );
6581 0 : fRevMarking = 0 != ( a8Bit & 0x80 );
6582 :
6583 0 : a8Bit = Get_Byte( pData ); // 6 0x06
6584 0 : fBackup = 0 != ( a8Bit & 0x01 );
6585 0 : fExactCWords = 0 != ( a8Bit & 0x02 );
6586 0 : fPagHidden = 0 != ( a8Bit & 0x04 );
6587 0 : fPagResults = 0 != ( a8Bit & 0x08 );
6588 0 : fLockAtn = 0 != ( a8Bit & 0x10 );
6589 0 : fMirrorMargins = 0 != ( a8Bit & 0x20 );
6590 0 : fReadOnlyRecommended = 0 != ( a8Bit & 0x40 );
6591 0 : fDfltTrueType = 0 != ( a8Bit & 0x80 );
6592 :
6593 0 : a8Bit = Get_Byte( pData ); // 7 0x07
6594 0 : fPagSuppressTopSpacing = 0 != ( a8Bit & 0x01 );
6595 0 : fProtEnabled = 0 != ( a8Bit & 0x02 );
6596 0 : fDispFormFldSel = 0 != ( a8Bit & 0x04 );
6597 0 : fRMView = 0 != ( a8Bit & 0x08 );
6598 0 : fRMPrint = 0 != ( a8Bit & 0x10 );
6599 0 : fWriteReservation = 0 != ( a8Bit & 0x20 );
6600 0 : fLockRev = 0 != ( a8Bit & 0x40 );
6601 0 : fEmbedFonts = 0 != ( a8Bit & 0x80 );
6602 :
6603 0 : a8Bit = Get_Byte( pData ); // 8 0x08
6604 0 : copts_fNoTabForInd = 0 != ( a8Bit & 0x01 );
6605 0 : copts_fNoSpaceRaiseLower = 0 != ( a8Bit & 0x02 );
6606 0 : copts_fSupressSpbfAfterPgBrk = 0 != ( a8Bit & 0x04 );
6607 0 : copts_fWrapTrailSpaces = 0 != ( a8Bit & 0x08 );
6608 0 : copts_fMapPrintTextColor = 0 != ( a8Bit & 0x10 );
6609 0 : copts_fNoColumnBalance = 0 != ( a8Bit & 0x20 );
6610 0 : copts_fConvMailMergeEsc = 0 != ( a8Bit & 0x40 );
6611 0 : copts_fSupressTopSpacing = 0 != ( a8Bit & 0x80 );
6612 :
6613 0 : a8Bit = Get_Byte( pData ); // 9 0x09
6614 0 : copts_fOrigWordTableRules = 0 != ( a8Bit & 0x01 );
6615 0 : copts_fTransparentMetafiles = 0 != ( a8Bit & 0x02 );
6616 0 : copts_fShowBreaksInFrames = 0 != ( a8Bit & 0x04 );
6617 0 : copts_fSwapBordersFacingPgs = 0 != ( a8Bit & 0x08 );
6618 0 : copts_fExpShRtn = 0 != ( a8Bit & 0x20 ); // #i56856#
6619 :
6620 0 : dxaTab = Get_Short( pData ); // 10 0x0a
6621 0 : wSpare = Get_UShort( pData ); // 12 0x0c
6622 0 : dxaHotZ = Get_UShort( pData ); // 14 0x0e
6623 0 : cConsecHypLim = Get_UShort( pData ); // 16 0x10
6624 0 : wSpare2 = Get_UShort( pData ); // 18 0x12
6625 0 : dttmCreated = Get_Long( pData ); // 20 0x14
6626 0 : dttmRevised = Get_Long( pData ); // 24 0x18
6627 0 : dttmLastPrint = Get_Long( pData ); // 28 0x1c
6628 0 : nRevision = Get_Short( pData ); // 32 0x20
6629 0 : tmEdited = Get_Long( pData ); // 34 0x22
6630 0 : cWords = Get_Long( pData ); // 38 0x26
6631 0 : cCh = Get_Long( pData ); // 42 0x2a
6632 0 : cPg = Get_Short( pData ); // 46 0x2e
6633 0 : cParas = Get_Long( pData ); // 48 0x30
6634 :
6635 0 : a16Bit = Get_UShort( pData ); // 52 0x34
6636 0 : rncEdn = a16Bit & 0x0003 ;
6637 0 : nEdn = ( a16Bit & ~0x0003 ) >> 2;
6638 :
6639 0 : a16Bit = Get_UShort( pData ); // 54 0x36
6640 0 : epc = a16Bit & 0x0003 ;
6641 0 : nfcFtnRef = ( a16Bit & 0x003c ) >> 2;
6642 0 : nfcEdnRef = ( a16Bit & 0x03c0 ) >> 6;
6643 0 : fPrintFormData = 0 != ( a16Bit & 0x0400 );
6644 0 : fSaveFormData = 0 != ( a16Bit & 0x0800 );
6645 0 : fShadeFormData = 0 != ( a16Bit & 0x1000 );
6646 0 : fWCFtnEdn = 0 != ( a16Bit & 0x8000 );
6647 :
6648 0 : cLines = Get_Long( pData ); // 56 0x38
6649 0 : cWordsFtnEnd = Get_Long( pData ); // 60 0x3c
6650 0 : cChFtnEdn = Get_Long( pData ); // 64 0x40
6651 0 : cPgFtnEdn = Get_Short( pData ); // 68 0x44
6652 0 : cParasFtnEdn = Get_Long( pData ); // 70 0x46
6653 0 : cLinesFtnEdn = Get_Long( pData ); // 74 0x4a
6654 0 : lKeyProtDoc = Get_Long( pData ); // 78 0x4e
6655 :
6656 0 : a16Bit = Get_UShort( pData ); // 82 0x52
6657 0 : wvkSaved = a16Bit & 0x0007 ;
6658 0 : wScaleSaved = ( a16Bit & 0x0ff8 ) >> 3 ;
6659 0 : zkSaved = ( a16Bit & 0x3000 ) >> 12;
6660 0 : fRotateFontW6 = ( a16Bit & 0x4000 ) >> 14;
6661 0 : iGutterPos = ( a16Bit & 0x8000 ) >> 15;
6662 : /*
6663 : bei nFib >= 103 gehts weiter:
6664 : */
6665 0 : if (nFib >= 103) // Word 6/32bit, 95, 97, 2000, 2002, 2003, 2007
6666 : {
6667 0 : a32Bit = Get_ULong( pData ); // 84 0x54
6668 0 : SetCompatabilityOptions(a32Bit);
6669 : }
6670 :
6671 : //#i22436#, for all WW7- documents
6672 0 : if (nFib <= 104) // Word 95
6673 0 : fUsePrinterMetrics = true;
6674 :
6675 : /*
6676 : bei nFib > 105 gehts weiter:
6677 : */
6678 0 : if (nFib > 105) // Word 97, 2000, 2002, 2003, 2007
6679 : {
6680 0 : adt = Get_Short( pData ); // 88 0x58
6681 :
6682 0 : doptypography.ReadFromMem(pData); // 90 0x5a
6683 :
6684 0 : memcpy( &dogrid, pData, sizeof( WW8_DOGRID )); // 400 0x190
6685 0 : pData += sizeof( WW8_DOGRID );
6686 :
6687 0 : a16Bit = Get_UShort( pData ); // 410 0x19a
6688 : // die untersten 9 Bit sind uninteressant
6689 0 : fHtmlDoc = ( a16Bit & 0x0200 ) >> 9 ;
6690 0 : fSnapBorder = ( a16Bit & 0x0800 ) >> 11 ;
6691 0 : fIncludeHeader = ( a16Bit & 0x1000 ) >> 12 ;
6692 0 : fIncludeFooter = ( a16Bit & 0x2000 ) >> 13 ;
6693 0 : fForcePageSizePag = ( a16Bit & 0x4000 ) >> 14 ;
6694 0 : fMinFontSizePag = ( a16Bit & 0x8000 ) >> 15 ;
6695 :
6696 0 : a16Bit = Get_UShort( pData ); // 412 0x19c
6697 0 : fHaveVersions = 0 != ( a16Bit & 0x0001 );
6698 0 : fAutoVersion = 0 != ( a16Bit & 0x0002 );
6699 :
6700 0 : pData += 12; // 414 0x19e
6701 :
6702 0 : cChWS = Get_Long( pData ); // 426 0x1aa
6703 0 : cChWSFtnEdn = Get_Long( pData ); // 430 0x1ae
6704 0 : grfDocEvents = Get_Long( pData ); // 434 0x1b2
6705 :
6706 0 : pData += 4+30+8; // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc
6707 :
6708 0 : cDBC = Get_Long( pData ); // 480 0x1e0
6709 0 : cDBCFtnEdn = Get_Long( pData ); // 484 0x1e4
6710 :
6711 0 : pData += 1 * sizeof( sal_Int32); // 488 0x1e8
6712 :
6713 0 : nfcFtnRef = Get_Short( pData ); // 492 0x1ec
6714 0 : nfcEdnRef = Get_Short( pData ); // 494 0x1ee
6715 0 : hpsZoonFontPag = Get_Short( pData ); // 496 0x1f0
6716 0 : dywDispPag = Get_Short( pData ); // 498 0x1f2
6717 :
6718 0 : if (nRead >= 516)
6719 : {
6720 : //500 -> 508, Appear to be repeated here in 2000+
6721 0 : pData += 8; // 500 0x1f4
6722 0 : a32Bit = Get_Long( pData ); // 508 0x1fc
6723 0 : SetCompatabilityOptions(a32Bit);
6724 0 : a32Bit = Get_Long( pData ); // 512 0x200
6725 :
6726 : // i#78591#
6727 0 : SetCompatabilityOptions2(a32Bit);
6728 : }
6729 0 : if (nRead >= 550)
6730 : {
6731 0 : pData += 32;
6732 0 : a16Bit = Get_UShort( pData );
6733 0 : fDoNotEmbedSystemFont = ( a16Bit & 0x0001 );
6734 0 : fWordCompat = ( a16Bit & 0x0002 ) >> 1;
6735 0 : fLiveRecover = ( a16Bit & 0x0004 ) >> 2;
6736 0 : fEmbedFactoids = ( a16Bit & 0x0008 ) >> 3;
6737 0 : fFactoidXML = ( a16Bit & 0x00010 ) >> 4;
6738 0 : fFactoidAllDone = ( a16Bit & 0x0020 ) >> 5;
6739 0 : fFolioPrint = ( a16Bit & 0x0040 ) >> 6;
6740 0 : fReverseFolio = ( a16Bit & 0x0080 ) >> 7;
6741 0 : iTextLineEnding = ( a16Bit & 0x0700 ) >> 8;
6742 0 : fHideFcc = ( a16Bit & 0x0800 ) >> 11;
6743 0 : fAcetateShowMarkup = ( a16Bit & 0x1000 ) >> 12;
6744 0 : fAcetateShowAtn = ( a16Bit & 0x2000 ) >> 13;
6745 0 : fAcetateShowInsDel = ( a16Bit & 0x4000 ) >> 14;
6746 0 : fAcetateShowProps = ( a16Bit & 0x8000 ) >> 15;
6747 : }
6748 0 : if (nRead >= 600)
6749 : {
6750 0 : pData += 48;
6751 0 : a16Bit = Get_Short(pData);
6752 0 : fUseBackGroundInAllmodes = (a16Bit & 0x0080) >> 7;
6753 : }
6754 : }
6755 : }
6756 0 : delete[] pDataPtr;
6757 0 : }
6758 :
6759 0 : WW8Dop::WW8Dop() : bUseThaiLineBreakingRules(false)
6760 : {
6761 : // first set everything to a default of 0
6762 0 : memset( &nDataStart, 0, (&nDataEnd - &nDataStart) );
6763 :
6764 0 : fWidowControl = true;
6765 0 : fpc = 1;
6766 0 : nFtn = 1;
6767 0 : fOutlineDirtySave = true;
6768 0 : fHyphCapitals = true;
6769 0 : fBackup = true;
6770 0 : fPagHidden = true;
6771 0 : fPagResults = true;
6772 0 : 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 0 : fNoLeading = true;
6780 0 : fUsePrinterMetrics = true;
6781 :
6782 0 : fRMView = true;
6783 0 : fRMPrint = true;
6784 0 : dxaTab = 0x2d0;
6785 0 : dxaHotZ = 0x168;
6786 0 : nRevision = 1;
6787 0 : nEdn = 1;
6788 :
6789 0 : epc = 3;
6790 0 : nfcEdnRef = 2;
6791 0 : fShadeFormData = true;
6792 :
6793 0 : wvkSaved = 2;
6794 0 : wScaleSaved = 100;
6795 0 : zkSaved = 0;
6796 :
6797 0 : lvl = 9;
6798 0 : fIncludeHeader = true;
6799 0 : fIncludeFooter = true;
6800 :
6801 0 : cChWS = /**!!**/ 0;
6802 0 : cChWSFtnEdn = /**!!**/ 0;
6803 :
6804 0 : cDBC = /**!!**/ 0;
6805 0 : cDBCFtnEdn = /**!!**/ 0;
6806 :
6807 0 : fAcetateShowAtn = true;
6808 0 : }
6809 :
6810 0 : void WW8Dop::SetCompatabilityOptions(sal_uInt32 a32Bit)
6811 : {
6812 0 : fNoTabForInd = ( a32Bit & 0x00000001 ) ;
6813 0 : fNoSpaceRaiseLower = ( a32Bit & 0x00000002 ) >> 1 ;
6814 0 : fSupressSpbfAfterPageBreak = ( a32Bit & 0x00000004 ) >> 2 ;
6815 0 : fWrapTrailSpaces = ( a32Bit & 0x00000008 ) >> 3 ;
6816 0 : fMapPrintTextColor = ( a32Bit & 0x00000010 ) >> 4 ;
6817 0 : fNoColumnBalance = ( a32Bit & 0x00000020 ) >> 5 ;
6818 0 : fConvMailMergeEsc = ( a32Bit & 0x00000040 ) >> 6 ;
6819 0 : fSupressTopSpacing = ( a32Bit & 0x00000080 ) >> 7 ;
6820 0 : fOrigWordTableRules = ( a32Bit & 0x00000100 ) >> 8 ;
6821 0 : fTransparentMetafiles = ( a32Bit & 0x00000200 ) >> 9 ;
6822 0 : fShowBreaksInFrames = ( a32Bit & 0x00000400 ) >> 10 ;
6823 0 : fSwapBordersFacingPgs = ( a32Bit & 0x00000800 ) >> 11 ;
6824 0 : fCompatabilityOptions_Unknown1_13 = ( a32Bit & 0x00001000 ) >> 12 ;
6825 0 : fExpShRtn = ( a32Bit & 0x00002000 ) >> 13 ; // #i56856#
6826 0 : fCompatabilityOptions_Unknown1_15 = ( a32Bit & 0x00004000 ) >> 14 ;
6827 0 : fCompatabilityOptions_Unknown1_16 = ( a32Bit & 0x00008000 ) >> 15 ;
6828 0 : fSuppressTopSpacingMac5 = ( a32Bit & 0x00010000 ) >> 16 ;
6829 0 : fTruncDxaExpand = ( a32Bit & 0x00020000 ) >> 17 ;
6830 0 : fPrintBodyBeforeHdr = ( a32Bit & 0x00040000 ) >> 18 ;
6831 0 : fNoLeading = ( a32Bit & 0x00080000 ) >> 19 ;
6832 0 : fCompatabilityOptions_Unknown1_21 = ( a32Bit & 0x00100000 ) >> 20 ;
6833 0 : fMWSmallCaps = ( a32Bit & 0x00200000 ) >> 21 ;
6834 0 : fCompatabilityOptions_Unknown1_23 = ( a32Bit & 0x00400000 ) >> 22 ;
6835 0 : fCompatabilityOptions_Unknown1_24 = ( a32Bit & 0x00800800 ) >> 23 ;
6836 0 : fCompatabilityOptions_Unknown1_25 = ( a32Bit & 0x01000000 ) >> 24 ;
6837 0 : fCompatabilityOptions_Unknown1_26 = ( a32Bit & 0x02000000 ) >> 25 ;
6838 0 : fCompatabilityOptions_Unknown1_27 = ( a32Bit & 0x04000000 ) >> 26 ;
6839 0 : fCompatabilityOptions_Unknown1_28 = ( a32Bit & 0x08000000 ) >> 27 ;
6840 0 : fCompatabilityOptions_Unknown1_29 = ( a32Bit & 0x10000000 ) >> 28 ;
6841 0 : fCompatabilityOptions_Unknown1_30 = ( a32Bit & 0x20000000 ) >> 29 ;
6842 0 : fCompatabilityOptions_Unknown1_31 = ( a32Bit & 0x40000000 ) >> 30 ;
6843 :
6844 0 : fUsePrinterMetrics = ( a32Bit & 0x80000000 ) >> 31 ;
6845 0 : }
6846 :
6847 0 : sal_uInt32 WW8Dop::GetCompatabilityOptions() const
6848 : {
6849 0 : sal_uInt32 a32Bit = 0;
6850 0 : if (fNoTabForInd) a32Bit |= 0x00000001;
6851 0 : if (fNoSpaceRaiseLower) a32Bit |= 0x00000002;
6852 0 : if (fSupressSpbfAfterPageBreak) a32Bit |= 0x00000004;
6853 0 : if (fWrapTrailSpaces) a32Bit |= 0x00000008;
6854 0 : if (fMapPrintTextColor) a32Bit |= 0x00000010;
6855 0 : if (fNoColumnBalance) a32Bit |= 0x00000020;
6856 0 : if (fConvMailMergeEsc) a32Bit |= 0x00000040;
6857 0 : if (fSupressTopSpacing) a32Bit |= 0x00000080;
6858 0 : if (fOrigWordTableRules) a32Bit |= 0x00000100;
6859 0 : if (fTransparentMetafiles) a32Bit |= 0x00000200;
6860 0 : if (fShowBreaksInFrames) a32Bit |= 0x00000400;
6861 0 : if (fSwapBordersFacingPgs) a32Bit |= 0x00000800;
6862 0 : if (fCompatabilityOptions_Unknown1_13) a32Bit |= 0x00001000;
6863 0 : if (fExpShRtn) a32Bit |= 0x00002000; // #i56856#
6864 0 : if (fCompatabilityOptions_Unknown1_15) a32Bit |= 0x00004000;
6865 0 : if (fCompatabilityOptions_Unknown1_16) a32Bit |= 0x00008000;
6866 0 : if (fSuppressTopSpacingMac5) a32Bit |= 0x00010000;
6867 0 : if (fTruncDxaExpand) a32Bit |= 0x00020000;
6868 0 : if (fPrintBodyBeforeHdr) a32Bit |= 0x00040000;
6869 0 : if (fNoLeading) a32Bit |= 0x00080000;
6870 0 : if (fCompatabilityOptions_Unknown1_21) a32Bit |= 0x00100000;
6871 0 : if (fMWSmallCaps) a32Bit |= 0x00200000;
6872 0 : if (fCompatabilityOptions_Unknown1_23) a32Bit |= 0x00400000;
6873 0 : if (fCompatabilityOptions_Unknown1_24) a32Bit |= 0x00800000;
6874 0 : if (fCompatabilityOptions_Unknown1_25) a32Bit |= 0x01000000;
6875 0 : if (fCompatabilityOptions_Unknown1_26) a32Bit |= 0x02000000;
6876 0 : if (fCompatabilityOptions_Unknown1_27) a32Bit |= 0x04000000;
6877 0 : if (fCompatabilityOptions_Unknown1_28) a32Bit |= 0x08000000;
6878 0 : if (fCompatabilityOptions_Unknown1_29) a32Bit |= 0x10000000;
6879 0 : if (fCompatabilityOptions_Unknown1_30) a32Bit |= 0x20000000;
6880 0 : if (fCompatabilityOptions_Unknown1_31) a32Bit |= 0x40000000;
6881 0 : if (fUsePrinterMetrics) a32Bit |= 0x80000000;
6882 0 : return a32Bit;
6883 : }
6884 :
6885 : // i#78591#
6886 0 : void WW8Dop::SetCompatabilityOptions2(sal_uInt32 a32Bit)
6887 : {
6888 0 : fCompatabilityOptions_Unknown2_1 = ( a32Bit & 0x00000001 );
6889 0 : fCompatabilityOptions_Unknown2_2 = ( a32Bit & 0x00000002 ) >> 1 ;
6890 0 : fDontUseHTMLAutoSpacing = ( a32Bit & 0x00000004 ) >> 2 ;
6891 0 : fCompatabilityOptions_Unknown2_4 = ( a32Bit & 0x00000008 ) >> 3 ;
6892 0 : fCompatabilityOptions_Unknown2_5 = ( a32Bit & 0x00000010 ) >> 4 ;
6893 0 : fCompatabilityOptions_Unknown2_6 = ( a32Bit & 0x00000020 ) >> 5 ;
6894 0 : fCompatabilityOptions_Unknown2_7 = ( a32Bit & 0x00000040 ) >> 6 ;
6895 0 : fCompatabilityOptions_Unknown2_8 = ( a32Bit & 0x00000080 ) >> 7 ;
6896 0 : fCompatabilityOptions_Unknown2_9 = ( a32Bit & 0x00000100 ) >> 8 ;
6897 0 : fCompatabilityOptions_Unknown2_10 = ( a32Bit & 0x00000200 ) >> 9 ;
6898 0 : fCompatabilityOptions_Unknown2_11 = ( a32Bit & 0x00000400 ) >> 10 ;
6899 0 : fCompatabilityOptions_Unknown2_12 = ( a32Bit & 0x00000800 ) >> 11 ;
6900 0 : fCompatabilityOptions_Unknown2_13 = ( a32Bit & 0x00001000 ) >> 12 ;
6901 0 : fCompatabilityOptions_Unknown2_14 = ( a32Bit & 0x00002000 ) >> 13 ;
6902 0 : fCompatabilityOptions_Unknown2_15 = ( a32Bit & 0x00004000 ) >> 14 ;
6903 0 : fCompatabilityOptions_Unknown2_16 = ( a32Bit & 0x00008000 ) >> 15 ;
6904 0 : fCompatabilityOptions_Unknown2_17 = ( a32Bit & 0x00010000 ) >> 16 ;
6905 0 : fCompatabilityOptions_Unknown2_18 = ( a32Bit & 0x00020000 ) >> 17 ;
6906 0 : fCompatabilityOptions_Unknown2_19 = ( a32Bit & 0x00040000 ) >> 18 ;
6907 0 : fCompatabilityOptions_Unknown2_20 = ( a32Bit & 0x00080000 ) >> 19 ;
6908 0 : fCompatabilityOptions_Unknown2_21 = ( a32Bit & 0x00100000 ) >> 20 ;
6909 0 : fCompatabilityOptions_Unknown2_22 = ( a32Bit & 0x00200000 ) >> 21 ;
6910 0 : fCompatabilityOptions_Unknown2_23 = ( a32Bit & 0x00400000 ) >> 22 ;
6911 0 : fCompatabilityOptions_Unknown2_24 = ( a32Bit & 0x00800800 ) >> 23 ;
6912 0 : fCompatabilityOptions_Unknown2_25 = ( a32Bit & 0x01000800 ) >> 24 ;
6913 0 : fCompatabilityOptions_Unknown2_26 = ( a32Bit & 0x02000800 ) >> 25 ;
6914 0 : fCompatabilityOptions_Unknown2_27 = ( a32Bit & 0x04000800 ) >> 26 ;
6915 0 : fCompatabilityOptions_Unknown2_28 = ( a32Bit & 0x08000800 ) >> 27 ;
6916 0 : fCompatabilityOptions_Unknown2_29 = ( a32Bit & 0x10000800 ) >> 28 ;
6917 0 : fCompatabilityOptions_Unknown2_30 = ( a32Bit & 0x20000800 ) >> 29 ;
6918 0 : fCompatabilityOptions_Unknown2_31 = ( a32Bit & 0x40000800 ) >> 30 ;
6919 0 : fCompatabilityOptions_Unknown2_32 = ( a32Bit & 0x80000000 ) >> 31 ;
6920 0 : }
6921 :
6922 0 : sal_uInt32 WW8Dop::GetCompatabilityOptions2() const
6923 : {
6924 0 : sal_uInt32 a32Bit = 0;
6925 0 : if (fCompatabilityOptions_Unknown2_1) a32Bit |= 0x00000001;
6926 0 : if (fCompatabilityOptions_Unknown2_2) a32Bit |= 0x00000002;
6927 0 : if (fDontUseHTMLAutoSpacing) a32Bit |= 0x00000004;
6928 0 : if (fCompatabilityOptions_Unknown2_4) a32Bit |= 0x00000008;
6929 0 : if (fCompatabilityOptions_Unknown2_5) a32Bit |= 0x00000010;
6930 0 : if (fCompatabilityOptions_Unknown2_6) a32Bit |= 0x00000020;
6931 0 : if (fCompatabilityOptions_Unknown2_7) a32Bit |= 0x00000040;
6932 0 : if (fCompatabilityOptions_Unknown2_8) a32Bit |= 0x00000080;
6933 0 : if (fCompatabilityOptions_Unknown2_9) a32Bit |= 0x00000100;
6934 0 : if (fCompatabilityOptions_Unknown2_10) a32Bit |= 0x00000200;
6935 0 : if (fCompatabilityOptions_Unknown2_11) a32Bit |= 0x00000400;
6936 0 : if (fCompatabilityOptions_Unknown2_12) a32Bit |= 0x00000800;
6937 0 : 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 0 : if (bUseThaiLineBreakingRules) a32Bit |= 0x00002000;
6942 0 : else if (fCompatabilityOptions_Unknown2_14) a32Bit |= 0x00002000;
6943 0 : if (fCompatabilityOptions_Unknown2_15) a32Bit |= 0x00004000;
6944 0 : if (fCompatabilityOptions_Unknown2_16) a32Bit |= 0x00008000;
6945 0 : if (fCompatabilityOptions_Unknown2_17) a32Bit |= 0x00010000;
6946 0 : if (fCompatabilityOptions_Unknown2_18) a32Bit |= 0x00020000;
6947 0 : if (fCompatabilityOptions_Unknown2_19) a32Bit |= 0x00040000;
6948 0 : if (fCompatabilityOptions_Unknown2_20) a32Bit |= 0x00080000;
6949 0 : if (fCompatabilityOptions_Unknown2_21) a32Bit |= 0x00100000;
6950 0 : if (fCompatabilityOptions_Unknown2_22) a32Bit |= 0x00200000;
6951 0 : if (fCompatabilityOptions_Unknown2_23) a32Bit |= 0x00400000;
6952 0 : if (fCompatabilityOptions_Unknown2_24) a32Bit |= 0x00800000;
6953 0 : if (fCompatabilityOptions_Unknown2_25) a32Bit |= 0x01000000;
6954 0 : if (fCompatabilityOptions_Unknown2_26) a32Bit |= 0x02000000;
6955 0 : if (fCompatabilityOptions_Unknown2_27) a32Bit |= 0x04000000;
6956 0 : if (fCompatabilityOptions_Unknown2_28) a32Bit |= 0x08000000;
6957 0 : if (fCompatabilityOptions_Unknown2_29) a32Bit |= 0x10000000;
6958 0 : if (fCompatabilityOptions_Unknown2_30) a32Bit |= 0x20000000;
6959 0 : if (fCompatabilityOptions_Unknown2_31) a32Bit |= 0x40000000;
6960 0 : if (fCompatabilityOptions_Unknown2_32) a32Bit |= 0x80000000;
6961 0 : return a32Bit;
6962 : }
6963 :
6964 0 : bool WW8Dop::Write(SvStream& rStrm, WW8Fib& rFib) const
6965 : {
6966 0 : const int nMaxDopLen = 610;
6967 0 : sal_uInt32 nLen = 8 == rFib.nVersion ? nMaxDopLen : 84;
6968 0 : rFib.fcDop = rStrm.Tell();
6969 0 : rFib.lcbDop = nLen;
6970 :
6971 : sal_uInt8 aData[ nMaxDopLen ];
6972 0 : memset( aData, 0, nMaxDopLen );
6973 0 : sal_uInt8* pData = aData;
6974 :
6975 : // dann mal die Daten auswerten
6976 : sal_uInt16 a16Bit;
6977 : sal_uInt8 a8Bit;
6978 :
6979 0 : a16Bit = 0; // 0 0x00
6980 0 : if (fFacingPages)
6981 0 : a16Bit |= 0x0001;
6982 0 : if (fWidowControl)
6983 0 : a16Bit |= 0x0002;
6984 0 : if (fPMHMainDoc)
6985 0 : a16Bit |= 0x0004;
6986 0 : a16Bit |= ( 0x0018 & (grfSuppression << 3));
6987 0 : a16Bit |= ( 0x0060 & (fpc << 5));
6988 0 : a16Bit |= ( 0xff00 & (grpfIhdt << 8));
6989 0 : Set_UInt16( pData, a16Bit );
6990 :
6991 0 : a16Bit = 0; // 2 0x02
6992 0 : a16Bit |= ( 0x0003 & rncFtn );
6993 0 : a16Bit |= ( ~0x0003 & (nFtn << 2));
6994 0 : Set_UInt16( pData, a16Bit );
6995 :
6996 0 : a8Bit = 0; // 4 0x04
6997 0 : if( fOutlineDirtySave ) a8Bit |= 0x01;
6998 0 : Set_UInt8( pData, a8Bit );
6999 :
7000 0 : a8Bit = 0; // 5 0x05
7001 0 : if( fOnlyMacPics ) a8Bit |= 0x01;
7002 0 : if( fOnlyWinPics ) a8Bit |= 0x02;
7003 0 : if( fLabelDoc ) a8Bit |= 0x04;
7004 0 : if( fHyphCapitals ) a8Bit |= 0x08;
7005 0 : if( fAutoHyphen ) a8Bit |= 0x10;
7006 0 : if( fFormNoFields ) a8Bit |= 0x20;
7007 0 : if( fLinkStyles ) a8Bit |= 0x40;
7008 0 : if( fRevMarking ) a8Bit |= 0x80;
7009 0 : Set_UInt8( pData, a8Bit );
7010 :
7011 0 : a8Bit = 0; // 6 0x06
7012 0 : if( fBackup ) a8Bit |= 0x01;
7013 0 : if( fExactCWords ) a8Bit |= 0x02;
7014 0 : if( fPagHidden ) a8Bit |= 0x04;
7015 0 : if( fPagResults ) a8Bit |= 0x08;
7016 0 : if( fLockAtn ) a8Bit |= 0x10;
7017 0 : if( fMirrorMargins ) a8Bit |= 0x20;
7018 0 : if( fReadOnlyRecommended ) a8Bit |= 0x40;
7019 0 : if( fDfltTrueType ) a8Bit |= 0x80;
7020 0 : Set_UInt8( pData, a8Bit );
7021 :
7022 0 : a8Bit = 0; // 7 0x07
7023 0 : if( fPagSuppressTopSpacing ) a8Bit |= 0x01;
7024 0 : if( fProtEnabled ) a8Bit |= 0x02;
7025 0 : if( fDispFormFldSel ) a8Bit |= 0x04;
7026 0 : if( fRMView ) a8Bit |= 0x08;
7027 0 : if( fRMPrint ) a8Bit |= 0x10;
7028 0 : if( fWriteReservation ) a8Bit |= 0x20;
7029 0 : if( fLockRev ) a8Bit |= 0x40;
7030 0 : if( fEmbedFonts ) a8Bit |= 0x80;
7031 0 : Set_UInt8( pData, a8Bit );
7032 :
7033 0 : a8Bit = 0; // 8 0x08
7034 0 : if( copts_fNoTabForInd ) a8Bit |= 0x01;
7035 0 : if( copts_fNoSpaceRaiseLower ) a8Bit |= 0x02;
7036 0 : if( copts_fSupressSpbfAfterPgBrk ) a8Bit |= 0x04;
7037 0 : if( copts_fWrapTrailSpaces ) a8Bit |= 0x08;
7038 0 : if( copts_fMapPrintTextColor ) a8Bit |= 0x10;
7039 0 : if( copts_fNoColumnBalance ) a8Bit |= 0x20;
7040 0 : if( copts_fConvMailMergeEsc ) a8Bit |= 0x40;
7041 0 : if( copts_fSupressTopSpacing ) a8Bit |= 0x80;
7042 0 : Set_UInt8( pData, a8Bit );
7043 :
7044 0 : a8Bit = 0; // 9 0x09
7045 0 : if( copts_fOrigWordTableRules ) a8Bit |= 0x01;
7046 0 : if( copts_fTransparentMetafiles ) a8Bit |= 0x02;
7047 0 : if( copts_fShowBreaksInFrames ) a8Bit |= 0x04;
7048 0 : if( copts_fSwapBordersFacingPgs ) a8Bit |= 0x08;
7049 0 : if( copts_fExpShRtn ) a8Bit |= 0x20; // #i56856#
7050 0 : Set_UInt8( pData, a8Bit );
7051 :
7052 0 : Set_UInt16( pData, dxaTab ); // 10 0x0a
7053 0 : Set_UInt16( pData, wSpare ); // 12 0x0c
7054 0 : Set_UInt16( pData, dxaHotZ ); // 14 0x0e
7055 0 : Set_UInt16( pData, cConsecHypLim ); // 16 0x10
7056 0 : Set_UInt16( pData, wSpare2 ); // 18 0x12
7057 0 : Set_UInt32( pData, dttmCreated ); // 20 0x14
7058 0 : Set_UInt32( pData, dttmRevised ); // 24 0x18
7059 0 : Set_UInt32( pData, dttmLastPrint ); // 28 0x1c
7060 0 : Set_UInt16( pData, nRevision ); // 32 0x20
7061 0 : Set_UInt32( pData, tmEdited ); // 34 0x22
7062 0 : Set_UInt32( pData, cWords ); // 38 0x26
7063 0 : Set_UInt32( pData, cCh ); // 42 0x2a
7064 0 : Set_UInt16( pData, cPg ); // 46 0x2e
7065 0 : Set_UInt32( pData, cParas ); // 48 0x30
7066 :
7067 0 : a16Bit = 0; // 52 0x34
7068 0 : a16Bit |= ( 0x0003 & rncEdn );
7069 0 : a16Bit |= (~0x0003 & ( nEdn << 2));
7070 0 : Set_UInt16( pData, a16Bit );
7071 :
7072 0 : a16Bit = 0; // 54 0x36
7073 0 : a16Bit |= (0x0003 & epc );
7074 0 : a16Bit |= (0x003c & (nfcFtnRef << 2));
7075 0 : a16Bit |= (0x03c0 & (nfcEdnRef << 6));
7076 0 : if( fPrintFormData ) a16Bit |= 0x0400;
7077 0 : if( fSaveFormData ) a16Bit |= 0x0800;
7078 0 : if( fShadeFormData ) a16Bit |= 0x1000;
7079 0 : if( fWCFtnEdn ) a16Bit |= 0x8000;
7080 0 : Set_UInt16( pData, a16Bit );
7081 :
7082 0 : Set_UInt32( pData, cLines ); // 56 0x38
7083 0 : Set_UInt32( pData, cWordsFtnEnd ); // 60 0x3c
7084 0 : Set_UInt32( pData, cChFtnEdn ); // 64 0x40
7085 0 : Set_UInt16( pData, cPgFtnEdn ); // 68 0x44
7086 0 : Set_UInt32( pData, cParasFtnEdn ); // 70 0x46
7087 0 : Set_UInt32( pData, cLinesFtnEdn ); // 74 0x4a
7088 0 : Set_UInt32( pData, lKeyProtDoc ); // 78 0x4e
7089 :
7090 0 : a16Bit = 0; // 82 0x52
7091 0 : if (wvkSaved)
7092 0 : a16Bit |= 0x0007;
7093 0 : a16Bit |= (0x0ff8 & (wScaleSaved << 3));
7094 0 : a16Bit |= (0x3000 & (zkSaved << 12));
7095 0 : Set_UInt16( pData, a16Bit );
7096 :
7097 0 : if( 8 == rFib.nVersion )
7098 : {
7099 0 : Set_UInt32(pData, GetCompatabilityOptions()); // 84 0x54
7100 :
7101 0 : Set_UInt16( pData, adt ); // 88 0x58
7102 :
7103 0 : doptypography.WriteToMem(pData); // 400 0x190
7104 :
7105 0 : memcpy( pData, &dogrid, sizeof( WW8_DOGRID ));
7106 0 : pData += sizeof( WW8_DOGRID );
7107 :
7108 0 : a16Bit = 0x12; // lvl auf 9 setzen // 410 0x19a
7109 0 : if( fHtmlDoc ) a16Bit |= 0x0200;
7110 0 : if( fSnapBorder ) a16Bit |= 0x0800;
7111 0 : if( fIncludeHeader ) a16Bit |= 0x1000;
7112 0 : if( fIncludeFooter ) a16Bit |= 0x2000;
7113 0 : if( fForcePageSizePag ) a16Bit |= 0x4000;
7114 0 : if( fMinFontSizePag ) a16Bit |= 0x8000;
7115 0 : Set_UInt16( pData, a16Bit );
7116 :
7117 0 : a16Bit = 0; // 412 0x19c
7118 0 : if( fHaveVersions ) a16Bit |= 0x0001;
7119 0 : if( fAutoVersion ) a16Bit |= 0x0002;
7120 0 : Set_UInt16( pData, a16Bit );
7121 :
7122 0 : pData += 12; // 414 0x19e
7123 :
7124 0 : Set_UInt32( pData, cChWS ); // 426 0x1aa
7125 0 : Set_UInt32( pData, cChWSFtnEdn ); // 430 0x1ae
7126 0 : Set_UInt32( pData, grfDocEvents ); // 434 0x1b2
7127 :
7128 0 : pData += 4+30+8; // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc
7129 :
7130 0 : Set_UInt32( pData, cDBC ); // 480 0x1e0
7131 0 : Set_UInt32( pData, cDBCFtnEdn ); // 484 0x1e4
7132 :
7133 0 : pData += 1 * sizeof( sal_Int32); // 488 0x1e8
7134 :
7135 0 : Set_UInt16( pData, nfcFtnRef ); // 492 0x1ec
7136 0 : Set_UInt16( pData, nfcEdnRef ); // 494 0x1ee
7137 0 : Set_UInt16( pData, hpsZoonFontPag ); // 496 0x1f0
7138 0 : Set_UInt16( pData, dywDispPag ); // 498 0x1f2
7139 :
7140 : //500 -> 508, Appear to be repeated here in 2000+
7141 0 : pData += 8;
7142 0 : Set_UInt32(pData, GetCompatabilityOptions());
7143 0 : Set_UInt32(pData, GetCompatabilityOptions2());
7144 0 : pData += 32;
7145 :
7146 0 : a16Bit = 0;
7147 0 : if (fAcetateShowMarkup)
7148 0 : a16Bit |= 0x1000;
7149 : //Word XP at least requires fAcetateShowMarkup to honour fAcetateShowAtn
7150 0 : if (fAcetateShowAtn)
7151 : {
7152 0 : a16Bit |= 0x1000;
7153 0 : a16Bit |= 0x2000;
7154 : }
7155 0 : Set_UInt16(pData, a16Bit);
7156 :
7157 0 : pData += 48;
7158 0 : a16Bit = 0x0080;
7159 0 : Set_UInt16(pData, a16Bit);
7160 : }
7161 0 : rStrm.Write( aData, nLen );
7162 0 : return 0 == rStrm.GetError();
7163 : }
7164 :
7165 0 : void WW8DopTypography::ReadFromMem(sal_uInt8 *&pData)
7166 : {
7167 0 : sal_uInt16 a16Bit = Get_UShort(pData);
7168 0 : fKerningPunct = (a16Bit & 0x0001);
7169 0 : iJustification = (a16Bit & 0x0006) >> 1;
7170 0 : iLevelOfKinsoku = (a16Bit & 0x0018) >> 3;
7171 0 : f2on1 = (a16Bit & 0x0020) >> 5;
7172 0 : reserved1 = (a16Bit & 0x03C0) >> 6;
7173 0 : reserved2 = (a16Bit & 0xFC00) >> 10;
7174 :
7175 0 : cchFollowingPunct = Get_Short(pData);
7176 0 : cchLeadingPunct = Get_Short(pData);
7177 :
7178 : sal_Int16 i;
7179 0 : for (i=0; i < nMaxFollowing; ++i)
7180 0 : rgxchFPunct[i] = Get_Short(pData);
7181 0 : for (i=0; i < nMaxLeading; ++i)
7182 0 : rgxchLPunct[i] = Get_Short(pData);
7183 :
7184 0 : if (cchFollowingPunct >= 0 && cchFollowingPunct < nMaxFollowing)
7185 0 : rgxchFPunct[cchFollowingPunct]=0;
7186 : else
7187 0 : rgxchFPunct[nMaxFollowing - 1]=0;
7188 :
7189 0 : if (cchLeadingPunct >= 0 && cchLeadingPunct < nMaxLeading)
7190 0 : rgxchLPunct[cchLeadingPunct]=0;
7191 : else
7192 0 : rgxchLPunct[nMaxLeading - 1]=0;
7193 :
7194 0 : }
7195 :
7196 0 : void WW8DopTypography::WriteToMem(sal_uInt8 *&pData) const
7197 : {
7198 0 : sal_uInt16 a16Bit = sal_uInt16(fKerningPunct);
7199 0 : a16Bit |= (iJustification << 1) & 0x0006;
7200 0 : a16Bit |= (iLevelOfKinsoku << 3) & 0x0018;
7201 0 : a16Bit |= (int(f2on1) << 5) & 0x0020;
7202 0 : a16Bit |= (reserved1 << 6) & 0x03C0;
7203 0 : a16Bit |= (reserved2 << 10) & 0xFC00;
7204 0 : Set_UInt16(pData,a16Bit);
7205 :
7206 0 : Set_UInt16(pData,cchFollowingPunct);
7207 0 : Set_UInt16(pData,cchLeadingPunct);
7208 :
7209 : sal_Int16 i;
7210 0 : for (i=0; i < nMaxFollowing; ++i)
7211 0 : Set_UInt16(pData,rgxchFPunct[i]);
7212 0 : for (i=0; i < nMaxLeading; ++i)
7213 0 : Set_UInt16(pData,rgxchLPunct[i]);
7214 0 : }
7215 :
7216 0 : 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 0 : switch(reserved1 & 0xE)
7230 : {
7231 : case 2: //Japan
7232 0 : nLang = LANGUAGE_JAPANESE;
7233 0 : break;
7234 : case 4: //Chinese (Peoples Republic)
7235 0 : nLang = LANGUAGE_CHINESE_SIMPLIFIED;
7236 0 : break;
7237 : case 6: //Korean
7238 0 : nLang = LANGUAGE_KOREAN;
7239 0 : break;
7240 : case 8: //Chinese (Taiwan)
7241 0 : nLang = LANGUAGE_CHINESE_TRADITIONAL;
7242 0 : 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 0 : return nLang;
7255 : }
7256 :
7257 : // Sprms
7258 :
7259 0 : sal_uInt16 wwSprmParser::GetSprmTailLen(sal_uInt16 nId, const sal_uInt8* pSprm)
7260 : const
7261 : {
7262 0 : SprmInfo aSprm = GetSprmInfo(nId);
7263 0 : sal_uInt16 nL = 0; // number of Bytes to read
7264 :
7265 : //sprmPChgTabs
7266 0 : switch( nId )
7267 : {
7268 : case 23:
7269 : case 0xC615:
7270 0 : if( pSprm[1 + mnDelta] != 255 )
7271 0 : 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 0 : break;
7280 : case 0xD608:
7281 0 : nL = SVBT16ToShort( &pSprm[1 + mnDelta] );
7282 0 : break;
7283 : default:
7284 0 : switch (aSprm.nVari)
7285 : {
7286 : case L_FIX:
7287 0 : nL = aSprm.nLen; // Excl. Token
7288 0 : break;
7289 : case L_VAR:
7290 : // Variable 1-Byte Length?
7291 : // Excl. Token + Var-Lengthbyte
7292 0 : nL = static_cast< sal_uInt16 >(pSprm[1 + mnDelta] + aSprm.nLen);
7293 0 : 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 0 : break;
7304 : }
7305 0 : return nL;
7306 : }
7307 :
7308 : // one or two bytes at the beginning at the sprm id
7309 0 : sal_uInt16 wwSprmParser::GetSprmId(const sal_uInt8* pSp) const
7310 : {
7311 0 : ASSERT_RET_ON_FAIL(pSp, "Why GetSprmId with pSp of 0", 0);
7312 :
7313 0 : sal_uInt16 nId = 0;
7314 :
7315 0 : if (ww::IsSevenMinus(meVersion))
7316 : {
7317 0 : nId = *pSp;
7318 0 : if (0x0100 < nId)
7319 0 : nId = 0;
7320 : }
7321 : else
7322 : {
7323 0 : nId = SVBT16ToShort(pSp);
7324 0 : if (0x0800 > nId)
7325 0 : nId = 0;
7326 : }
7327 :
7328 0 : return nId;
7329 : }
7330 :
7331 : // with tokens and length byte
7332 0 : sal_uInt16 wwSprmParser::GetSprmSize(sal_uInt16 nId, const sal_uInt8* pSprm) const
7333 : {
7334 0 : return GetSprmTailLen(nId, pSprm) + 1 + mnDelta + SprmDataOfs(nId);
7335 : }
7336 :
7337 0 : sal_uInt8 wwSprmParser::SprmDataOfs(sal_uInt16 nId) const
7338 : {
7339 0 : return GetSprmInfo(nId).nVari;
7340 : }
7341 :
7342 0 : sal_uInt16 wwSprmParser::DistanceToData(sal_uInt16 nId) const
7343 : {
7344 0 : return 1 + mnDelta + SprmDataOfs(nId);
7345 : }
7346 :
7347 0 : sal_uInt8* wwSprmParser::findSprmData(sal_uInt16 nId, sal_uInt8* pSprms,
7348 : sal_uInt16 nLen) const
7349 : {
7350 0 : while (nLen >= MinSprmLen())
7351 : {
7352 0 : sal_uInt16 nAktId = GetSprmId(pSprms);
7353 : // gib Zeiger auf Daten
7354 0 : sal_uInt16 nSize = GetSprmSize(nAktId, pSprms);
7355 :
7356 0 : 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 0 : if (nAktId == nId && bValid) // Sprm found
7363 0 : return pSprms + DistanceToData(nId);
7364 :
7365 : //Clip to available size if wrong
7366 0 : nSize = std::min(nSize, nLen);
7367 0 : pSprms += nSize;
7368 0 : nLen -= nSize;
7369 : }
7370 : // Sprm not found
7371 0 : return 0;
7372 : }
7373 :
7374 0 : 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 0 : reserved4(0)
7388 : {
7389 0 : memset(rgdxaColumnWidthSpacing, 0, sizeof(rgdxaColumnWidthSpacing));
7390 0 : }
7391 :
7392 0 : bool checkSeek(SvStream &rSt, sal_uInt32 nOffset)
7393 : {
7394 0 : return (rSt.Seek(nOffset) == static_cast<sal_Size>(nOffset));
7395 : }
7396 :
7397 0 : bool checkRead(SvStream &rSt, void *pDest, sal_uInt32 nLength)
7398 : {
7399 0 : return (rSt.Read(pDest, nLength) == static_cast<sal_Size>(nLength));
7400 0 : }
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: */
|