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