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