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