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