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