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