1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "ww8scan.hxx"
26 #include <i18nlangtag/mslangid.hxx>
27 #include <rtl/tencinfo.h>
28 #include <sal/macros.h>
32 #define ERR_SWG_READ_ERROR 1234
33 #define OSL_ENSURE( a, b )
36 #include <swerror.h> // ERR_WW6_...
37 #include <swtypes.hxx> // DELETEZ
40 #include <comphelper/processfactory.hxx>
41 #include <comphelper/string.hxx>
42 #include <unotools/localedatawrapper.hxx>
43 #include <i18nlangtag/lang.h>
44 #include <editeng/unolingu.hxx>
45 #include <vcl/svapp.hxx> // Application #i90932#
49 #define ASSERT_RET_ON_FAIL( aCon, aError, aRet ) \
50 OSL_ENSURE(aCon, aError); \
54 using namespace ::com::sun::star::lang
;
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
);
74 winword strings are typically Belt and Braces strings preceeded with a
75 pascal style count, and ending with a c style 0 terminator. 16bit chars
76 and count for ww8+ and 8bit chars and count for ww7-. The count and 0
77 can be checked for integrity to catch errors (e.g. lotus created
78 documents) where in error 8bit strings are used instead of 16bits
79 strings for style names.
81 template<typename C
> bool TestBeltAndBraces(SvStream
& rStrm
)
84 sal_uInt32 nOldPos
= rStrm
.Tell();
88 if (rStrm
.good() && (rStrm
.remainingSize() >= (nBelt
+ sizeof(C
))))
95 if (rStrm
.good() && cBraces
== 0)
104 inline bool operator==(const SprmInfo
&rFirst
, const SprmInfo
&rSecond
)
106 return (rFirst
.nId
== rSecond
.nId
);
109 const wwSprmSearcher
*wwSprmParser::GetWW2SprmSearcher()
113 static const SprmInfo aSprms
[] =
115 { 0, 0, L_FIX
}, // "Default-sprm", will be skipped
116 { 2, 1, L_FIX
}, // "sprmPIstd", pap.istd (style code)
117 { 3, 0, L_VAR
}, // "sprmPIstdPermute pap.istd permutation
118 { 4, 1, L_FIX
}, // "sprmPIncLv1" pap.istddifference
119 { 5, 1, L_FIX
}, // "sprmPJc" pap.jc (justification)
120 { 6, 1, L_FIX
}, // "sprmPFSideBySide" pap.fSideBySide
121 { 7, 1, L_FIX
}, // "sprmPFKeep" pap.fKeep
122 { 8, 1, L_FIX
}, // "sprmPFKeepFollow " pap.fKeepFollow
123 { 9, 1, L_FIX
}, // "sprmPPageBreakBefore" pap.fPageBreakBefore
124 { 10, 1, L_FIX
}, // "sprmPBrcl" pap.brcl
125 { 11, 1, L_FIX
}, // "sprmPBrcp" pap.brcp
126 { 12, 1, L_FIX
}, // "sprmPNfcSeqNumb" pap.nfcSeqNumb
127 { 13, 1, L_FIX
}, // "sprmPNoSeqNumb" pap.nnSeqNumb
128 { 14, 1, L_FIX
}, // "sprmPFNoLineNumb" pap.fNoLnn
129 { 15, 0, L_VAR
}, // "?sprmPChgTabsPapx" pap.itbdMac, ...
130 { 16, 2, L_FIX
}, // "sprmPDxaRight" pap.dxaRight
131 { 17, 2, L_FIX
}, // "sprmPDxaLeft" pap.dxaLeft
132 { 18, 2, L_FIX
}, // "sprmPNest" pap.dxaLeft
133 { 19, 2, L_FIX
}, // "sprmPDxaLeft1" pap.dxaLeft1
134 { 20, 2, L_FIX
}, // "sprmPDyaLine" pap.lspd an LSPD
135 { 21, 2, L_FIX
}, // "sprmPDyaBefore" pap.dyaBefore
136 { 22, 2, L_FIX
}, // "sprmPDyaAfter" pap.dyaAfter
137 { 23, 0, L_VAR
}, // "?sprmPChgTabs" pap.itbdMac, pap.rgdxaTab, ...
138 { 24, 1, L_FIX
}, // "sprmPFInTable" pap.fInTable
139 { 25, 1, L_FIX
}, // "sprmPTtp" pap.fTtp
140 { 26, 2, L_FIX
}, // "sprmPDxaAbs" pap.dxaAbs
141 { 27, 2, L_FIX
}, // "sprmPDyaAbs" pap.dyaAbs
142 { 28, 2, L_FIX
}, // "sprmPDxaWidth" pap.dxaWidth
143 { 29, 1, L_FIX
}, // "sprmPPc" pap.pcHorz, pap.pcVert
144 { 30, 2, L_FIX
}, // "sprmPBrcTop10" pap.brcTop BRC10
145 { 31, 2, L_FIX
}, // "sprmPBrcLeft10" pap.brcLeft BRC10
146 { 32, 2, L_FIX
}, // "sprmPBrcBottom10" pap.brcBottom BRC10
147 { 33, 2, L_FIX
}, // "sprmPBrcRight10" pap.brcRight BRC10
148 { 34, 2, L_FIX
}, // "sprmPBrcBetween10" pap.brcBetween BRC10
149 { 35, 2, L_FIX
}, // "sprmPBrcBar10" pap.brcBar BRC10
150 { 36, 2, L_FIX
}, // "sprmPFromText10" pap.dxaFromText dxa
151 { 37, 1, L_FIX
}, // "sprmPWr" pap.wr wr
152 { 38, 2, L_FIX
}, // "sprmPBrcTop" pap.brcTop BRC
153 { 39, 2, L_FIX
}, // "sprmPBrcLeft" pap.brcLeft BRC
154 { 40, 2, L_FIX
}, // "sprmPBrcBottom" pap.brcBottom BRC
155 { 41, 2, L_FIX
}, // "sprmPBrcRight" pap.brcRight BRC
156 { 42, 2, L_FIX
}, // "sprmPBrcBetween" pap.brcBetween BRC
157 { 43, 2, L_FIX
}, // "sprmPBrcBar" pap.brcBar BRC word
158 { 44, 1, L_FIX
}, // "sprmPFNoAutoHyph" pap.fNoAutoHyph
159 { 45, 2, L_FIX
}, // "sprmPWHeightAbs" pap.wHeightAbs w
160 { 46, 2, L_FIX
}, // "sprmPDcs" pap.dcs DCS
161 { 47, 2, L_FIX
}, // "sprmPShd" pap.shd SHD
162 { 48, 2, L_FIX
}, // "sprmPDyaFromText" pap.dyaFromText dya
163 { 49, 2, L_FIX
}, // "sprmPDxaFromText" pap.dxaFromText dxa
164 { 50, 1, L_FIX
}, // "sprmPFBiDi" pap.fBiDi 0 or 1 byte
165 { 51, 1, L_FIX
}, // "sprmPFWidowControl" pap.fWidowControl 0 or 1 byte
166 { 52, 0, L_FIX
}, // "?sprmPRuler 52"
167 { 53, 1, L_FIX
}, // "sprmCFStrikeRM" chp.fRMarkDel 1 or 0 bit
168 { 54, 1, L_FIX
}, // "sprmCFRMark" chp.fRMark 1 or 0 bit
169 { 55, 1, L_FIX
}, // "sprmCFFldVanish" chp.fFldVanish 1 or 0 bit
170 { 57, 0, L_VAR
}, // "sprmCDefault" whole CHP
171 { 58, 0, L_FIX
}, // "sprmCPlain" whole CHP
172 { 60, 1, L_FIX
}, // "sprmCFBold" chp.fBold 0,1, 128, or 129
173 { 61, 1, L_FIX
}, // "sprmCFItalic" chp.fItalic 0,1, 128, or 129
174 { 62, 1, L_FIX
}, // "sprmCFStrike" chp.fStrike 0,1, 128, or 129
175 { 63, 1, L_FIX
}, // "sprmCFOutline" chp.fOutline 0,1, 128, or 129
176 { 64, 1, L_FIX
}, // "sprmCFShadow" chp.fShadow 0,1, 128, or 129
177 { 65, 1, L_FIX
}, // "sprmCFSmallCaps" chp.fSmallCaps 0,1, 128, or 129
178 { 66, 1, L_FIX
}, // "sprmCFCaps" chp.fCaps 0,1, 128, or 129
179 { 67, 1, L_FIX
}, // "sprmCFVanish" chp.fVanish 0,1, 128, or 129
180 { 68, 2, L_FIX
}, // "sprmCFtc" chp.ftc ftc word
181 { 69, 1, L_FIX
}, // "sprmCKul" chp.kul kul byte
182 { 70, 3, L_FIX
}, // "sprmCSizePos" chp.hps, chp.hpsPos
183 { 71, 2, L_FIX
}, // "sprmCDxaSpace" chp.dxaSpace dxa
184 { 72, 2, L_FIX
}, // "sprmCLid" chp.lid LID
185 { 73, 1, L_FIX
}, // "sprmCIco" chp.ico ico byte
186 { 74, 1, L_FIX
}, // "sprmCHps" chp.hps hps !word!
187 { 75, 1, L_FIX
}, // "sprmCHpsInc" chp.hps
188 { 76, 1, L_FIX
}, // "sprmCHpsPos" chp.hpsPos hps !word!
189 { 77, 1, L_FIX
}, // "sprmCHpsPosAdj" chp.hpsPos hps
190 { 78, 0, L_VAR
}, // "?sprmCMajority" chp.fBold, chp.fItalic, ...
191 { 80, 1, L_FIX
}, // "sprmCFBoldBi" chp.fBoldBi
192 { 81, 1, L_FIX
}, // "sprmCFItalicBi" chp.fItalicBi
193 { 82, 2, L_FIX
}, // "sprmCFtcBi" chp.ftcBi
194 { 83, 2, L_FIX
}, // "sprmClidBi" chp.lidBi
195 { 84, 1, L_FIX
}, // "sprmCIcoBi" chp.icoBi
196 { 85, 1, L_FIX
}, // "sprmCHpsBi" chp.hpsBi
197 { 86, 1, L_FIX
}, // "sprmCFBiDi" chp.fBiDi
198 { 87, 1, L_FIX
}, // "sprmCFDiacColor" chp.fDiacUSico
199 { 94, 1, L_FIX
}, // "sprmPicBrcl" pic.brcl brcl (see PIC definition)
200 { 95,12, L_VAR
}, // "sprmPicScale" pic.mx, pic.my, pic.dxaCropleft,
201 { 96, 2, L_FIX
}, // "sprmPicBrcTop" pic.brcTop BRC word
202 { 97, 2, L_FIX
}, // "sprmPicBrcLeft" pic.brcLeft BRC word
203 { 98, 2, L_FIX
}, // "sprmPicBrcBottom" pic.brcBottom BRC word
204 { 99, 2, L_FIX
}, // "sprmPicBrcRight" pic.brcRight BRC word
205 {112, 1, L_FIX
}, // "sprmSFRTLGutter", set to one if gutter is on
206 {114, 1, L_FIX
}, // "sprmSFBiDi" ;;;
207 {115, 2, L_FIX
}, // "sprmSDmBinFirst" sep.dmBinFirst word
208 {116, 2, L_FIX
}, // "sprmSDmBinOther" sep.dmBinOther word
209 {117, 1, L_FIX
}, // "sprmSBkc" sep.bkc bkc byte
210 {118, 1, L_FIX
}, // "sprmSFTitlePage" sep.fTitlePage 0 or 1 byte
211 {119, 2, L_FIX
}, // "sprmSCcolumns" sep.ccolM1 # of cols - 1 word
212 {120, 2, L_FIX
}, // "sprmSDxaColumns" sep.dxaColumns dxa word
213 {121, 1, L_FIX
}, // "sprmSFAutoPgn" sep.fAutoPgn obsolete byte
214 {122, 1, L_FIX
}, // "sprmSNfcPgn" sep.nfcPgn nfc byte
215 {123, 2, L_FIX
}, // "sprmSDyaPgn" sep.dyaPgn dya short
216 {124, 2, L_FIX
}, // "sprmSDxaPgn" sep.dxaPgn dya short
217 {125, 1, L_FIX
}, // "sprmSFPgnRestart" sep.fPgnRestart 0 or 1 byte
218 {126, 1, L_FIX
}, // "sprmSFEndnote" sep.fEndnote 0 or 1 byte
219 {127, 1, L_FIX
}, // "sprmSLnc" sep.lnc lnc byte
220 {128, 1, L_FIX
}, // "sprmSGprfIhdt" sep.grpfIhdt grpfihdt
221 {129, 2, L_FIX
}, // "sprmSNLnnMod" sep.nLnnMod non-neg int. word
222 {130, 2, L_FIX
}, // "sprmSDxaLnn" sep.dxaLnn dxa word
223 {131, 2, L_FIX
}, // "sprmSDyaHdrTop" sep.dyaHdrTop dya word
224 {132, 2, L_FIX
}, // "sprmSDyaHdrBottom" sep.dyaHdrBottom dya word
225 {133, 1, L_FIX
}, // "sprmSLBetween" sep.fLBetween 0 or 1 byte
226 {134, 1, L_FIX
}, // "sprmSVjc" sep.vjc vjc byte
227 {135, 2, L_FIX
}, // "sprmSLnnMin" sep.lnnMin lnn word
228 {136, 2, L_FIX
}, // "sprmSPgnStart" sep.pgnStart pgn word
229 {137, 1, L_FIX
}, // "sprmSBOrientation" sep.dmOrientPage dm byte
230 {138, 1, L_FIX
}, // "sprmSFFacingCol" ;;;
231 {139, 2, L_FIX
}, // "sprmSXaPage" sep.xaPage xa word
232 {140, 2, L_FIX
}, // "sprmSYaPage" sep.yaPage ya word
233 {141, 2, L_FIX
}, // "sprmSDxaLeft" sep.dxaLeft dxa word
234 {142, 2, L_FIX
}, // "sprmSDxaRight" sep.dxaRight dxa word
235 {143, 2, L_FIX
}, // "sprmSDyaTop" sep.dyaTop dya word
236 {144, 2, L_FIX
}, // "sprmSDyaBottom" sep.dyaBottom dya word
237 {145, 2, L_FIX
}, // "sprmSDzaGutter" sep.dzaGutter dza word
238 {146, 2, L_FIX
}, // "sprmTJc" tap.jc jc (low order byte is significant)
239 {147, 2, L_FIX
}, // "sprmTDxaLeft" tap.rgdxaCenter dxa word
240 {148, 2, L_FIX
}, // "sprmTDxaGapHalf" tap.dxaGapHalf, tap.rgdxaCenter
241 {149, 1, L_FIX
}, // "sprmTFBiDi" ;;;
242 {152, 0, L_VAR
}, // "sprmTDefTable10" tap.rgdxaCenter, tap.rgtc complex
243 {153, 2, L_FIX
}, // "sprmTDyaRowHeight" tap.dyaRowHeight dya word
244 {154, 0, L_VAR2
},// "sprmTDefTable" tap.rgtc complex
245 {155, 1, L_VAR
}, // "sprmTDefTableShd" tap.rgshd complex
246 {157, 5, L_FIX
}, // "sprmTSetBrc" tap.rgtc[].rgbrc complex 5 bytes
247 {158, 4, L_FIX
}, // "sprmTInsert" tap.rgdxaCenter,tap.rgtc complex
248 {159, 2, L_FIX
}, // "sprmTDelete" tap.rgdxaCenter, tap.rgtc complex
249 {160, 4, L_FIX
}, // "sprmTDxaCol" tap.rgdxaCenter complex
250 {161, 2, L_FIX
}, // "sprmTMerge" tap.fFirstMerged, tap.fMerged complex
251 {162, 2, L_FIX
}, // "sprmTSplit" tap.fFirstMerged, tap.fMerged complex
252 {163, 5, L_FIX
}, // "sprmTSetBrc10" tap.rgtc[].rgbrc complex 5 bytes
253 {164, 4, L_FIX
}, // "sprmTSetShd", tap.rgshd complex 4 bytes
256 static wwSprmSearcher
aSprmSrch(aSprms
, sizeof(aSprms
) / sizeof(aSprms
[0]));
261 const wwSprmSearcher
*wwSprmParser::GetWW6SprmSearcher()
265 static const SprmInfo aSprms
[] =
267 { 0, 0, L_FIX
}, // "Default-sprm", wird uebersprungen
268 { 2, 2, L_FIX
}, // "sprmPIstd", pap.istd (style code)
269 { 3, 3, L_VAR
}, // "sprmPIstdPermute pap.istd permutation
270 { 4, 1, L_FIX
}, // "sprmPIncLv1" pap.istddifference
271 { 5, 1, L_FIX
}, // "sprmPJc" pap.jc (justification)
272 { 6, 1, L_FIX
}, // "sprmPFSideBySide" pap.fSideBySide
273 { 7, 1, L_FIX
}, // "sprmPFKeep" pap.fKeep
274 { 8, 1, L_FIX
}, // "sprmPFKeepFollow " pap.fKeepFollow
275 { 9, 1, L_FIX
}, // "sprmPPageBreakBefore" pap.fPageBreakBefore
276 { 10, 1, L_FIX
}, // "sprmPBrcl" pap.brcl
277 { 11, 1, L_FIX
}, // "sprmPBrcp" pap.brcp
278 { 12, 0, L_VAR
}, // "sprmPAnld" pap.anld (ANLD structure)
279 { 13, 1, L_FIX
}, // "sprmPNLvlAnm" pap.nLvlAnm nn
280 { 14, 1, L_FIX
}, // "sprmPFNoLineNumb" pap.fNoLnn
281 { 15, 0, L_VAR
}, // "?sprmPChgTabsPapx" pap.itbdMac, ...
282 { 16, 2, L_FIX
}, // "sprmPDxaRight" pap.dxaRight
283 { 17, 2, L_FIX
}, // "sprmPDxaLeft" pap.dxaLeft
284 { 18, 2, L_FIX
}, // "sprmPNest" pap.dxaLeft
285 { 19, 2, L_FIX
}, // "sprmPDxaLeft1" pap.dxaLeft1
286 { 20, 4, L_FIX
}, // "sprmPDyaLine" pap.lspd an LSPD
287 { 21, 2, L_FIX
}, // "sprmPDyaBefore" pap.dyaBefore
288 { 22, 2, L_FIX
}, // "sprmPDyaAfter" pap.dyaAfter
289 { 23, 0, L_VAR
}, // "?sprmPChgTabs" pap.itbdMac, pap.rgdxaTab, ...
290 { 24, 1, L_FIX
}, // "sprmPFInTable" pap.fInTable
291 { 25, 1, L_FIX
}, // "sprmPTtp" pap.fTtp
292 { 26, 2, L_FIX
}, // "sprmPDxaAbs" pap.dxaAbs
293 { 27, 2, L_FIX
}, // "sprmPDyaAbs" pap.dyaAbs
294 { 28, 2, L_FIX
}, // "sprmPDxaWidth" pap.dxaWidth
295 { 29, 1, L_FIX
}, // "sprmPPc" pap.pcHorz, pap.pcVert
296 { 30, 2, L_FIX
}, // "sprmPBrcTop10" pap.brcTop BRC10
297 { 31, 2, L_FIX
}, // "sprmPBrcLeft10" pap.brcLeft BRC10
298 { 32, 2, L_FIX
}, // "sprmPBrcBottom10" pap.brcBottom BRC10
299 { 33, 2, L_FIX
}, // "sprmPBrcRight10" pap.brcRight BRC10
300 { 34, 2, L_FIX
}, // "sprmPBrcBetween10" pap.brcBetween BRC10
301 { 35, 2, L_FIX
}, // "sprmPBrcBar10" pap.brcBar BRC10
302 { 36, 2, L_FIX
}, // "sprmPFromText10" pap.dxaFromText dxa
303 { 37, 1, L_FIX
}, // "sprmPWr" pap.wr wr
304 { 38, 2, L_FIX
}, // "sprmPBrcTop" pap.brcTop BRC
305 { 39, 2, L_FIX
}, // "sprmPBrcLeft" pap.brcLeft BRC
306 { 40, 2, L_FIX
}, // "sprmPBrcBottom" pap.brcBottom BRC
307 { 41, 2, L_FIX
}, // "sprmPBrcRight" pap.brcRight BRC
308 { 42, 2, L_FIX
}, // "sprmPBrcBetween" pap.brcBetween BRC
309 { 43, 2, L_FIX
}, // "sprmPBrcBar" pap.brcBar BRC word
310 { 44, 1, L_FIX
}, // "sprmPFNoAutoHyph" pap.fNoAutoHyph
311 { 45, 2, L_FIX
}, // "sprmPWHeightAbs" pap.wHeightAbs w
312 { 46, 2, L_FIX
}, // "sprmPDcs" pap.dcs DCS
313 { 47, 2, L_FIX
}, // "sprmPShd" pap.shd SHD
314 { 48, 2, L_FIX
}, // "sprmPDyaFromText" pap.dyaFromText dya
315 { 49, 2, L_FIX
}, // "sprmPDxaFromText" pap.dxaFromText dxa
316 { 50, 1, L_FIX
}, // "sprmPFLocked" pap.fLocked 0 or 1 byte
317 { 51, 1, L_FIX
}, // "sprmPFWidowControl" pap.fWidowControl 0 or 1 byte
318 { 52, 0, L_FIX
}, // "?sprmPRuler 52"
319 { 64, 0, L_VAR
}, // rtl property ?
320 { 65, 1, L_FIX
}, // "sprmCFStrikeRM" chp.fRMarkDel 1 or 0 bit
321 { 66, 1, L_FIX
}, // "sprmCFRMark" chp.fRMark 1 or 0 bit
322 { 67, 1, L_FIX
}, // "sprmCFFldVanish" chp.fFldVanish 1 or 0 bit
323 { 68, 0, L_VAR
}, // "sprmCPicLocation" chp.fcPic and chp.fSpec
324 { 69, 2, L_FIX
}, // "sprmCIbstRMark" chp.ibstRMark index into sttbRMark
325 { 70, 4, L_FIX
}, // "sprmCDttmRMark" chp.dttm DTTM long
326 { 71, 1, L_FIX
}, // "sprmCFData" chp.fData 1 or 0 bit
327 { 72, 2, L_FIX
}, // "sprmCRMReason" chp.idslRMReason an index to a table
328 { 73, 3, L_FIX
}, // "sprmCChse" chp.fChsDiff and chp.chse
329 { 74, 0, L_VAR
}, // "sprmCSymbol" chp.fSpec, chp.chSym and chp.ftcSym
330 { 75, 1, L_FIX
}, // "sprmCFOle2" chp.fOle2 1 or 0 bit
331 { 77, 0, L_VAR
}, // unknown
332 { 79, 0, L_VAR
}, // unknown
333 { 80, 2, L_FIX
}, // "sprmCIstd" chp.istd istd, see stylesheet definition
334 { 81, 0, L_VAR
}, // "sprmCIstdPermute" chp.istd permutation vector
335 { 82, 0, L_VAR
}, // "sprmCDefault" whole CHP
336 { 83, 0, L_FIX
}, // "sprmCPlain" whole CHP
337 { 85, 1, L_FIX
}, // "sprmCFBold" chp.fBold 0,1, 128, or 129
338 { 86, 1, L_FIX
}, // "sprmCFItalic" chp.fItalic 0,1, 128, or 129
339 { 87, 1, L_FIX
}, // "sprmCFStrike" chp.fStrike 0,1, 128, or 129
340 { 88, 1, L_FIX
}, // "sprmCFOutline" chp.fOutline 0,1, 128, or 129
341 { 89, 1, L_FIX
}, // "sprmCFShadow" chp.fShadow 0,1, 128, or 129
342 { 90, 1, L_FIX
}, // "sprmCFSmallCaps" chp.fSmallCaps 0,1, 128, or 129
343 { 91, 1, L_FIX
}, // "sprmCFCaps" chp.fCaps 0,1, 128, or 129
344 { 92, 1, L_FIX
}, // "sprmCFVanish" chp.fVanish 0,1, 128, or 129
345 { 93, 2, L_FIX
}, // "sprmCFtc" chp.ftc ftc word
346 { 94, 1, L_FIX
}, // "sprmCKul" chp.kul kul byte
347 { 95, 3, L_FIX
}, // "sprmCSizePos" chp.hps, chp.hpsPos
348 { 96, 2, L_FIX
}, // "sprmCDxaSpace" chp.dxaSpace dxa
349 { 97, 2, L_FIX
}, // "sprmCLid" chp.lid LID
350 { 98, 1, L_FIX
}, // "sprmCIco" chp.ico ico byte
351 { 99, 2, L_FIX
}, // "sprmCHps" chp.hps hps !word!
352 {100, 1, L_FIX
}, // "sprmCHpsInc" chp.hps
353 {101, 2, L_FIX
}, // "sprmCHpsPos" chp.hpsPos hps !word!
354 {102, 1, L_FIX
}, // "sprmCHpsPosAdj" chp.hpsPos hps
355 {103, 0, L_VAR
}, // "?sprmCMajority" chp.fBold, chp.fItalic, ...
356 {104, 1, L_FIX
}, // "sprmCIss" chp.iss iss
357 {105, 0, L_VAR
}, // "sprmCHpsNew50" chp.hps hps variable width
358 {106, 0, L_VAR
}, // "sprmCHpsInc1" chp.hps complex
359 {107, 2, L_FIX
}, // "sprmCHpsKern" chp.hpsKern hps
360 {108, 0, L_VAR
}, // "sprmCMajority50" chp.fBold, chp.fItalic, ...
361 {109, 2, L_FIX
}, // "sprmCHpsMul" chp.hps percentage to grow hps
362 {110, 2, L_FIX
}, // "sprmCCondHyhen" chp.ysri ysri
363 {111, 2, L_FIX
}, // rtl bold
364 {112, 2, L_FIX
}, // rtl italic
365 {113, 0, L_VAR
}, // rtl property ?
366 {115, 0, L_VAR
}, // rtl property ?
367 {116, 0, L_VAR
}, // unknown
368 {117, 1, L_FIX
}, // "sprmCFSpec" chp.fSpec 1 or 0 bit
369 {118, 1, L_FIX
}, // "sprmCFObj" chp.fObj 1 or 0 bit
370 {119, 1, L_FIX
}, // "sprmPicBrcl" pic.brcl brcl (see PIC definition)
371 {120,12, L_VAR
}, // "sprmPicScale" pic.mx, pic.my, pic.dxaCropleft,
372 {121, 2, L_FIX
}, // "sprmPicBrcTop" pic.brcTop BRC word
373 {122, 2, L_FIX
}, // "sprmPicBrcLeft" pic.brcLeft BRC word
374 {123, 2, L_FIX
}, // "sprmPicBrcBottom" pic.brcBottom BRC word
375 {124, 2, L_FIX
}, // "sprmPicBrcRight" pic.brcRight BRC word
376 {131, 1, L_FIX
}, // "sprmSScnsPgn" sep.cnsPgn cns byte
377 {132, 1, L_FIX
}, // "sprmSiHeadingPgn" sep.iHeadingPgn
378 {133, 0, L_VAR
}, // "sprmSOlstAnm" sep.olstAnm OLST variable length
379 {136, 3, L_FIX
}, // "sprmSDxaColWidth" sep.rgdxaColWidthSpacing complex
380 {137, 3, L_FIX
}, // "sprmSDxaColSpacing" sep.rgdxaColWidthSpacing
381 {138, 1, L_FIX
}, // "sprmSFEvenlySpaced" sep.fEvenlySpaced 1 or 0
382 {139, 1, L_FIX
}, // "sprmSFProtected" sep.fUnlocked 1 or 0 byte
383 {140, 2, L_FIX
}, // "sprmSDmBinFirst" sep.dmBinFirst word
384 {141, 2, L_FIX
}, // "sprmSDmBinOther" sep.dmBinOther word
385 {142, 1, L_FIX
}, // "sprmSBkc" sep.bkc bkc byte
386 {143, 1, L_FIX
}, // "sprmSFTitlePage" sep.fTitlePage 0 or 1 byte
387 {144, 2, L_FIX
}, // "sprmSCcolumns" sep.ccolM1 # of cols - 1 word
388 {145, 2, L_FIX
}, // "sprmSDxaColumns" sep.dxaColumns dxa word
389 {146, 1, L_FIX
}, // "sprmSFAutoPgn" sep.fAutoPgn obsolete byte
390 {147, 1, L_FIX
}, // "sprmSNfcPgn" sep.nfcPgn nfc byte
391 {148, 2, L_FIX
}, // "sprmSDyaPgn" sep.dyaPgn dya short
392 {149, 2, L_FIX
}, // "sprmSDxaPgn" sep.dxaPgn dya short
393 {150, 1, L_FIX
}, // "sprmSFPgnRestart" sep.fPgnRestart 0 or 1 byte
394 {151, 1, L_FIX
}, // "sprmSFEndnote" sep.fEndnote 0 or 1 byte
395 {152, 1, L_FIX
}, // "sprmSLnc" sep.lnc lnc byte
396 {153, 1, L_FIX
}, // "sprmSGprfIhdt" sep.grpfIhdt grpfihdt
397 {154, 2, L_FIX
}, // "sprmSNLnnMod" sep.nLnnMod non-neg int. word
398 {155, 2, L_FIX
}, // "sprmSDxaLnn" sep.dxaLnn dxa word
399 {156, 2, L_FIX
}, // "sprmSDyaHdrTop" sep.dyaHdrTop dya word
400 {157, 2, L_FIX
}, // "sprmSDyaHdrBottom" sep.dyaHdrBottom dya word
401 {158, 1, L_FIX
}, // "sprmSLBetween" sep.fLBetween 0 or 1 byte
402 {159, 1, L_FIX
}, // "sprmSVjc" sep.vjc vjc byte
403 {160, 2, L_FIX
}, // "sprmSLnnMin" sep.lnnMin lnn word
404 {161, 2, L_FIX
}, // "sprmSPgnStart" sep.pgnStart pgn word
405 {162, 1, L_FIX
}, // "sprmSBOrientation" sep.dmOrientPage dm byte
406 {163, 0, L_FIX
}, // "?SprmSBCustomize 163"
407 {164, 2, L_FIX
}, // "sprmSXaPage" sep.xaPage xa word
408 {165, 2, L_FIX
}, // "sprmSYaPage" sep.yaPage ya word
409 {166, 2, L_FIX
}, // "sprmSDxaLeft" sep.dxaLeft dxa word
410 {167, 2, L_FIX
}, // "sprmSDxaRight" sep.dxaRight dxa word
411 {168, 2, L_FIX
}, // "sprmSDyaTop" sep.dyaTop dya word
412 {169, 2, L_FIX
}, // "sprmSDyaBottom" sep.dyaBottom dya word
413 {170, 2, L_FIX
}, // "sprmSDzaGutter" sep.dzaGutter dza word
414 {171, 2, L_FIX
}, // "sprmSDMPaperReq" sep.dmPaperReq dm word
415 {179, 0, L_VAR
}, // rtl property ?
416 {181, 0, L_VAR
}, // rtl property ?
417 {182, 2, L_FIX
}, // "sprmTJc" tap.jc jc (low order byte is significant)
418 {183, 2, L_FIX
}, // "sprmTDxaLeft" tap.rgdxaCenter dxa word
419 {184, 2, L_FIX
}, // "sprmTDxaGapHalf" tap.dxaGapHalf, tap.rgdxaCenter
420 {185, 1, L_FIX
}, // "sprmTFCantSplit" tap.fCantSplit 1 or 0 byte
421 {186, 1, L_FIX
}, // "sprmTTableHeader" tap.fTableHeader 1 or 0 byte
422 {187,12, L_FIX
}, // "sprmTTableBorders" tap.rgbrcTable complex 12 bytes
423 {188, 0, L_VAR
}, // "sprmTDefTable10" tap.rgdxaCenter, tap.rgtc complex
424 {189, 2, L_FIX
}, // "sprmTDyaRowHeight" tap.dyaRowHeight dya word
425 {190, 0, L_VAR2
},// "sprmTDefTable" tap.rgtc complex
426 {191, 1, L_VAR
}, // "sprmTDefTableShd" tap.rgshd complex
427 {192, 4, L_FIX
}, // "sprmTTlp" tap.tlp TLP 4 bytes
428 {193, 5, L_FIX
}, // "sprmTSetBrc" tap.rgtc[].rgbrc complex 5 bytes
429 {194, 4, L_FIX
}, // "sprmTInsert" tap.rgdxaCenter,tap.rgtc complex
430 {195, 2, L_FIX
}, // "sprmTDelete" tap.rgdxaCenter, tap.rgtc complex
431 {196, 4, L_FIX
}, // "sprmTDxaCol" tap.rgdxaCenter complex
432 {197, 2, L_FIX
}, // "sprmTMerge" tap.fFirstMerged, tap.fMerged complex
433 {198, 2, L_FIX
}, // "sprmTSplit" tap.fFirstMerged, tap.fMerged complex
434 {199, 5, L_FIX
}, // "sprmTSetBrc10" tap.rgtc[].rgbrc complex 5 bytes
435 {200, 4, L_FIX
}, // "sprmTSetShd", tap.rgshd complex 4 bytes
436 {207, 0, L_VAR
} // rtl property ?
439 static wwSprmSearcher
aSprmSrch(aSprms
, sizeof(aSprms
) / sizeof(aSprms
[0]));
443 const wwSprmSearcher
*wwSprmParser::GetWW8SprmSearcher()
447 static const SprmInfo aSprms
[] =
449 { 0, 0, L_FIX
}, // "Default-sprm"/ wird uebersprungen
450 {0x4600, 2, L_FIX
}, // "sprmPIstd" pap.istd;istd (style code);short;
451 {0xC601, 0, L_VAR
}, // "sprmPIstdPermute" pap.istd;permutation vector
452 {0x2602, 1, L_FIX
}, // "sprmPIncLvl" pap.istd, pap.lvl;difference
453 // between istd of base PAP and istd of PAP to be
455 {0x2403, 1, L_FIX
}, // "sprmPJc" pap.jc;jc (justification);byte;
456 {0x2404, 1, L_FIX
}, // "sprmPFSideBySide" pap.fSideBySide;0 or 1;byte;
457 {0x2405, 1, L_FIX
}, // "sprmPFKeep" pap.fKeep;0 or 1;byte;
458 {0x2406, 1, L_FIX
}, // "sprmPFKeepFollow" pap.fKeepFollow;0 or 1;byte;
459 {0x2407, 1, L_FIX
}, // "sprmPFPageBreakBefore" pap.fPageBreakBefore;
461 {0x2408, 1, L_FIX
}, // "sprmPBrcl" pap.brcl;brcl;byte;
462 {0x2409, 1, L_FIX
}, // "sprmPBrcp" pap.brcp;brcp;byte;
463 {0x260A, 1, L_FIX
}, // "sprmPIlvl" pap.ilvl;ilvl;byte;
464 {0x460B, 2, L_FIX
}, // "sprmPIlfo" pap.ilfo;ilfo (list index) ;short;
465 {0x240C, 1, L_FIX
}, // "sprmPFNoLineNumb" pap.fNoLnn;0 or 1;byte;
466 {0xC60D, 0, L_VAR
}, // "sprmPChgTabsPapx" pap.itbdMac, pap.rgdxaTab,
468 {0x840E, 2, L_FIX
}, // "sprmPDxaRight" pap.dxaRight;dxa;word;
469 {0x840F, 2, L_FIX
}, // "sprmPDxaLeft" pap.dxaLeft;dxa;word;
470 {0x4610, 2, L_FIX
}, // "sprmPNest" pap.dxaLeft;dxa
471 {0x8411, 2, L_FIX
}, // "sprmPDxaLeft1" pap.dxaLeft1;dxa;word;
472 {0x6412, 4, L_FIX
}, // "sprmPDyaLine" pap.lspd;an LSPD, a long word
473 // structure consisting of a short of dyaLine
474 // followed by a short of fMultLinespace
475 {0xA413, 2, L_FIX
}, // "sprmPDyaBefore" pap.dyaBefore;dya;word;
476 {0xA414, 2, L_FIX
}, // "sprmPDyaAfter" pap.dyaAfter;dya;word;
477 {0xC615, 0, L_VAR
}, // "sprmPChgTabs" pap.itbdMac, pap.rgdxaTab,
479 {0x2416, 1, L_FIX
}, // "sprmPFInTable" pap.fInTable;0 or 1;byte;
480 {0x2417, 1, L_FIX
}, // "sprmPFTtp" pap.fTtp;0 or 1;byte;
481 {0x8418, 2, L_FIX
}, // "sprmPDxaAbs" pap.dxaAbs;dxa;word;
482 {0x8419, 2, L_FIX
}, // "sprmPDyaAbs" pap.dyaAbs;dya;word;
483 {0x841A, 2, L_FIX
}, // "sprmPDxaWidth" pap.dxaWidth;dxa;word;
484 {0x261B, 1, L_FIX
}, // "sprmPPc" pap.pcHorz, pap.pcVert;complex
485 {0x461C, 2, L_FIX
}, // "sprmPBrcTop10" pap.brcTop;BRC10;word;
486 {0x461D, 2, L_FIX
}, // "sprmPBrcLeft10" pap.brcLeft;BRC10;word;
487 {0x461E, 2, L_FIX
}, // "sprmPBrcBottom10" pap.brcBottom;BRC10;word;
488 {0x461F, 2, L_FIX
}, // "sprmPBrcRight10" pap.brcRight;BRC10;word;
489 {0x4620, 2, L_FIX
}, // "sprmPBrcBetween10" pap.brcBetween;BRC10;word;
490 {0x4621, 2, L_FIX
}, // "sprmPBrcBar10" pap.brcBar;BRC10;word;
491 {0x4622, 2, L_FIX
}, // "sprmPDxaFromText10" pap.dxaFromText;dxa;word;
492 {0x2423, 1, L_FIX
}, // "sprmPWr" pap.wr;wr
493 {0x6424, 4, L_FIX
}, // "sprmPBrcTop" pap.brcTop;BRC;long;
494 {0x6425, 4, L_FIX
}, // "sprmPBrcLeft" pap.brcLeft;BRC;long;
495 {0x6426, 4, L_FIX
}, // "sprmPBrcBottom" pap.brcBottom;BRC;long;
496 {0x6427, 4, L_FIX
}, // "sprmPBrcRight" pap.brcRight;BRC;long;
497 {0x6428, 4, L_FIX
}, // "sprmPBrcBetween" pap.brcBetween;BRC;long;
498 {0x6629, 4, L_FIX
}, // "sprmPBrcBar" pap.brcBar;BRC;long;
499 {0x242A, 1, L_FIX
}, // "sprmPFNoAutoHyph" pap.fNoAutoHyph;0 or 1;byte;
500 {0x442B, 2, L_FIX
}, // "sprmPWHeightAbs" pap.wHeightAbs;w;word;
501 {0x442C, 2, L_FIX
}, // "sprmPDcs" pap.dcs;DCS;short;
502 {0x442D, 2, L_FIX
}, // "sprmPShd" pap.shd;SHD;word;
503 {0x842E, 2, L_FIX
}, // "sprmPDyaFromText" pap.dyaFromText;dya;word;
504 {0x842F, 2, L_FIX
}, // "sprmPDxaFromText" pap.dxaFromText;dxa;word;
505 {0x2430, 1, L_FIX
}, // "sprmPFLocked" pap.fLocked;0 or 1;byte;
506 {0x2431, 1, L_FIX
}, // "sprmPFWidowControl" pap.fWidowControl;0 or 1
507 {0xC632, 0, L_VAR
}, // "sprmPRuler" ;;variable length;
508 {0x2433, 1, L_FIX
}, // "sprmPFKinsoku" pap.fKinsoku;0 or 1;byte;
509 {0x2434, 1, L_FIX
}, // "sprmPFWordWrap" pap.fWordWrap;0 or 1;byte;
510 {0x2435, 1, L_FIX
}, // "sprmPFOverflowPunct" pap.fOverflowPunct;0 or 1
511 {0x2436, 1, L_FIX
}, // "sprmPFTopLinePunct" pap.fTopLinePunct;0 or 1
512 {0x2437, 1, L_FIX
}, // "sprmPFAutoSpaceDE" pap.fAutoSpaceDE;0 or 1
513 {0x2438, 1, L_FIX
}, // "sprmPFAutoSpaceDN" pap.fAutoSpaceDN;0 or 1
514 {0x4439, 2, L_FIX
}, // "sprmPWAlignFont" pap.wAlignFont;iFa
515 {0x443A, 2, L_FIX
}, // "sprmPFrameTextFlow" pap.fVertical pap.fBackward
516 // pap.fRotateFont;complex
517 {0x243B, 1, L_FIX
}, // "sprmPISnapBaseLine" obsolete: not applicable in
518 // Word97 and later versions;
519 {0xC63E, 0, L_VAR
}, // "sprmPAnld" pap.anld;;variable length;
520 {0xC63F, 0, L_VAR
}, // "sprmPPropRMark" pap.fPropRMark;complex
521 {0x2640, 1, L_FIX
}, // "sprmPOutLvl" pap.lvl;has no effect if pap.istd
523 {0x2441, 1, L_FIX
}, // "sprmPFBiDi" ;;byte;
524 {0x2443, 1, L_FIX
}, // "sprmPFNumRMIns" pap.fNumRMIns;1 or 0;bit;
525 {0x2444, 1, L_FIX
}, // "sprmPCrLf" ;;byte;
526 {0xC645, 0, L_VAR
}, // "sprmPNumRM" pap.numrm;;variable length;
527 {0x6645, 4, L_FIX
}, // "sprmPHugePapx" fc in the data stream to locate
529 {0x6646, 4, L_FIX
}, // "sprmPHugePapx" fc in the data stream to locate
531 {0x2447, 1, L_FIX
}, // "sprmPFUsePgsuSettings" pap.fUsePgsuSettings;
533 {0x2448, 1, L_FIX
}, // "sprmPFAdjustRight" pap.fAdjustRight;1 or 0;byte;
534 {0x0800, 1, L_FIX
}, // "sprmCFRMarkDel" chp.fRMarkDel;1 or 0;bit;
535 {0x0801, 1, L_FIX
}, // "sprmCFRMark" chp.fRMark;1 or 0;bit;
536 {0x0802, 1, L_FIX
}, // "sprmCFFldVanish" chp.fFldVanish;1 or 0;bit;
537 {0x6A03, 4, L_FIX
}, // "sprmCPicLocation" chp.fcPic and chp.fSpec;
538 {0x4804, 2, L_FIX
}, // "sprmCIbstRMark" chp.ibstRMark;index into
540 {0x6805, 4, L_FIX
}, // "sprmCDttmRMark" chp.dttmRMark;DTTM;long;
541 {0x0806, 1, L_FIX
}, // "sprmCFData" chp.fData;1 or 0;bit;
542 {0x4807, 2, L_FIX
}, // "sprmCIdslRMark" chp.idslRMReason;an index to a
543 // table of strings defined in Word 6.0
544 // executables;short;
545 {0xEA08, 1, L_FIX
}, // "sprmCChs" chp.fChsDiff and chp.chse;
546 {0x6A09, 4, L_FIX
}, // "sprmCSymbol" chp.fSpec, chp.xchSym and
548 {0x080A, 1, L_FIX
}, // "sprmCFOle2" chp.fOle2;1 or 0;bit;
549 {0x480B, 0, L_FIX
}, // "sprmCIdCharType" obsolete: not applicable in
550 // Word97 and later versions;;;
551 {0x2A0C, 1, L_FIX
}, // "sprmCHighlight" chp.fHighlight,
552 // chp.icoHighlight;ico (fHighlight is set to 1 iff
554 {0x680E, 4, L_FIX
}, // "sprmCObjLocation" chp.fcObj;FC;long;
555 {0x2A10, 0, L_FIX
}, // "sprmCFFtcAsciSymb" ;;;
556 {0x4A30, 2, L_FIX
}, // "sprmCIstd" chp.istd;istd, see stylesheet def
557 {0xCA31, 0, L_VAR
}, // "sprmCIstdPermute" chp.istd;permutation vector
558 {0x2A32, 0, L_VAR
}, // "sprmCDefault" whole CHP;none;variable length;
559 {0x2A33, 0, L_FIX
}, // "sprmCPlain" whole CHP;none;0;
560 {0x2A34, 1, L_FIX
}, // "sprmCKcd" ;;;
561 {0x0835, 1, L_FIX
}, // "sprmCFBold" chp.fBold;0,1, 128, or 129
562 {0x0836, 1, L_FIX
}, // "sprmCFItalic" chp.fItalic;0,1, 128, or 129
563 {0x0837, 1, L_FIX
}, // "sprmCFStrike" chp.fStrike;0,1, 128, or 129
564 {0x0838, 1, L_FIX
}, // "sprmCFOutline" chp.fOutline;0,1, 128, or 129
565 {0x0839, 1, L_FIX
}, // "sprmCFShadow" chp.fShadow;0,1, 128, or 129
566 {0x083A, 1, L_FIX
}, // "sprmCFSmallCaps" chp.fSmallCaps;0,1, 128, or 129
567 {0x083B, 1, L_FIX
}, // "sprmCFCaps" chp.fCaps;0,1, 128, or 129
568 {0x083C, 1, L_FIX
}, // "sprmCFVanish" chp.fVanish;0,1, 128, or 129
569 {0x4A3D, 2, L_FIX
}, // "sprmCFtcDefault" ;ftc, only used internally
570 {0x2A3E, 1, L_FIX
}, // "sprmCKul" chp.kul;kul;byte;
571 {0xEA3F, 3, L_FIX
}, // "sprmCSizePos" chp.hps, chp.hpsPos;3 bytes;
572 {0x8840, 2, L_FIX
}, // "sprmCDxaSpace" chp.dxaSpace;dxa;word;
573 {0x4A41, 2, L_FIX
}, // "sprmCLid" ;only used internally never stored
574 {0x2A42, 1, L_FIX
}, // "sprmCIco" chp.ico;ico;byte;
575 {0x4A43, 2, L_FIX
}, // "sprmCHps" chp.hps;hps
576 {0x2A44, 1, L_FIX
}, // "sprmCHpsInc" chp.hps;
577 {0x4845, 2, L_FIX
}, // "sprmCHpsPos" chp.hpsPos;hps;short; (doc wrong)
578 {0x2A46, 1, L_FIX
}, // "sprmCHpsPosAdj" chp.hpsPos;hps
579 {0xCA47, 0, L_VAR
}, // "sprmCMajority" chp.fBold, chp.fItalic,
580 // chp.fSmallCaps, chp.fVanish, chp.fStrike,
581 // chp.fCaps, chp.rgftc, chp.hps, chp.hpsPos,
582 // chp.kul, chp.dxaSpace, chp.ico,
583 // chp.rglid;complex;variable length, length byte
584 // plus size of following grpprl;
585 {0x2A48, 1, L_FIX
}, // "sprmCIss" chp.iss;iss;byte;
586 {0xCA49, 0, L_VAR
}, // "sprmCHpsNew50" chp.hps;hps;variable width
587 {0xCA4A, 0, L_VAR
}, // "sprmCHpsInc1" chp.hps;complex
588 {0x484B, 2, L_FIX
}, // "sprmCHpsKern" chp.hpsKern;hps;short;
589 {0xCA4C, 2, L_FIX
}, // "sprmCMajority50" chp.fBold, chp.fItalic,
590 // chp.fSmallCaps, chp.fVanish, chp.fStrike,
591 // chp.fCaps, chp.ftc, chp.hps, chp.hpsPos, chp.kul,
592 // chp.dxaSpace, chp.ico,;complex
593 {0x4A4D, 2, L_FIX
}, // "sprmCHpsMul" chp.hps;percentage to grow hps
594 {0x484E, 2, L_FIX
}, // "sprmCYsri" chp.ysri;ysri;short;
595 {0x4A4F, 2, L_FIX
}, // "sprmCRgFtc0" chp.rgftc[0];ftc for ASCII text
596 {0x4A50, 2, L_FIX
}, // "sprmCRgFtc1" chp.rgftc[1];ftc for Far East text
597 {0x4A51, 2, L_FIX
}, // "sprmCRgFtc2" chp.rgftc[2];ftc for non-FE text
598 {0x4852, 2, L_FIX
}, // "sprmCCharScale"
599 {0x2A53, 1, L_FIX
}, // "sprmCFDStrike" chp.fDStrike;;byte;
600 {0x0854, 1, L_FIX
}, // "sprmCFImprint" chp.fImprint;1 or 0;bit;
601 {0x0855, 1, L_FIX
}, // "sprmCFSpec" chp.fSpec ;1 or 0;bit;
602 {0x0856, 1, L_FIX
}, // "sprmCFObj" chp.fObj;1 or 0;bit;
603 {0xCA57, 0, L_VAR
}, // "sprmCPropRMark" chp.fPropRMark,
604 // chp.ibstPropRMark, chp.dttmPropRMark;Complex
605 {0x0858, 1, L_FIX
}, // "sprmCFEmboss" chp.fEmboss;1 or 0;bit;
606 {0x2859, 1, L_FIX
}, // "sprmCSfxText" chp.sfxtText;text animation;byte;
607 {0x085A, 1, L_FIX
}, // "sprmCFBiDi" ;;;
608 {0x085B, 1, L_FIX
}, // "sprmCFDiacColor" ;;;
609 {0x085C, 1, L_FIX
}, // "sprmCFBoldBi" ;;;
610 {0x085D, 1, L_FIX
}, // "sprmCFItalicBi" ;;;
612 {0x485F, 2, L_FIX
}, // "sprmCLidBi" ;;;
613 {0x4A60, 1, L_FIX
}, // "sprmCIcoBi" ;;;
614 {0x4A61, 2, L_FIX
}, // "sprmCHpsBi" ;;;
615 {0xCA62, 0, L_VAR
}, // "sprmCDispFldRMark" chp.fDispFldRMark,
616 // chp.ibstDispFldRMark, chp.dttmDispFldRMark ;
617 {0x4863, 2, L_FIX
}, // "sprmCIbstRMarkDel" chp.ibstRMarkDel;index into
619 {0x6864, 4, L_FIX
}, // "sprmCDttmRMarkDel" chp.dttmRMarkDel;DTTM;long;
620 {0x6865, 4, L_FIX
}, // "sprmCBrc" chp.brc;BRC;long;
621 {0x4866, 2, L_FIX
}, // "sprmCShd" chp.shd;SHD;short;
622 {0x4867, 2, L_FIX
}, // "sprmCIdslRMarkDel" chp.idslRMReasonDel;an index
623 // to a table of strings defined in Word 6.0
624 // executables;short;
625 {0x0868, 1, L_FIX
}, // "sprmCFUsePgsuSettings"
626 // chp.fUsePgsuSettings;1 or 0
627 {0x486B, 2, L_FIX
}, // "sprmCCpg" ;;word;
628 {0x486D, 2, L_FIX
}, // "sprmCRgLid0_80" chp.rglid[0];LID: for non-FE text
629 {0x486E, 2, L_FIX
}, // "sprmCRgLid1_80" chp.rglid[1];LID: for Far East text
630 {0x286F, 1, L_FIX
}, // "sprmCIdctHint" chp.idctHint;IDCT:
631 {0x2E00, 1, L_FIX
}, // "sprmPicBrcl" pic.brcl;brcl (see PIC definition)
632 {0xCE01, 0, L_VAR
}, // "sprmPicScale" pic.mx, pic.my, pic.dxaCropleft,
633 // pic.dyaCropTop pic.dxaCropRight,
634 // pic.dyaCropBottom;Complex
635 {0x6C02, 4, L_FIX
}, // "sprmPicBrcTop" pic.brcTop;BRC;long;
636 {0x6C03, 4, L_FIX
}, // "sprmPicBrcLeft" pic.brcLeft;BRC;long;
637 {0x6C04, 4, L_FIX
}, // "sprmPicBrcBottom" pic.brcBottom;BRC;long;
638 {0x6C05, 4, L_FIX
}, // "sprmPicBrcRight" pic.brcRight;BRC;long;
639 {0x3000, 1, L_FIX
}, // "sprmScnsPgn" sep.cnsPgn;cns;byte;
640 {0x3001, 1, L_FIX
}, // "sprmSiHeadingPgn" sep.iHeadingPgn;heading number
642 {0xD202, 0, L_VAR
}, // "sprmSOlstAnm" sep.olstAnm;OLST;variable length;
643 {0xF203, 3, L_FIX
}, // "sprmSDxaColWidth" sep.rgdxaColWidthSpacing;
644 {0xF204, 3, L_FIX
}, // "sprmSDxaColSpacing" sep.rgdxaColWidthSpacing;
646 {0x3005, 1, L_FIX
}, // "sprmSFEvenlySpaced" sep.fEvenlySpaced;1 or 0
647 {0x3006, 1, L_FIX
}, // "sprmSFProtected" sep.fUnlocked;1 or 0;byte;
648 {0x5007, 2, L_FIX
}, // "sprmSDmBinFirst" sep.dmBinFirst;;word;
649 {0x5008, 2, L_FIX
}, // "sprmSDmBinOther" sep.dmBinOther;;word;
650 {0x3009, 1, L_FIX
}, // "sprmSBkc" sep.bkc;bkc;byte;
651 {0x300A, 1, L_FIX
}, // "sprmSFTitlePage" sep.fTitlePage;0 or 1;byte;
652 {0x500B, 2, L_FIX
}, // "sprmSCcolumns" sep.ccolM1;# of cols - 1;word;
653 {0x900C, 2, L_FIX
}, // "sprmSDxaColumns" sep.dxaColumns;dxa;word;
654 {0x300D, 1, L_FIX
}, // "sprmSFAutoPgn" sep.fAutoPgn;obsolete;byte;
655 {0x300E, 1, L_FIX
}, // "sprmSNfcPgn" sep.nfcPgn;nfc;byte;
656 {0xB00F, 2, L_FIX
}, // "sprmSDyaPgn" sep.dyaPgn;dya;short;
657 {0xB010, 2, L_FIX
}, // "sprmSDxaPgn" sep.dxaPgn;dya;short;
658 {0x3011, 1, L_FIX
}, // "sprmSFPgnRestart" sep.fPgnRestart;0 or 1;byte;
659 {0x3012, 1, L_FIX
}, // "sprmSFEndnote" sep.fEndnote;0 or 1;byte;
660 {0x3013, 1, L_FIX
}, // "sprmSLnc" sep.lnc;lnc;byte;
661 {0x3014, 1, L_FIX
}, // "sprmSGprfIhdt" sep.grpfIhdt;grpfihdt
662 {0x5015, 2, L_FIX
}, // "sprmSNLnnMod" sep.nLnnMod;non-neg int.;word;
663 {0x9016, 2, L_FIX
}, // "sprmSDxaLnn" sep.dxaLnn;dxa;word;
664 {0xB017, 2, L_FIX
}, // "sprmSDyaHdrTop" sep.dyaHdrTop;dya;word;
665 {0xB018, 2, L_FIX
}, // "sprmSDyaHdrBottom" sep.dyaHdrBottom;dya;word;
666 {0x3019, 1, L_FIX
}, // "sprmSLBetween" sep.fLBetween;0 or 1;byte;
667 {0x301A, 1, L_FIX
}, // "sprmSVjc" sep.vjc;vjc;byte;
668 {0x501B, 2, L_FIX
}, // "sprmSLnnMin" sep.lnnMin;lnn;word;
669 {0x501C, 2, L_FIX
}, // "sprmSPgnStart" sep.pgnStart;pgn;word;
670 {0x301D, 1, L_FIX
}, // "sprmSBOrientation" sep.dmOrientPage;dm;byte;
671 {0x301E, 1, L_FIX
}, // "sprmSBCustomize" ;;;
672 {0xB01F, 2, L_FIX
}, // "sprmSXaPage" sep.xaPage;xa;word;
673 {0xB020, 2, L_FIX
}, // "sprmSYaPage" sep.yaPage;ya;word;
674 {0xB021, 2, L_FIX
}, // "sprmSDxaLeft" sep.dxaLeft;dxa;word;
675 {0xB022, 2, L_FIX
}, // "sprmSDxaRight" sep.dxaRight;dxa;word;
676 {0x9023, 2, L_FIX
}, // "sprmSDyaTop" sep.dyaTop;dya;word;
677 {0x9024, 2, L_FIX
}, // "sprmSDyaBottom" sep.dyaBottom;dya;word;
678 {0xB025, 2, L_FIX
}, // "sprmSDzaGutter" sep.dzaGutter;dza;word;
679 {0x5026, 2, L_FIX
}, // "sprmSDmPaperReq" sep.dmPaperReq;dm;word;
680 {0xD227, 0, L_VAR
}, // "sprmSPropRMark" sep.fPropRMark,
681 // sep.ibstPropRMark, sep.dttmPropRMark ;complex
682 {0x3228, 1, L_FIX
}, // "sprmSFBiDi" ;;;
683 {0x3229, 1, L_FIX
}, // "sprmSFFacingCol" ;;;
684 {0x322A, 1, L_FIX
}, // "sprmSFRTLGutter", set to one if gutter is on
686 {0x702B, 4, L_FIX
}, // "sprmSBrcTop" sep.brcTop;BRC;long;
687 {0x702C, 4, L_FIX
}, // "sprmSBrcLeft" sep.brcLeft;BRC;long;
688 {0x702D, 4, L_FIX
}, // "sprmSBrcBottom" sep.brcBottom;BRC;long;
689 {0x702E, 4, L_FIX
}, // "sprmSBrcRight" sep.brcRight;BRC;long;
690 {0x522F, 2, L_FIX
}, // "sprmSPgbProp" sep.pgbProp;;word;
691 {0x7030, 4, L_FIX
}, // "sprmSDxtCharSpace" sep.dxtCharSpace;dxt;long;
692 {0x9031, 2, L_FIX
}, // "sprmSDyaLinePitch"
693 // sep.dyaLinePitch;dya; WRONG:long; RIGHT:short; !
694 {0x5032, 2, L_FIX
}, // "sprmSClm" ;;;
695 {0x5033, 2, L_FIX
}, // "sprmSTextFlow" sep.wTextFlow;complex
696 {0x5400, 2, L_FIX
}, // "sprmTJc" tap.jc;jc;word (low order byte is
698 {0x9601, 2, L_FIX
}, // "sprmTDxaLeft" tap.rgdxaCenter
699 {0x9602, 2, L_FIX
}, // "sprmTDxaGapHalf" tap.dxaGapHalf,
701 {0x3403, 1, L_FIX
}, // "sprmTFCantSplit" tap.fCantSplit;1 or 0;byte;
702 {0x3404, 1, L_FIX
}, // "sprmTTableHeader" tap.fTableHeader;1 or 0;byte;
703 {0x3466, 1, L_FIX
}, // "sprmTFCantSplit90" tap.fCantSplit90;1 or 0;byte;
704 {0xD605, 0, L_VAR
}, // "sprmTTableBorders" tap.rgbrcTable;complex
705 {0xD606, 0, L_VAR
}, // "sprmTDefTable10" tap.rgdxaCenter,
707 {0x9407, 2, L_FIX
}, // "sprmTDyaRowHeight" tap.dyaRowHeight;dya;word;
708 {0xD608, 0, L_VAR
}, // "sprmTDefTable" tap.rgtc;complex
709 {0xD609, 0, L_VAR
}, // "sprmTDefTableShd" tap.rgshd;complex
710 {0x740A, 4, L_FIX
}, // "sprmTTlp" tap.tlp;TLP;4 bytes;
711 {0x560B, 2, L_FIX
}, // "sprmTFBiDi" ;;;
712 {0x740C, 1, L_FIX
}, // "sprmTHTMLProps" ;;;
713 {0xD620, 0, L_VAR
}, // "sprmTSetBrc" tap.rgtc[].rgbrc;complex
714 {0x7621, 4, L_FIX
}, // "sprmTInsert" tap.rgdxaCenter, tap.rgtc;complex
715 {0x5622, 2, L_FIX
}, // "sprmTDelete" tap.rgdxaCenter, tap.rgtc;complex
716 {0x7623, 4, L_FIX
}, // "sprmTDxaCol" tap.rgdxaCenter;complex
717 {0x5624, 0, L_VAR
}, // "sprmTMerge" tap.fFirstMerged, tap.fMerged;
718 {0x5625, 0, L_VAR
}, // "sprmTSplit" tap.fFirstMerged, tap.fMerged;
719 {0xD626, 0, L_VAR
}, // "sprmTSetBrc10" tap.rgtc[].rgbrc;complex
720 {0x7627, 0, L_VAR
}, // "sprmTSetShd" tap.rgshd;complex
721 {0x7628, 0, L_VAR
}, // "sprmTSetShdOdd" tap.rgshd;complex
722 {0x7629, 4, L_FIX
}, // "sprmTTextFlow" tap.rgtc[].fVerticaltap,
723 // rgtc[].fBackwardtap, rgtc[].fRotateFont;0 or 10
725 {0xD62A, 1, L_FIX
}, // "sprmTDiagLine" ;;;
726 {0xD62B, 0, L_VAR
}, // "sprmTVertMerge" tap.rgtc[].vertMerge
727 {0xD62C, 0, L_VAR
}, // "sprmTVertAlign" tap.rgtc[].vertAlign
728 {0xCA78, 0, L_VAR
}, // undocumented "sprmCDoubleLine ?"
729 {0x6649, 4, L_FIX
}, // undocumented
730 {0xF614, 3, L_FIX
}, // undocumented
731 {0xD612, 0, L_VAR
}, // undocumented, new background colours.
732 {0xD613, 0, L_VAR
}, // undocumented
733 {0xD61A, 0, L_VAR
}, // undocumented
734 {0xD61B, 0, L_VAR
}, // undocumented
735 {0xD61C, 0, L_VAR
}, // undocumented
736 {0xD61D, 0, L_VAR
}, // undocumented
737 {0xD632, 0, L_VAR
}, // undocumented
738 {0xD634, 0, L_VAR
}, // undocumented
739 {0xD238, 0, L_VAR
}, // undocumented sep
740 {0xC64E, 0, L_VAR
}, // undocumented
741 {0xC64F, 0, L_VAR
}, // undocumented
742 {0xC650, 0, L_VAR
}, // undocumented
743 {0xC651, 0, L_VAR
}, // undocumented
744 {0xF661, 3, L_FIX
}, // undocumented
745 {0x4873, 2, L_FIX
}, // "sprmCRgLid0" chp.rglid[0];LID: for non-FE text
746 {0x4874, 2, L_FIX
}, // "sprmCRgLid1" chp.rglid[1];LID: for Far East text
747 {0x6463, 4, L_FIX
}, // undocumented
748 {0x2461, 1, L_FIX
}, // undoc, must be asian version of "sprmPJc"
749 {0x845D, 2, L_FIX
}, // undoc, must be asian version of "sprmPDxaRight"
750 {0x845E, 2, L_FIX
}, // undoc, must be asian version of "sprmPDxaLeft"
751 {0x8460, 2, L_FIX
}, // undoc, must be asian version of "sprmPDxaLeft1"
752 {0x3615, 1, L_FIX
}, // undocumented
753 {0x360D, 1, L_FIX
}, // undocumented
754 {0x703A, 4, L_FIX
}, // undocumented, sep, perhaps related to textgrids ?
755 {0x303B, 1, L_FIX
}, // undocumented, sep
756 {0x244B, 1, L_FIX
}, // undocumented, subtable "sprmPFInTable" equiv ?
757 {0x244C, 1, L_FIX
}, // undocumented, subtable "sprmPFTtp" equiv ?
758 {0x940E, 2, L_FIX
}, // undocumented
759 {0x940F, 2, L_FIX
}, // undocumented
760 {0x9410, 2, L_FIX
}, // undocumented
761 {0x6815, 4, L_FIX
}, // undocumented
762 {0x6816, 4, L_FIX
}, // undocumented
763 {0x6870, 4, L_FIX
}, // undocumented, text colour
764 {0xC64D, 0, L_VAR
}, // undocumented, para back colour
765 {0x6467, 4, L_FIX
}, // undocumented
766 {0x646B, 4, L_FIX
}, // undocumented
767 {0xF617, 3, L_FIX
}, // undocumented
768 {0xD660, 0, L_VAR
}, // undocumented, something to do with colour.
769 {0xD670, 0, L_VAR
}, // undocumented, something to do with colour.
770 {0xCA71, 0, L_VAR
}, // undocumented, text backcolour
771 {0x303C, 1, L_FIX
}, // undocumented, sep
772 {0x245B, 1, L_FIX
}, // undocumented, para autobefore
773 {0x245C, 1, L_FIX
}, // undocumented, para autoafter
774 // "sprmPFContextualSpacing", don't add space between para of the same style
778 static wwSprmSearcher
aSprmSrch(aSprms
, sizeof(aSprms
) / sizeof(aSprms
[0]));
782 wwSprmParser::wwSprmParser(ww::WordVersion eVersion
) : meVersion(eVersion
)
784 OSL_ENSURE((meVersion
>= ww::eWW2
&& meVersion
<= ww::eWW8
),
785 "Impossible value for version");
787 mnDelta
= (ww::IsSevenMinus(meVersion
)) ? 0 : 1;
789 if (meVersion
<= ww::eWW2
)
790 mpKnownSprms
= GetWW2SprmSearcher();
791 else if (meVersion
< ww::eWW8
)
792 mpKnownSprms
= GetWW6SprmSearcher();
794 mpKnownSprms
= GetWW8SprmSearcher();
797 SprmInfo
wwSprmParser::GetSprmInfo(sal_uInt16 nId
) const
800 SprmInfo aSrch
={0,0,0};
802 const SprmInfo
* pFound
= mpKnownSprms
->search(aSrch
);
805 OSL_ENSURE(ww::IsEightPlus(meVersion
),
806 "Unknown ww7- sprm, dangerous, report to development");
810 //All the unknown ww7 sprms appear to be variable (which makes sense)
813 if (ww::IsEightPlus(meVersion
)) //We can recover perfectly in this case
850 inline sal_uInt8
Get_Byte( sal_uInt8
*& p
)
852 sal_uInt8 n
= SVBT8ToByte( *(SVBT8
*)p
);
857 inline sal_uInt16
Get_UShort( sal_uInt8
*& p
)
859 sal_uInt16 n
= SVBT16ToShort( *(SVBT16
*)p
);
864 inline short Get_Short( sal_uInt8
*& p
)
866 return Get_UShort(p
);
869 inline sal_uLong
Get_ULong( sal_uInt8
*& p
)
871 sal_uLong n
= SVBT32ToUInt32( *(SVBT32
*)p
);
876 inline long Get_Long( sal_uInt8
*& p
)
881 WW8SprmIter::WW8SprmIter(const sal_uInt8
* pSprms_
, long nLen_
,
882 const wwSprmParser
&rParser
)
883 : mrSprmParser(rParser
), pSprms( pSprms_
), nRemLen( nLen_
)
888 void WW8SprmIter::SetSprms(const sal_uInt8
* pSprms_
, long nLen_
)
895 void WW8SprmIter::advance()
899 sal_uInt16 nSize
= nAktSize
;
908 void WW8SprmIter::UpdateMyMembers()
910 bool bValid
= (pSprms
&& nRemLen
>= mrSprmParser
.MinSprmLen());
914 nAktId
= mrSprmParser
.GetSprmId(pSprms
);
915 nAktSize
= mrSprmParser
.GetSprmSize(nAktId
, pSprms
);
916 pAktParams
= pSprms
+ mrSprmParser
.DistanceToData(nAktId
);
917 bValid
= nAktSize
<= nRemLen
;
918 SAL_WARN_IF(!bValid
, "sw.ww8", "sprm longer than remaining bytes, doc or parser is wrong");
930 const sal_uInt8
* WW8SprmIter::FindSprm(sal_uInt16 nId
)
934 if (GetAktId() == nId
)
935 return GetAktParams(); // SPRM found!
939 return 0; // SPRM _not_ found
943 // WW8PLCFx_PCDAttrs cling to WW8PLCF_Pcd and therefore do not have their own iterators.
944 // All methods relating to iterators are therefore dummies.
945 WW8PLCFx_PCDAttrs::WW8PLCFx_PCDAttrs(ww::WordVersion eVersion
,
946 WW8PLCFx_PCD
* pPLCFx_PCD
, const WW8ScannerBase
* pBase
)
947 : WW8PLCFx(eVersion
, true), pPcdI(pPLCFx_PCD
->GetPLCFIter()),
948 pPcd(pPLCFx_PCD
), pGrpprls(pBase
->pPieceGrpprls
),
949 nGrpprls(pBase
->nPieceGrpprls
)
953 sal_uLong
WW8PLCFx_PCDAttrs::GetIdx() const
958 void WW8PLCFx_PCDAttrs::SetIdx( sal_uLong
)
962 bool WW8PLCFx_PCDAttrs::SeekPos(WW8_CP
)
967 void WW8PLCFx_PCDAttrs::advance()
971 WW8_CP
WW8PLCFx_PCDAttrs::Where()
973 return ( pPcd
) ? pPcd
->Where() : WW8_CP_MAX
;
976 void WW8PLCFx_PCDAttrs::GetSprms(WW8PLCFxDesc
* p
)
980 p
->bRealLineEnd
= false;
981 if ( !pPcdI
|| !pPcdI
->Get(p
->nStartPos
, p
->nEndPos
, pData
) )
983 // PLCF fully processed
984 p
->nStartPos
= p
->nEndPos
= WW8_CP_MAX
;
990 sal_uInt16 nPrm
= SVBT16ToShort( ( (WW8_PCD
*)pData
)->prm
);
994 sal_uInt16 nSprmIdx
= nPrm
>> 1;
996 if( nSprmIdx
>= nGrpprls
)
999 p
->nStartPos
= p
->nEndPos
= WW8_CP_MAX
;
1004 const sal_uInt8
* pSprms
= pGrpprls
[ nSprmIdx
];
1006 p
->nSprmsLen
= SVBT16ToShort( pSprms
); // Length
1008 p
->pMemPos
= pSprms
; // Position
1012 // SPRM is stored directly into members var
1014 These are the attr that are in the piece-table instead of in the text!
1017 if (IsSevenMinus(GetFIBVersion()))
1019 aShortSprm
[0] = (sal_uInt8
)( ( nPrm
& 0xfe) >> 1 );
1020 aShortSprm
[1] = (sal_uInt8
)( nPrm
>> 8 );
1021 p
->nSprmsLen
= ( nPrm
) ? 2 : 0; // length
1023 // store Postion of internal mini storage in Data Pointer
1024 p
->pMemPos
= aShortSprm
;
1030 sal_uInt8 nSprmListIdx
= (sal_uInt8
)((nPrm
& 0xfe) >> 1);
1033 // process Sprm Id Matching as explained in MS Documentation
1035 // ''Property Modifier(variant 1) (PRM)''
1036 // see file: s62f39.htm
1038 // Since isprm is 7 bits, rgsprmPrm can hold 0x80 entries.
1039 static const sal_uInt16 aSprmId
[0x80] =
1041 // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1042 0x0000,0x0000,0x0000,0x0000,
1043 // sprmPIncLvl, sprmPJc, sprmPFSideBySide, sprmPFKeep
1044 0x2402,0x2403,0x2404,0x2405,
1045 // sprmPFKeepFollow, sprmPFPageBreakBefore, sprmPBrcl,
1047 0x2406,0x2407,0x2408,0x2409,
1048 // sprmPIlvl, sprmNoop, sprmPFNoLineNumb, sprmNoop
1049 0x260A,0x0000,0x240C,0x0000,
1050 // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1051 0x0000,0x0000,0x0000,0x0000,
1052 // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1053 0x0000,0x0000,0x0000,0x0000,
1054 // sprmPFInTable, sprmPFTtp, sprmNoop, sprmNoop
1055 0x2416,0x2417,0x0000,0x0000,
1056 // sprmNoop, sprmPPc, sprmNoop, sprmNoop
1057 0x0000,0x261B,0x0000,0x0000,
1058 // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1059 0x0000,0x0000,0x0000,0x0000,
1060 // sprmNoop, sprmPWr, sprmNoop, sprmNoop
1061 0x0000,0x2423,0x0000,0x0000,
1062 // sprmNoop, sprmNoop, sprmNoop, sprmNoop
1063 0x0000,0x0000,0x0000,0x0000,
1064 // sprmPFNoAutoHyph, sprmNoop, sprmNoop, sprmNoop
1065 0x242A,0x0000,0x0000,0x0000,
1066 // sprmNoop, sprmNoop, sprmPFLocked, sprmPFWidowControl
1067 0x0000,0x0000,0x2430,0x2431,
1068 // sprmNoop, sprmPFKinsoku, sprmPFWordWrap,
1069 // sprmPFOverflowPunct
1070 0x0000,0x2433,0x2434,0x2435,
1071 // sprmPFTopLinePunct, sprmPFAutoSpaceDE,
1072 // sprmPFAutoSpaceDN, sprmNoop
1073 0x2436,0x2437,0x2438,0x0000,
1074 // sprmNoop, sprmPISnapBaseLine, sprmNoop, sprmNoop
1075 0x0000,0x243B,0x000,0x0000,
1076 // sprmNoop, sprmCFStrikeRM, sprmCFRMark, sprmCFFldVanish
1077 0x0000,0x0800,0x0801,0x0802,
1078 // sprmNoop, sprmNoop, sprmNoop, sprmCFData
1079 0x0000,0x0000,0x0000,0x0806,
1080 // sprmNoop, sprmNoop, sprmNoop, sprmCFOle2
1081 0x0000,0x0000,0x0000,0x080A,
1082 // sprmNoop, sprmCHighlight, sprmCFEmboss, sprmCSfxText
1083 0x0000,0x2A0C,0x0858,0x2859,
1084 // sprmNoop, sprmNoop, sprmNoop, sprmCPlain
1085 0x0000,0x0000,0x0000,0x2A33,
1086 // sprmNoop, sprmCFBold, sprmCFItalic, sprmCFStrike
1087 0x0000,0x0835,0x0836,0x0837,
1088 // sprmCFOutline, sprmCFShadow, sprmCFSmallCaps, sprmCFCaps,
1089 0x0838,0x0839,0x083a,0x083b,
1090 // sprmCFVanish, sprmNoop, sprmCKul, sprmNoop,
1091 0x083C,0x0000,0x2A3E,0x0000,
1092 // sprmNoop, sprmNoop, sprmCIco, sprmNoop,
1093 0x0000,0x0000,0x2A42,0x0000,
1094 // sprmCHpsInc, sprmNoop, sprmCHpsPosAdj, sprmNoop,
1095 0x2A44,0x0000,0x2A46,0x0000,
1096 // sprmCIss, sprmNoop, sprmNoop, sprmNoop,
1097 0x2A48,0x0000,0x0000,0x0000,
1098 // sprmNoop, sprmNoop, sprmNoop, sprmNoop,
1099 0x0000,0x0000,0x0000,0x0000,
1100 // sprmNoop, sprmNoop, sprmNoop, sprmCFDStrike,
1101 0x0000,0x0000,0x0000,0x2A53,
1102 // sprmCFImprint, sprmCFSpec, sprmCFObj, sprmPicBrcl,
1103 0x0854,0x0855,0x0856,0x2E00,
1104 // sprmPOutLvl, sprmPFBiDi, sprmNoop, sprmNoop,
1105 0x2640,0x2441,0x0000,0x0000,
1106 // sprmNoop, sprmNoop, sprmPPnbrRMarkNot
1107 0x0000,0x0000,0x0000,0x0000
1110 // find real Sprm Id:
1111 sal_uInt16 nSprmId
= aSprmId
[ nSprmListIdx
];
1115 // move Sprm Id and Sprm Param to internal mini storage:
1116 aShortSprm
[0] = (sal_uInt8
)( ( nSprmId
& 0x00ff) );
1117 aShortSprm
[1] = (sal_uInt8
)( ( nSprmId
& 0xff00) >> 8 );
1118 aShortSprm
[2] = (sal_uInt8
)( nPrm
>> 8 );
1120 // store Sprm Length in member:
1121 p
->nSprmsLen
= ( nPrm
) ? 3 : 0;
1123 // store Postion of internal mini storage in Data Pointer
1124 p
->pMemPos
= aShortSprm
;
1131 WW8PLCFx_PCD::WW8PLCFx_PCD(ww::WordVersion eVersion
, WW8PLCFpcd
* pPLCFpcd
,
1132 WW8_CP nStartCp
, bool bVer67P
)
1133 : WW8PLCFx(eVersion
, false), nClipStart(-1)
1135 // construct own iterator
1136 pPcdI
= new WW8PLCFpcd_Iter(*pPLCFpcd
, nStartCp
);
1140 WW8PLCFx_PCD::~WW8PLCFx_PCD()
1142 // pPcd-Dtor which in called from WW8ScannerBase
1146 sal_uLong
WW8PLCFx_PCD::GetIMax() const
1148 return pPcdI
? pPcdI
->GetIMax() : 0;
1151 sal_uLong
WW8PLCFx_PCD::GetIdx() const
1153 return pPcdI
? pPcdI
->GetIdx() : 0;
1156 void WW8PLCFx_PCD::SetIdx( sal_uLong nIdx
)
1159 pPcdI
->SetIdx( nIdx
);
1162 bool WW8PLCFx_PCD::SeekPos(WW8_CP nCpPos
)
1164 return pPcdI
? pPcdI
->SeekPos( nCpPos
) : false;
1167 WW8_CP
WW8PLCFx_PCD::Where()
1169 return pPcdI
? pPcdI
->Where() : WW8_CP_MAX
;
1172 long WW8PLCFx_PCD::GetNoSprms( WW8_CP
& rStart
, WW8_CP
& rEnd
, sal_Int32
& rLen
)
1177 if ( !pPcdI
|| !pPcdI
->Get(rStart
, rEnd
, pData
) )
1179 rStart
= rEnd
= WW8_CP_MAX
;
1182 return pPcdI
->GetIdx();
1185 void WW8PLCFx_PCD::advance()
1187 OSL_ENSURE(pPcdI
, "missing pPcdI");
1192 WW8_FC
WW8PLCFx_PCD::AktPieceStartCp2Fc( WW8_CP nCp
)
1194 WW8_CP nCpStart
, nCpEnd
;
1197 if ( !pPcdI
->Get(nCpStart
, nCpEnd
, pData
) )
1199 OSL_ENSURE( !this, "AktPieceStartCp2Fc() with false Cp found (1)" );
1203 OSL_ENSURE( nCp
>= nCpStart
&& nCp
< nCpEnd
,
1204 "AktPieceCp2Fc() with false Cp found (2)" );
1206 if( nCp
< nCpStart
)
1211 bool bIsUnicode
= false;
1212 WW8_FC nFC
= SVBT32ToUInt32( ((WW8_PCD
*)pData
)->fc
);
1214 nFC
= WW8PLCFx_PCD::TransformPieceAddress( nFC
, bIsUnicode
);
1216 return nFC
+ (nCp
- nCpStart
) * (bIsUnicode
? 2 : 1);
1220 void WW8PLCFx_PCD::AktPieceFc2Cp( WW8_CP
& rStartPos
, WW8_CP
& rEndPos
,
1221 const WW8ScannerBase
*pSBase
)
1223 //No point going anywhere with this
1224 if ((rStartPos
== WW8_CP_MAX
) && (rEndPos
== WW8_CP_MAX
))
1227 rStartPos
= pSBase
->WW8Fc2Cp( rStartPos
);
1228 rEndPos
= pSBase
->WW8Fc2Cp( rEndPos
);
1231 WW8_CP
WW8PLCFx_PCD::AktPieceStartFc2Cp( WW8_FC nStartPos
)
1233 WW8_CP nCpStart
, nCpEnd
;
1235 if ( !pPcdI
->Get( nCpStart
, nCpEnd
, pData
) )
1237 OSL_ENSURE( !this, "AktPieceStartFc2Cp() - error" );
1240 bool bIsUnicode
= false;
1241 sal_Int32 nFcStart
= SVBT32ToUInt32( ((WW8_PCD
*)pData
)->fc
);
1243 nFcStart
= WW8PLCFx_PCD::TransformPieceAddress( nFcStart
, bIsUnicode
);
1245 sal_Int32 nUnicodeFactor
= bIsUnicode
? 2 : 1;
1247 if( nStartPos
< nFcStart
)
1248 nStartPos
= nFcStart
;
1250 if( nStartPos
>= nFcStart
+ (nCpEnd
- nCpStart
) * nUnicodeFactor
)
1251 nStartPos
= nFcStart
+ (nCpEnd
- nCpStart
- 1) * nUnicodeFactor
;
1253 return nCpStart
+ (nStartPos
- nFcStart
) / nUnicodeFactor
;
1256 // Helper routines for all
1258 short WW8_BRC::DetermineBorderProperties(bool bVer67
, short *pSpace
,
1259 sal_uInt8
*pCol
, short *pIdx
) const
1262 Word does not factor the width of the border into the width/height
1263 stored in the information for graphic/table/object widths, so we need
1264 to figure out this extra width here and utilize the returned size in
1267 short nMSTotalWidth
;
1272 sal_uInt16 aBrc1
= SVBT16ToShort(aBits1
);
1273 nCol
= static_cast< sal_uInt8
>((aBrc1
>> 6) & 0x1f); // aBor.ico
1274 nSpace
= (aBrc1
& 0xF800) >> 11;
1276 nMSTotalWidth
= aBrc1
& 0x07;
1277 nIdx
= (aBrc1
& 0x18) >> 3;
1278 //Dashed/Dotted unsets double/thick
1279 if (nMSTotalWidth
> 5)
1281 nIdx
= nMSTotalWidth
;
1284 nMSTotalWidth
= nMSTotalWidth
* nIdx
* 15;
1289 nCol
= aBits2
[0]; // aBor.ico
1290 nSpace
= aBits2
[1] & 0x1F; //space between line and object
1292 //Specification in 8ths of a point, 1 Point = 20 Twips, so by 2.5
1293 nMSTotalWidth
= aBits1
[ 0 ] * 20 / 8;
1295 //Figure out the real size of the border according to word
1298 //Note that codes over 25 are undocumented, and I can't create
1299 //these 4 here in the wild.
1304 OSL_FAIL("Can't create these from the menus, please report");
1306 case 23: //Only 3pt in the menus, but honours the size setting.
1310 triple line is five times the width of an ordinary line,
1311 except that the smallest 1/4 point size appears to have
1312 exactly the same total border width as a 3/4 point size
1313 ordinary line, i.e. three times the nominal line width. The
1314 second smallest 1/2 point size appears to have exactly the
1315 total border width as a 2 1/4 border, i.e 4.5 times the size.
1317 if (nMSTotalWidth
== 5)
1319 else if (nMSTotalWidth
== 10)
1320 nMSTotalWidth
= nMSTotalWidth
*9/2;
1326 wave, the dimensions appear to be created by the drawing of
1327 the wave, so we have only two possibilites in the menus, 3/4
1328 point is equal to solid 3 point. This calculation seems to
1329 match well to results.
1335 double wave, the dimensions appear to be created by the
1336 drawing of the wave, so we have only one possibilites in the
1337 menus, that of 3/4 point is equal to solid 3 point. This
1338 calculation seems to match well to results.
1340 nMSTotalWidth
+= 45*2;
1348 *pSpace
= nSpace
*20;
1351 return nMSTotalWidth
;
1355 * WW8Cp2Fc is a good method, a CP always maps to a FC
1356 * WW8Fc2Cp on the other hand is more dubious, a random FC
1357 * may not map to a valid CP. Try and avoid WW8Fc2Cp where
1360 WW8_CP
WW8ScannerBase::WW8Fc2Cp( WW8_FC nFcPos
) const
1362 WW8_CP nFallBackCpEnd
= WW8_CP_MAX
;
1363 if( nFcPos
== WW8_FC_MAX
)
1364 return nFallBackCpEnd
;
1367 if (pWw8Fib
->nVersion
>= 8)
1370 bIsUnicode
= pWw8Fib
->fExtChar
? true : false;
1372 if( pPieceIter
) // Complex File ?
1374 sal_uLong nOldPos
= pPieceIter
->GetIdx();
1376 for (pPieceIter
->SetIdx(0);
1377 pPieceIter
->GetIdx() < pPieceIter
->GetIMax(); pPieceIter
->advance())
1379 WW8_CP nCpStart
, nCpEnd
;
1381 if( !pPieceIter
->Get( nCpStart
, nCpEnd
, pData
) )
1382 { // outside PLCFfpcd ?
1383 OSL_ENSURE( !this, "PLCFpcd-WW8Fc2Cp() went wrong" );
1386 sal_Int32 nFcStart
= SVBT32ToUInt32( ((WW8_PCD
*)pData
)->fc
);
1387 if (pWw8Fib
->nVersion
>= 8)
1389 nFcStart
= WW8PLCFx_PCD::TransformPieceAddress( nFcStart
,
1394 bIsUnicode
= pWw8Fib
->fExtChar
? true : false;
1396 sal_Int32 nLen
= (nCpEnd
- nCpStart
) * (bIsUnicode
? 2 : 1);
1399 If this cp is inside this piece, or its the last piece and we are
1400 on the very last cp of that piece
1402 if (nFcPos
>= nFcStart
)
1406 nCpStart
+ ((nFcPos
- nFcStart
) / (bIsUnicode
? 2 : 1));
1407 if (nFcPos
< nFcStart
+ nLen
)
1409 pPieceIter
->SetIdx( nOldPos
);
1412 else if (nFcPos
== nFcStart
+ nLen
)
1414 //Keep this cp as its on a piece boundary because we might
1415 //need it if tests fail
1416 nFallBackCpEnd
= nTempCp
;
1421 pPieceIter
->SetIdx( nOldPos
); // not found
1423 If it was not found, then this is because it has fallen between two
1424 stools, i.e. either it is the last cp/fc of the last piece, or it is
1425 the last cp/fc of a disjoint piece.
1427 return nFallBackCpEnd
;
1432 nFallBackCpEnd
= (nFcPos
- pWw8Fib
->fcMin
);
1434 nFallBackCpEnd
= (nFcPos
- pWw8Fib
->fcMin
+ 1) / 2;
1436 return nFallBackCpEnd
;
1439 WW8_FC
WW8ScannerBase::WW8Cp2Fc(WW8_CP nCpPos
, bool* pIsUnicode
,
1440 WW8_CP
* pNextPieceCp
, bool* pTestFlag
) const
1444 if( WW8_CP_MAX
== nCpPos
)
1449 pIsUnicode
= &bIsUnicode
;
1451 if (pWw8Fib
->nVersion
>= 8)
1452 *pIsUnicode
= false;
1454 *pIsUnicode
= pWw8Fib
->fExtChar
? true : false;
1460 *pNextPieceCp
= WW8_CP_MAX
;
1462 if( !pPieceIter
->SeekPos( nCpPos
) )
1467 OSL_ENSURE( !this, "Handed over wrong CP to WW8Cp2Fc()" );
1471 WW8_CP nCpStart
, nCpEnd
;
1473 if( !pPieceIter
->Get( nCpStart
, nCpEnd
, pData
) )
1478 OSL_ENSURE( !this, "PLCFfpcd-Get went wrong" );
1483 *pNextPieceCp
= nCpEnd
;
1485 WW8_FC nRet
= SVBT32ToUInt32( ((WW8_PCD
*)pData
)->fc
);
1486 if (pWw8Fib
->nVersion
>= 8)
1487 nRet
= WW8PLCFx_PCD::TransformPieceAddress( nRet
, *pIsUnicode
);
1489 *pIsUnicode
= pWw8Fib
->fExtChar
? true : false;
1491 nRet
+= (nCpPos
- nCpStart
) * (*pIsUnicode
? 2 : 1);
1497 return pWw8Fib
->fcMin
+ nCpPos
* (*pIsUnicode
? 2 : 1);
1500 // class WW8ScannerBase
1501 WW8PLCFpcd
* WW8ScannerBase::OpenPieceTable( SvStream
* pStr
, const WW8Fib
* pWwF
)
1503 if ( ((8 > pWw8Fib
->nVersion
) && !pWwF
->fComplex
) || !pWwF
->lcbClx
)
1506 WW8_FC nClxPos
= pWwF
->fcClx
;
1507 sal_Int32 nClxLen
= pWwF
->lcbClx
;
1508 sal_Int32 nLeft
= nClxLen
;
1509 sal_Int16 nGrpprl
= 0;
1511 if (!checkSeek(*pStr
, nClxPos
))
1514 while( 1 ) // Zaehle Zahl der Grpprls
1519 if( 2 == clxt
) // PLCFfpcd ?
1520 break; // PLCFfpcd gefunden
1521 if( 1 == clxt
) // clxtGrpprl ?
1527 return NULL
; // gone wrong
1528 pStr
->SeekRel( nLen
); // ueberlies grpprl
1531 if (!checkSeek(*pStr
, nClxPos
))
1535 pPieceGrpprls
= new sal_uInt8
*[nGrpprl
+ 1];
1536 memset( pPieceGrpprls
, 0, ( nGrpprl
+ 1 ) * sizeof(sal_uInt8
*) );
1537 nPieceGrpprls
= nGrpprl
;
1538 sal_Int16 nAktGrpprl
= 0; // read Grpprls
1544 if( 2 == clxt
) // PLCFfpcd ?
1545 break; // PLCFfpcd found
1550 return NULL
; // gone wrong
1551 if( 1 == clxt
) // clxtGrpprl ?
1553 sal_uInt8
* p
= new sal_uInt8
[nLen
+2]; // allocate
1554 ShortToSVBT16(nLen
, p
); // trage Laenge ein
1555 if (!checkRead(*pStr
, p
+2, nLen
)) // read grpprl
1560 pPieceGrpprls
[nAktGrpprl
++] = p
; // trage in Array ein
1563 pStr
->SeekRel( nLen
); // ueberlies nicht-Grpprl
1565 // lies Piece Table PLCF ein
1566 sal_Int32
nPLCFfLen(0);
1567 if (pWwF
->GetFIBVersion() <= ww::eWW2
)
1569 sal_Int16
nWordTwoLen(0);
1570 *pStr
>> nWordTwoLen
;
1571 nPLCFfLen
= nWordTwoLen
;
1575 OSL_ENSURE( 65536 > nPLCFfLen
, "PLCFfpcd above 64 k" );
1576 return new WW8PLCFpcd( pStr
, pStr
->Tell(), nPLCFfLen
, 8 );
1579 void WW8ScannerBase::DeletePieceTable()
1583 for( sal_uInt8
** p
= pPieceGrpprls
; *p
; p
++ )
1585 delete[] pPieceGrpprls
;
1590 WW8ScannerBase::WW8ScannerBase( SvStream
* pSt
, SvStream
* pTblSt
,
1591 SvStream
* pDataSt
, WW8Fib
* pWwFib
)
1592 : pWw8Fib(pWwFib
), pMainFdoa(0), pHdFtFdoa(0), pMainTxbx(0),
1593 pMainTxbxBkd(0), pHdFtTxbx(0), pHdFtTxbxBkd(0), pMagicTables(0),
1594 pSubdocs(0), pExtendedAtrds(0), pPieceGrpprls(0)
1596 pPiecePLCF
= OpenPieceTable( pTblSt
, pWw8Fib
); // Complex
1599 pPieceIter
= new WW8PLCFpcd_Iter( *pPiecePLCF
);
1600 pPLCFx_PCD
= new WW8PLCFx_PCD(pWwFib
->GetFIBVersion(), pPiecePLCF
, 0,
1601 IsSevenMinus(pWw8Fib
->GetFIBVersion()));
1602 pPLCFx_PCDAttrs
= new WW8PLCFx_PCDAttrs(pWwFib
->GetFIBVersion(),
1609 pPLCFx_PCDAttrs
= 0;
1612 // pChpPLCF and pPapPLCF may NOT be created before pPLCFx_PCD !!
1613 pChpPLCF
= new WW8PLCFx_Cp_FKP( pSt
, pTblSt
, pDataSt
, *this, CHP
); // CHPX
1614 pPapPLCF
= new WW8PLCFx_Cp_FKP( pSt
, pTblSt
, pDataSt
, *this, PAP
); // PAPX
1616 pSepPLCF
= new WW8PLCFx_SEPX( pSt
, pTblSt
, *pWwFib
, 0 ); // SEPX
1619 pFtnPLCF
= new WW8PLCFx_SubDoc( pTblSt
, pWwFib
->GetFIBVersion(), 0,
1620 pWwFib
->fcPlcffndRef
, pWwFib
->lcbPlcffndRef
, pWwFib
->fcPlcffndTxt
,
1621 pWwFib
->lcbPlcffndTxt
, 2 );
1623 pEdnPLCF
= new WW8PLCFx_SubDoc( pTblSt
, pWwFib
->GetFIBVersion(), 0,
1624 pWwFib
->fcPlcfendRef
, pWwFib
->lcbPlcfendRef
, pWwFib
->fcPlcfendTxt
,
1625 pWwFib
->lcbPlcfendTxt
, 2 );
1627 pAndPLCF
= new WW8PLCFx_SubDoc( pTblSt
, pWwFib
->GetFIBVersion(), 0,
1628 pWwFib
->fcPlcfandRef
, pWwFib
->lcbPlcfandRef
, pWwFib
->fcPlcfandTxt
,
1629 pWwFib
->lcbPlcfandTxt
, IsSevenMinus(pWwFib
->GetFIBVersion()) ? 20 : 30);
1632 pFldPLCF
= new WW8PLCFx_FLD(pTblSt
, *pWwFib
, MAN_MAINTEXT
);
1633 // Fields Header / Footer
1634 pFldHdFtPLCF
= new WW8PLCFx_FLD(pTblSt
, *pWwFib
, MAN_HDFT
);
1636 pFldFtnPLCF
= new WW8PLCFx_FLD(pTblSt
, *pWwFib
, MAN_FTN
);
1638 pFldEdnPLCF
= new WW8PLCFx_FLD(pTblSt
, *pWwFib
, MAN_EDN
);
1640 pFldAndPLCF
= new WW8PLCFx_FLD(pTblSt
, *pWwFib
, MAN_AND
);
1641 // Fields in Textboxes in Main Text
1642 pFldTxbxPLCF
= new WW8PLCFx_FLD(pTblSt
, *pWwFib
, MAN_TXBX
);
1643 // Fields in Textboxes in Header / Footer
1644 pFldTxbxHdFtPLCF
= new WW8PLCFx_FLD(pTblSt
,*pWwFib
,MAN_TXBX_HDFT
);
1646 // Note: 6 stands for "6 OR 7", 7 stands for "ONLY 7"
1647 switch( pWw8Fib
->nVersion
)
1651 if( pWwFib
->fcPlcfdoaMom
&& pWwFib
->lcbPlcfdoaMom
)
1653 pMainFdoa
= new WW8PLCFspecial( pTblSt
, pWwFib
->fcPlcfdoaMom
,
1654 pWwFib
->lcbPlcfdoaMom
, 6 );
1656 if( pWwFib
->fcPlcfdoaHdr
&& pWwFib
->lcbPlcfdoaHdr
)
1658 pHdFtFdoa
= new WW8PLCFspecial( pTblSt
, pWwFib
->fcPlcfdoaHdr
,
1659 pWwFib
->lcbPlcfdoaHdr
, 6 );
1663 if( pWwFib
->fcPlcfspaMom
&& pWwFib
->lcbPlcfspaMom
)
1665 pMainFdoa
= new WW8PLCFspecial( pTblSt
, pWwFib
->fcPlcfspaMom
,
1666 pWwFib
->lcbPlcfspaMom
, 26 );
1668 if( pWwFib
->fcPlcfspaHdr
&& pWwFib
->lcbPlcfspaHdr
)
1670 pHdFtFdoa
= new WW8PLCFspecial( pTblSt
, pWwFib
->fcPlcfspaHdr
,
1671 pWwFib
->lcbPlcfspaHdr
, 26 );
1673 // PLCF for TextBox break-descriptors in the main text
1674 if( pWwFib
->fcPlcftxbxBkd
&& pWwFib
->lcbPlcftxbxBkd
)
1676 pMainTxbxBkd
= new WW8PLCFspecial( pTblSt
,
1677 pWwFib
->fcPlcftxbxBkd
, pWwFib
->lcbPlcftxbxBkd
, 0);
1679 // PLCF for TextBox break-descriptors in Header/Footer range
1680 if( pWwFib
->fcPlcfHdrtxbxBkd
&& pWwFib
->lcbPlcfHdrtxbxBkd
)
1682 pHdFtTxbxBkd
= new WW8PLCFspecial( pTblSt
,
1683 pWwFib
->fcPlcfHdrtxbxBkd
, pWwFib
->lcbPlcfHdrtxbxBkd
, 0);
1685 // Sub table cp positions
1686 if (pWwFib
->fcPlcfTch
&& pWwFib
->lcbPlcfTch
)
1688 pMagicTables
= new WW8PLCFspecial( pTblSt
,
1689 pWwFib
->fcPlcfTch
, pWwFib
->lcbPlcfTch
, 4);
1691 // Sub document cp positions
1692 if (pWwFib
->fcPlcfwkb
&& pWwFib
->lcbPlcfwkb
)
1694 pSubdocs
= new WW8PLCFspecial( pTblSt
,
1695 pWwFib
->fcPlcfwkb
, pWwFib
->lcbPlcfwkb
, 12);
1698 if (pWwFib
->fcAtrdExtra
&& pWwFib
->lcbAtrdExtra
)
1700 sal_Size nOldPos
= pTblSt
->Tell();
1701 if (checkSeek(*pTblSt
, pWwFib
->fcAtrdExtra
) && (pTblSt
->remainingSize() >= pWwFib
->lcbAtrdExtra
))
1703 pExtendedAtrds
= new sal_uInt8
[pWwFib
->lcbAtrdExtra
];
1704 pWwFib
->lcbAtrdExtra
= pTblSt
->Read(pExtendedAtrds
, pWwFib
->lcbAtrdExtra
);
1707 pWwFib
->lcbAtrdExtra
= 0;
1708 pTblSt
->Seek(nOldPos
);
1713 OSL_ENSURE( !this, "Es wurde vergessen, nVersion zu kodieren!" );
1717 // PLCF for TextBox stories in main text
1718 sal_uInt32 nLenTxBxS
= (8 > pWw8Fib
->nVersion
) ? 0 : 22;
1719 if( pWwFib
->fcPlcftxbxTxt
&& pWwFib
->lcbPlcftxbxTxt
)
1721 pMainTxbx
= new WW8PLCFspecial( pTblSt
, pWwFib
->fcPlcftxbxTxt
,
1722 pWwFib
->lcbPlcftxbxTxt
, nLenTxBxS
);
1725 // PLCF for TextBox stories in Header/Footer range
1726 if( pWwFib
->fcPlcfHdrtxbxTxt
&& pWwFib
->lcbPlcfHdrtxbxTxt
)
1728 pHdFtTxbx
= new WW8PLCFspecial( pTblSt
, pWwFib
->fcPlcfHdrtxbxTxt
,
1729 pWwFib
->lcbPlcfHdrtxbxTxt
, nLenTxBxS
);
1732 pBook
= new WW8PLCFx_Book(pTblSt
, *pWwFib
);
1735 WW8ScannerBase::~WW8ScannerBase()
1738 delete pPLCFx_PCDAttrs
;
1746 delete pFldHdFtPLCF
;
1748 delete pFldTxbxPLCF
;
1749 delete pFldTxbxHdFtPLCF
;
1756 // vergessene Schaeflein
1760 delete pMainTxbxBkd
;
1762 delete pHdFtTxbxBkd
;
1763 delete pMagicTables
;
1765 delete [] pExtendedAtrds
;
1770 static bool WW8SkipField(WW8PLCFspecial
& rPLCF
)
1775 if (!rPLCF
.Get(nP
, pData
)) // End of PLCFspecial?
1780 if((((sal_uInt8
*)pData
)[0] & 0x1f ) != 0x13 ) // No beginning?
1781 return true; // Do not terminate on error
1783 if( !rPLCF
.Get( nP
, pData
) )
1787 while((((sal_uInt8
*)pData
)[0] & 0x1f ) == 0x13 )
1789 // still new (nested) beginnings ?
1790 WW8SkipField( rPLCF
); // nested Field in description
1791 if( !rPLCF
.Get( nP
, pData
) )
1795 if((((sal_uInt8
*)pData
)[0] & 0x1f ) == 0x14 )
1798 // Field Separator ?
1801 if( !rPLCF
.Get( nP
, pData
) )
1804 while ((((sal_uInt8
*)pData
)[0] & 0x1f ) == 0x13)
1806 // still new (nested) beginnings?
1807 WW8SkipField( rPLCF
); // nested Field in Results
1808 if( !rPLCF
.Get( nP
, pData
) )
1817 static bool WW8GetFieldPara(WW8PLCFspecial
& rPLCF
, WW8FieldDesc
& rF
)
1820 sal_uLong nOldIdx
= rPLCF
.GetIdx();
1822 rF
.nLen
= rF
.nId
= rF
.nOpt
= rF
.bCodeNest
= rF
.bResNest
= 0;
1824 if( !rPLCF
.Get( rF
.nSCode
, pData
) ) // end of PLCFspecial?
1829 if((((sal_uInt8
*)pData
)[0] & 0x1f ) != 0x13 ) // No beginning?
1832 rF
.nId
= ((sal_uInt8
*)pData
)[1];
1834 if( !rPLCF
.Get( rF
.nLCode
, pData
) )
1837 rF
.nSRes
= rF
.nLCode
; // Default
1838 rF
.nSCode
++; // without markers
1839 rF
.nLCode
-= rF
.nSCode
; // Pos -> length
1841 while((((sal_uInt8
*)pData
)[0] & 0x1f ) == 0x13 )
1843 // still new (nested) beginnings ?
1844 WW8SkipField( rPLCF
); // nested Field in description
1845 rF
.bCodeNest
= true;
1846 if( !rPLCF
.Get( rF
.nSRes
, pData
) )
1850 if ((((sal_uInt8
*)pData
)[0] & 0x1f ) == 0x14 ) // Field Separator?
1854 if( !rPLCF
.Get( rF
.nLRes
, pData
) )
1857 while((((sal_uInt8
*)pData
)[0] & 0x1f ) == 0x13 )
1859 // still new (nested) beginnings ?
1860 WW8SkipField( rPLCF
); // nested Field in results
1862 if( !rPLCF
.Get( rF
.nLRes
, pData
) )
1865 rF
.nLen
= rF
.nLRes
- rF
.nSCode
+ 2; // nLRes is still the final position
1866 rF
.nLRes
-= rF
.nSRes
; // now: nLRes = length
1867 rF
.nSRes
++; // Endpos encluding Markers
1870 rF
.nLRes
= 0; // no result found
1871 rF
.nLen
= rF
.nSRes
- rF
.nSCode
+ 2; // total length
1875 if((((sal_uInt8
*)pData
)[0] & 0x1f ) == 0x15 )
1878 // INDEX-Fld has set Bit7?
1879 rF
.nOpt
= ((sal_uInt8
*)pData
)[1]; // yes -> copy flags
1881 rF
.nId
= 0; // no -> Field invalid
1884 rPLCF
.SetIdx( nOldIdx
);
1887 rPLCF
.SetIdx( nOldIdx
);
1891 String
read_uInt8_BeltAndBracesString(SvStream
& rStrm
, rtl_TextEncoding eEnc
)
1893 OUString aRet
= read_lenPrefixed_uInt8s_ToOUString
<sal_uInt8
>(rStrm
, eEnc
);
1894 rStrm
.SeekRel(sizeof(sal_uInt8
)); // skip null-byte at end
1898 String
read_uInt16_BeltAndBracesString(SvStream
& rStrm
)
1900 String aRet
= read_uInt16_PascalString(rStrm
);
1901 rStrm
.SeekRel(sizeof(sal_Unicode
)); // skip null-byte at end
1905 xub_StrLen
WW8ScannerBase::WW8ReadString( SvStream
& rStrm
, String
& rStr
,
1906 WW8_CP nAktStartCp
, long nTotalLen
, rtl_TextEncoding eEnc
) const
1908 // Read in plain text, which can extend over several pieces
1911 long nTotalRead
= 0;
1912 WW8_CP nBehindTextCp
= nAktStartCp
+ nTotalLen
;
1913 WW8_CP nNextPieceCp
= nBehindTextCp
; // Initialization, important for Ver6
1916 bool bIsUnicode
, bPosOk
;
1917 WW8_FC fcAct
= WW8Cp2Fc(nAktStartCp
,&bIsUnicode
,&nNextPieceCp
,&bPosOk
);
1919 // Probably aimed beyond file end, doesn't matter!
1923 rStrm
.Seek( fcAct
);
1925 long nLen
= ( (nNextPieceCp
< nBehindTextCp
) ? nNextPieceCp
1926 : nBehindTextCp
) - nAktStartCp
;
1931 if( nLen
> USHRT_MAX
- 1 )
1932 nLen
= USHRT_MAX
- 1;
1935 rStr
.Append(String(read_uInt16s_ToOUString(rStrm
, nLen
)));
1937 rStr
.Append(String(read_uInt8s_ToOUString(rStrm
, nLen
, eEnc
)));
1939 nAktStartCp
+= nLen
;
1940 if ( nTotalRead
!= rStr
.Len() )
1943 while( nTotalRead
< nTotalLen
);
1948 WW8PLCFspecial::WW8PLCFspecial(SvStream
* pSt
, sal_uInt32 nFilePos
,
1949 sal_uInt32 nPLCF
, sal_uInt32 nStruct
)
1950 : nIdx(0), nStru(nStruct
)
1952 const sal_uInt32 nValidMin
=4;
1954 sal_Size nOldPos
= pSt
->Tell();
1956 bool bValid
= checkSeek(*pSt
, nFilePos
);
1957 sal_Size nRemainingSize
= pSt
->remainingSize();
1958 if( !(nRemainingSize
>= nValidMin
&& nPLCF
>= nValidMin
))
1960 nPLCF
= bValid
? std::min(nRemainingSize
, static_cast<sal_Size
>(nPLCF
)) : nValidMin
;
1962 // Pointer to Pos- and Struct-array
1963 pPLCF_PosArray
= new sal_Int32
[ ( nPLCF
+ 3 ) / 4 ];
1964 pPLCF_PosArray
[0] = 0;
1966 nPLCF
= bValid
? pSt
->Read(pPLCF_PosArray
, nPLCF
) : nValidMin
;
1968 nPLCF
= std::max(nPLCF
, nValidMin
);
1970 nIMax
= ( nPLCF
- 4 ) / ( 4 + nStruct
);
1971 #ifdef OSL_BIGENDIAN
1972 for( nIdx
= 0; nIdx
<= nIMax
; nIdx
++ )
1973 pPLCF_PosArray
[nIdx
] = OSL_SWAPDWORD( pPLCF_PosArray
[nIdx
] );
1975 #endif // OSL_BIGENDIAN
1976 if( nStruct
) // Pointer to content array
1977 pPLCF_Contents
= (sal_uInt8
*)&pPLCF_PosArray
[nIMax
+ 1];
1979 pPLCF_Contents
= 0; // no content
1984 // WW8PLCFspecial::SeekPos() sets WW8PLCFspecial to position nPos, while also the entry is used
1985 // that begins before nPos and ends after nPos.
1986 // Suitable for normal attributes. However, the beginning of the attribute is not corrected onto
1987 // the position nPos.
1988 bool WW8PLCFspecial::SeekPos(long nP
)
1990 if( nP
< pPLCF_PosArray
[0] )
1993 return false; // Not found: nP less than smallest entry
1996 // Search from beginning?
1997 if( (1 > nIdx
) || (nP
< pPLCF_PosArray
[ nIdx
-1 ]) )
2000 long nI
= nIdx
? nIdx
: 1;
2003 for(int n
= (1==nIdx
? 1 : 2); n
; --n
)
2005 for( ; nI
<=nEnd
; ++nI
)
2006 { // search with an index that is incremented by 1
2007 if( nP
< pPLCF_PosArray
[nI
] )
2009 nIdx
= nI
- 1; // nI - 1 is the correct index
2010 return true; // done
2016 nIdx
= nIMax
; // not found, greater than all entries
2020 // WW8PLCFspecial::SeekPosExact() like SeekPos(), but it is ensured that no attribute is cut,
2021 // i.e. the next given attribute begins at or after nPos.
2022 // Is used for fields and bookmarks.
2023 bool WW8PLCFspecial::SeekPosExact(long nP
)
2025 if( nP
< pPLCF_PosArray
[0] )
2028 return false; // Not found: nP less than smallest entry
2030 // Search from beginning?
2031 if( nP
<=pPLCF_PosArray
[nIdx
] )
2034 long nI
= nIdx
? nIdx
-1 : 0;
2037 for(int n
= (0==nIdx
? 1 : 2); n
; --n
)
2039 for( ; nI
< nEnd
; ++nI
)
2041 if( nP
<=pPLCF_PosArray
[nI
] )
2043 nIdx
= nI
; // nI is the correct index
2044 return true; // done
2050 nIdx
= nIMax
; // Not found, greater than all entries
2054 bool WW8PLCFspecial::Get(WW8_CP
& rPos
, void*& rpValue
) const
2056 return GetData( nIdx
, rPos
, rpValue
);
2059 bool WW8PLCFspecial::GetData(long nInIdx
, WW8_CP
& rPos
, void*& rpValue
) const
2061 if ( nInIdx
>= nIMax
)
2066 rPos
= pPLCF_PosArray
[nInIdx
];
2067 rpValue
= pPLCF_Contents
? (void*)&pPLCF_Contents
[nInIdx
* nStru
] : 0;
2071 // WW8PLCF e.g. for SEPX
2072 // Ctor for *others* than Fkps
2073 // With nStartPos < 0, the first element of PLCFs will be taken
2074 WW8PLCF::WW8PLCF(SvStream
& rSt
, WW8_FC nFilePos
, sal_Int32 nPLCF
, int nStruct
,
2075 WW8_CP nStartPos
) : pPLCF_PosArray(0), nIdx(0), nStru(nStruct
)
2077 OSL_ENSURE( nPLCF
, "WW8PLCF: nPLCF is zero!" );
2079 nIMax
= ( nPLCF
- 4 ) / ( 4 + nStruct
);
2081 ReadPLCF(rSt
, nFilePos
, nPLCF
);
2083 if( nStartPos
>= 0 )
2084 SeekPos( nStartPos
);
2087 // Ctor *only* for Fkps
2088 // The last 2 parameters are needed for PLCF.Chpx and PLCF.Papx.
2089 // If ncpN != 0, then an incomple PLCF will be completed. This is always required for WW6 with
2090 // lack of resources and for WordPad (W95).
2091 // With nStartPos < 0, the first element of the PLCFs is taken.
2092 WW8PLCF::WW8PLCF(SvStream
& rSt
, WW8_FC nFilePos
, sal_Int32 nPLCF
, int nStruct
,
2093 WW8_CP nStartPos
, sal_Int32 nPN
, sal_Int32 ncpN
): pPLCF_PosArray(0), nIdx(0),
2096 nIMax
= ( nPLCF
- 4 ) / ( 4 + nStruct
);
2099 ReadPLCF(rSt
, nFilePos
, nPLCF
);
2101 GeneratePLCF(rSt
, nPN
, ncpN
);
2103 if( nStartPos
>= 0 )
2104 SeekPos( nStartPos
);
2107 void WW8PLCF::ReadPLCF(SvStream
& rSt
, WW8_FC nFilePos
, sal_uInt32 nPLCF
)
2109 sal_Size nOldPos
= rSt
.Tell();
2110 bool bValid
= checkSeek(rSt
, nFilePos
) && (rSt
.remainingSize() >= nPLCF
);
2114 // Pointer to Pos-array
2115 pPLCF_PosArray
= new WW8_CP
[ ( nPLCF
+ 3 ) / 4 ];
2116 bValid
= checkRead(rSt
, pPLCF_PosArray
, nPLCF
);
2121 #ifdef OSL_BIGENDIAN
2122 for( nIdx
= 0; nIdx
<= nIMax
; nIdx
++ )
2123 pPLCF_PosArray
[nIdx
] = OSL_SWAPDWORD( pPLCF_PosArray
[nIdx
] );
2125 #endif // OSL_BIGENDIAN
2126 // Pointer to content array
2127 pPLCF_Contents
= (sal_uInt8
*)&pPLCF_PosArray
[nIMax
+ 1];
2130 OSL_ENSURE(bValid
, "Document has corrupt PLCF, ignoring it");
2138 void WW8PLCF::MakeFailedPLCF()
2141 delete[] pPLCF_PosArray
;
2142 pPLCF_PosArray
= new sal_Int32
[2];
2143 pPLCF_PosArray
[0] = pPLCF_PosArray
[1] = WW8_CP_MAX
;
2144 pPLCF_Contents
= (sal_uInt8
*)&pPLCF_PosArray
[nIMax
+ 1];
2147 void WW8PLCF::GeneratePLCF(SvStream
& rSt
, sal_Int32 nPN
, sal_Int32 ncpN
)
2149 OSL_ENSURE( nIMax
< ncpN
, "Pcl.Fkp: Why is PLCF too big?" );
2151 bool failure
= false;
2154 if ((nIMax
< 1) || (nIMax
> (WW8_CP_MAX
- 4)/6) || ((nPN
+ ncpN
) > USHRT_MAX
))
2159 size_t nSiz
= 6 * nIMax
+ 4;
2160 size_t nElems
= ( nSiz
+ 3 ) / 4;
2161 pPLCF_PosArray
= new sal_Int32
[ nElems
]; // Pointer to Pos-array
2163 for (sal_Int32 i
= 0; i
< ncpN
&& !failure
; ++i
)
2166 // construct FC entries
2167 // first FC entry of each Fkp
2168 if (checkSeek(rSt
, ( nPN
+ i
) << 9 ))
2172 pPLCF_PosArray
[i
] = nFc
;
2173 failure
= rSt
.GetError();
2183 sal_Size nLastFkpPos
= ( ( nPN
+ nIMax
- 1 ) << 9 );
2184 // Anz. Fkp-Eintraege des letzten Fkp
2185 if (!checkSeek(rSt
, nLastFkpPos
+ 511))
2190 // letzer FC-Eintrag des letzten Fkp
2191 if (!checkSeek(rSt
, nLastFkpPos
+ nb
* 4))
2196 pPLCF_PosArray
[nIMax
] = nFc
; // end of the last Fkp
2198 failure
= rSt
.GetError();
2204 // Pointer to content array
2205 pPLCF_Contents
= (sal_uInt8
*)&pPLCF_PosArray
[nIMax
+ 1];
2206 sal_uInt8
* p
= pPLCF_Contents
;
2208 for (sal_Int32 i
= 0; i
< ncpN
; ++i
) // construct PNs
2210 ShortToSVBT16(static_cast<sal_uInt16
>(nPN
+ i
), p
);
2215 OSL_ENSURE( !failure
, "Document has corrupt PLCF, ignoring it" );
2221 bool WW8PLCF::SeekPos(WW8_CP nPos
)
2225 if( nP
< pPLCF_PosArray
[0] )
2228 // not found: nPos less than smallest entry
2232 // Search from beginning?
2233 if( (1 > nIdx
) || (nP
< pPLCF_PosArray
[ nIdx
-1 ]) )
2236 sal_Int32 nI
= nIdx
? nIdx
: 1;
2237 sal_Int32 nEnd
= nIMax
;
2239 for(int n
= (1==nIdx
? 1 : 2); n
; --n
)
2241 for( ; nI
<=nEnd
; ++nI
) // search with an index that is incremented by 1
2243 if( nP
< pPLCF_PosArray
[nI
] ) // found position
2245 nIdx
= nI
- 1; // nI - 1 is the correct index
2246 return true; // done
2253 nIdx
= nIMax
; // not found, greater than all entries
2257 bool WW8PLCF::Get(WW8_CP
& rStart
, WW8_CP
& rEnd
, void*& rpValue
) const
2259 if ( nIdx
>= nIMax
)
2261 rStart
= rEnd
= WW8_CP_MAX
;
2264 rStart
= pPLCF_PosArray
[ nIdx
];
2265 rEnd
= pPLCF_PosArray
[ nIdx
+ 1 ];
2266 rpValue
= (void*)&pPLCF_Contents
[nIdx
* nStru
];
2270 WW8_CP
WW8PLCF::Where() const
2272 if ( nIdx
>= nIMax
)
2275 return pPLCF_PosArray
[nIdx
];
2278 WW8PLCFpcd::WW8PLCFpcd(SvStream
* pSt
, sal_uInt32 nFilePos
,
2279 sal_uInt32 nPLCF
, sal_uInt32 nStruct
)
2282 const sal_uInt32 nValidMin
=4;
2284 sal_Size nOldPos
= pSt
->Tell();
2286 bool bValid
= checkSeek(*pSt
, nFilePos
);
2287 sal_Size nRemainingSize
= pSt
->remainingSize();
2288 if( !(nRemainingSize
>= nValidMin
&& nPLCF
>= nValidMin
))
2290 nPLCF
= bValid
? std::min(nRemainingSize
, static_cast<sal_Size
>(nPLCF
)) : nValidMin
;
2292 pPLCF_PosArray
= new sal_Int32
[ ( nPLCF
+ 3 ) / 4 ]; // Pointer to Pos-array
2293 pPLCF_PosArray
[0] = 0;
2295 nPLCF
= bValid
? pSt
->Read(pPLCF_PosArray
, nPLCF
) : nValidMin
;
2296 nPLCF
= std::max(nPLCF
, nValidMin
);
2298 nIMax
= ( nPLCF
- 4 ) / ( 4 + nStruct
);
2299 #ifdef OSL_BIGENDIAN
2300 for( long nI
= 0; nI
<= nIMax
; nI
++ )
2301 pPLCF_PosArray
[nI
] = OSL_SWAPDWORD( pPLCF_PosArray
[nI
] );
2302 #endif // OSL_BIGENDIAN
2304 // Pointer to content array
2305 pPLCF_Contents
= (sal_uInt8
*)&pPLCF_PosArray
[nIMax
+ 1];
2307 pSt
->Seek( nOldPos
);
2310 // If nStartPos < 0, the first element of PLCFs will be taken
2311 WW8PLCFpcd_Iter::WW8PLCFpcd_Iter( WW8PLCFpcd
& rPLCFpcd
, long nStartPos
)
2312 :rPLCF( rPLCFpcd
), nIdx( 0 )
2314 if( nStartPos
>= 0 )
2315 SeekPos( nStartPos
);
2318 bool WW8PLCFpcd_Iter::SeekPos(long nPos
)
2322 if( nP
< rPLCF
.pPLCF_PosArray
[0] )
2325 return false; // not found: nPos less than smallest entry
2327 // Search from beginning?
2328 if( (1 > nIdx
) || (nP
< rPLCF
.pPLCF_PosArray
[ nIdx
-1 ]) )
2331 long nI
= nIdx
? nIdx
: 1;
2332 long nEnd
= rPLCF
.nIMax
;
2334 for(int n
= (1==nIdx
? 1 : 2); n
; --n
)
2336 for( ; nI
<=nEnd
; ++nI
)
2337 { // search with an index that is incremented by 1
2338 if( nP
< rPLCF
.pPLCF_PosArray
[nI
] )
2340 nIdx
= nI
- 1; // nI - 1 is the correct index
2341 return true; // done
2347 nIdx
= rPLCF
.nIMax
; // not found, greater than all entries
2351 bool WW8PLCFpcd_Iter::Get(WW8_CP
& rStart
, WW8_CP
& rEnd
, void*& rpValue
) const
2353 if( nIdx
>= rPLCF
.nIMax
)
2355 rStart
= rEnd
= WW8_CP_MAX
;
2358 rStart
= rPLCF
.pPLCF_PosArray
[nIdx
];
2359 rEnd
= rPLCF
.pPLCF_PosArray
[nIdx
+ 1];
2360 rpValue
= (void*)&rPLCF
.pPLCF_Contents
[nIdx
* rPLCF
.nStru
];
2364 sal_Int32
WW8PLCFpcd_Iter::Where() const
2366 if ( nIdx
>= rPLCF
.nIMax
)
2367 return SAL_MAX_INT32
;
2369 return rPLCF
.pPLCF_PosArray
[nIdx
];
2373 bool WW8PLCFx_Fc_FKP::WW8Fkp::Entry::operator<
2374 (const WW8PLCFx_Fc_FKP::WW8Fkp::Entry
& rSecond
) const
2376 return (mnFC
< rSecond
.mnFC
);
2379 bool IsReplaceAllSprm(sal_uInt16 nSpId
)
2381 return (0x6645 == nSpId
|| 0x6646 == nSpId
);
2384 bool IsExpandableSprm(sal_uInt16 nSpId
)
2386 return 0x646B == nSpId
;
2389 void WW8PLCFx_Fc_FKP::WW8Fkp::FillEntry(WW8PLCFx_Fc_FKP::WW8Fkp::Entry
&rEntry
,
2390 sal_Size nDataOffset
, sal_uInt16 nLen
)
2392 bool bValidPos
= (nDataOffset
< sizeof(maRawData
));
2394 OSL_ENSURE(bValidPos
, "sprm sequence offset is out of range, ignoring");
2402 sal_uInt16 nAvailableData
= sizeof(maRawData
)-nDataOffset
;
2403 OSL_ENSURE(nLen
<= nAvailableData
, "srpm sequence len is out of range, clipping");
2404 rEntry
.mnLen
= std::min(nLen
, nAvailableData
);
2405 rEntry
.mpData
= maRawData
+ nDataOffset
;
2408 WW8PLCFx_Fc_FKP::WW8Fkp::WW8Fkp(ww::WordVersion eVersion
, SvStream
* pSt
,
2409 SvStream
* pDataSt
, long _nFilePos
, long nItemSiz
, ePLCFT ePl
,
2411 : nItemSize(nItemSiz
), nFilePos(_nFilePos
), mnIdx(0), ePLCF(ePl
),
2412 maSprmParser(eVersion
)
2414 memset(maRawData
, 0, 512);
2416 sal_Size nOldPos
= pSt
->Tell();
2418 bool bCouldSeek
= checkSeek(*pSt
, nFilePos
);
2419 bool bCouldRead
= bCouldSeek
? checkRead(*pSt
, maRawData
, 512) : false;
2421 mnIMax
= bCouldRead
? maRawData
[511] : 0;
2423 sal_uInt8
*pStart
= maRawData
;
2424 // Offset-Location in maRawData
2425 const size_t nRawDataStart
= (mnIMax
+ 1) * 4;
2427 for (mnIdx
= 0; mnIdx
< mnIMax
; ++mnIdx
)
2429 const size_t nRawDataOffset
= nRawDataStart
+ mnIdx
* nItemSize
;
2431 //clip to available data, corrupt fkp
2432 if (nRawDataOffset
>= 511)
2438 unsigned int nOfs
= maRawData
[nRawDataOffset
] * 2;
2440 //clip to available data, corrupt fkp
2447 Entry
aEntry(Get_Long(pStart
));
2455 aEntry
.mnLen
= maRawData
[nOfs
];
2458 sal_Size nDataOffset
= nOfs
+ 1;
2460 FillEntry(aEntry
, nDataOffset
, aEntry
.mnLen
);
2462 if (aEntry
.mnLen
&& eVersion
== ww::eWW2
)
2464 Word2CHPX aChpx
= ReadWord2Chpx(*pSt
, nFilePos
+ nOfs
+ 1, static_cast< sal_uInt8
>(aEntry
.mnLen
));
2465 std::vector
<sal_uInt8
> aSprms
= ChpxToSprms(aChpx
);
2466 aEntry
.mnLen
= static_cast< sal_uInt16
>(aSprms
.size());
2469 aEntry
.mpData
= new sal_uInt8
[aEntry
.mnLen
];
2470 memcpy(aEntry
.mpData
, &(aSprms
[0]), aEntry
.mnLen
);
2471 aEntry
.mbMustDelete
= true;
2478 sal_uInt8 nDelta
= 0;
2480 aEntry
.mnLen
= maRawData
[nOfs
];
2481 if (IsEightPlus(eVersion
) && !aEntry
.mnLen
)
2483 aEntry
.mnLen
= maRawData
[nOfs
+1];
2488 //stylecode, std/istd
2489 if (eVersion
== ww::eWW2
)
2491 if (aEntry
.mnLen
>= 1)
2493 aEntry
.mnIStd
= *(maRawData
+nOfs
+1+nDelta
);
2494 aEntry
.mnLen
--; //style code
2495 if (aEntry
.mnLen
>= 6)
2497 aEntry
.mnLen
-=6; //PHE
2498 //skipi stc, len byte + 6 byte PHE
2499 unsigned int nOffset
= nOfs
+ 8;
2500 if (nOffset
>= 511) //Bad offset
2502 if (aEntry
.mnLen
) //start is ok
2504 if (nOffset
+ aEntry
.mnLen
> 512) //Bad end, clip
2505 aEntry
.mnLen
= 512 - nOffset
;
2506 aEntry
.mpData
= maRawData
+ nOffset
;
2510 aEntry
.mnLen
=0; //Too short
2515 if (aEntry
.mnLen
>= 2)
2517 //len byte + optional extra len byte
2518 sal_Size nDataOffset
= nOfs
+ 1 + nDelta
;
2519 aEntry
.mnIStd
= nDataOffset
<= sizeof(maRawData
)-sizeof(aEntry
.mnIStd
) ?
2520 SVBT16ToShort(maRawData
+nDataOffset
) : 0;
2521 aEntry
.mnLen
-=2; //istd
2525 nDataOffset
+= sizeof(aEntry
.mnIStd
);
2527 FillEntry(aEntry
, nDataOffset
, aEntry
.mnLen
);
2531 aEntry
.mnLen
=0; //Too short, ignore
2534 sal_uInt16 nSpId
= aEntry
.mnLen
? maSprmParser
.GetSprmId(aEntry
.mpData
) : 0;
2537 If we replace then we throw away the old data, if we
2538 are expanding, then we tack the old data onto the end
2541 bool bExpand
= IsExpandableSprm(nSpId
);
2542 if (IsReplaceAllSprm(nSpId
) || bExpand
)
2544 sal_uInt32 nCurr
= pDataSt
->Tell();
2545 sal_uInt32 nPos
= SVBT32ToUInt32(aEntry
.mpData
+ 2);
2546 if (checkSeek(*pDataSt
, nPos
))
2548 sal_uInt16 nOrigLen
= bExpand
? aEntry
.mnLen
: 0;
2549 sal_uInt8
*pOrigData
= bExpand
? aEntry
.mpData
: 0;
2551 *pDataSt
>> aEntry
.mnLen
;
2553 new sal_uInt8
[aEntry
.mnLen
+ nOrigLen
];
2554 aEntry
.mbMustDelete
= true;
2556 pDataSt
->Read(aEntry
.mpData
, aEntry
.mnLen
);
2558 pDataSt
->Seek( nCurr
);
2562 memcpy(aEntry
.mpData
+ aEntry
.mnLen
,
2563 pOrigData
, nOrigLen
);
2564 aEntry
.mnLen
= aEntry
.mnLen
+ nOrigLen
;
2571 OSL_FAIL("sweet god, what have you done!");
2576 maEntries
.push_back(aEntry
);
2578 #ifdef DEBUGSPRMREADER
2581 sal_uInt8
* pSprms
= GetLenAndIStdAndSprms( nLen
);
2583 WW8SprmIter
aIter(pSprms
, nLen
, maSprmParser
);
2584 while (aIter
.GetSprms())
2586 fprintf(stderr
, "id is %x\n", aIter
.GetAktId());
2593 //one more FC than grrpl entries
2594 maEntries
.push_back(Entry(Get_Long(pStart
)));
2596 //we expect them sorted, but it appears possible for them to arive unsorted
2597 std::sort(maEntries
.begin(), maEntries
.end());
2607 WW8PLCFx_Fc_FKP::WW8Fkp::Entry::Entry(const Entry
&rEntry
)
2608 : mnFC(rEntry
.mnFC
), mnLen(rEntry
.mnLen
), mnIStd(rEntry
.mnIStd
),
2609 mbMustDelete(rEntry
.mbMustDelete
)
2613 mpData
= new sal_uInt8
[mnLen
];
2614 memcpy(mpData
, rEntry
.mpData
, mnLen
);
2617 mpData
= rEntry
.mpData
;
2620 WW8PLCFx_Fc_FKP::WW8Fkp::Entry
&
2621 WW8PLCFx_Fc_FKP::WW8Fkp::Entry::operator=(const Entry
&rEntry
)
2623 if (this == &rEntry
)
2630 mnLen
= rEntry
.mnLen
;
2631 mnIStd
= rEntry
.mnIStd
;
2632 mbMustDelete
= rEntry
.mbMustDelete
;
2636 mpData
= new sal_uInt8
[mnLen
];
2637 memcpy(mpData
, rEntry
.mpData
, mnLen
);
2640 mpData
= rEntry
.mpData
;
2644 WW8PLCFx_Fc_FKP::WW8Fkp::Entry::~Entry()
2650 void WW8PLCFx_Fc_FKP::WW8Fkp::Reset(WW8_FC nFc
)
2657 bool WW8PLCFx_Fc_FKP::WW8Fkp::SeekPos(WW8_FC nFc
)
2659 if (nFc
< maEntries
[0].mnFC
)
2662 return false; // not found: nPos less than smallest entry
2665 // Search from beginning?
2666 if ((1 > mnIdx
) || (nFc
< maEntries
[mnIdx
-1].mnFC
))
2669 sal_uInt8 nI
= mnIdx
? mnIdx
: 1;
2670 sal_uInt8 nEnd
= mnIMax
;
2672 for(sal_uInt8 n
= (1==mnIdx
? 1 : 2); n
; --n
)
2674 for( ; nI
<=nEnd
; ++nI
)
2675 { // search with an index that is incremented by 1
2676 if (nFc
< maEntries
[nI
].mnFC
)
2678 mnIdx
= nI
- 1; // nI - 1 is the correct index
2679 return true; // done
2685 mnIdx
= mnIMax
; // not found, greater than all entries
2689 sal_uInt8
* WW8PLCFx_Fc_FKP::WW8Fkp::Get(WW8_FC
& rStart
, WW8_FC
& rEnd
, sal_Int32
& rLen
)
2694 if (mnIdx
>= mnIMax
)
2696 rStart
= WW8_FC_MAX
;
2700 rStart
= maEntries
[mnIdx
].mnFC
;
2701 rEnd
= maEntries
[mnIdx
+ 1].mnFC
;
2703 sal_uInt8
* pSprms
= GetLenAndIStdAndSprms( rLen
);
2707 bool WW8PLCFx_Fc_FKP::WW8Fkp::SetIdx(sal_uInt8 nI
)
2717 sal_uInt8
* WW8PLCFx_Fc_FKP::WW8Fkp::GetLenAndIStdAndSprms(sal_Int32
& rLen
) const
2719 rLen
= maEntries
[mnIdx
].mnLen
;
2720 return maEntries
[mnIdx
].mpData
;
2723 const sal_uInt8
* WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm( sal_uInt16 nId
)
2725 if (mnIdx
>= mnIMax
)
2729 sal_uInt8
* pSprms
= GetLenAndIStdAndSprms( nLen
);
2731 WW8SprmIter
aIter(pSprms
, nLen
, maSprmParser
);
2732 return aIter
.FindSprm(nId
);
2735 bool WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm(sal_uInt16 nId
,
2736 std::vector
<const sal_uInt8
*> &rResult
)
2738 if (mnIdx
>= mnIMax
)
2742 sal_uInt8
* pSprms
= GetLenAndIStdAndSprms( nLen
);
2744 WW8SprmIter
aIter(pSprms
, nLen
, maSprmParser
);
2746 while(aIter
.GetSprms())
2748 if (aIter
.GetAktId() == nId
)
2749 rResult
.push_back(aIter
.GetAktParams());
2752 return !rResult
.empty();
2756 void WW8PLCFx::GetSprms( WW8PLCFxDesc
* p
)
2758 OSL_ENSURE( !this, "Called wrong GetSprms" );
2759 p
->nStartPos
= p
->nEndPos
= WW8_CP_MAX
;
2762 p
->bRealLineEnd
= false;
2766 long WW8PLCFx::GetNoSprms( WW8_CP
& rStart
, WW8_CP
& rEnd
, sal_Int32
& rLen
)
2768 OSL_ENSURE( !this, "Called wrong GetNoSprms" );
2769 rStart
= rEnd
= WW8_CP_MAX
;
2774 // ...Idx2: Default: ignore
2775 sal_uLong
WW8PLCFx::GetIdx2() const
2780 void WW8PLCFx::SetIdx2(sal_uLong
)
2785 public std::unary_function
<const WW8PLCFx_Fc_FKP::WW8Fkp
*, bool>
2790 SamePos(long nPo
) : mnPo(nPo
) {}
2791 bool operator()(const WW8PLCFx_Fc_FKP::WW8Fkp
*pFkp
)
2792 {return mnPo
== pFkp
->GetFilePos();}
2796 bool WW8PLCFx_Fc_FKP::NewFkp()
2798 WW8_CP nPLCFStart
, nPLCFEnd
;
2801 static const int WW8FkpSizeTabVer2
[ PLCF_END
] =
2803 1, 1, 0 /*, 0, 0, 0*/
2805 static const int WW8FkpSizeTabVer6
[ PLCF_END
] =
2807 1, 7, 0 /*, 0, 0, 0*/
2809 static const int WW8FkpSizeTabVer8
[ PLCF_END
] =
2811 1, 13, 0 /*, 0, 0, 0*/
2813 const int* pFkpSizeTab
;
2815 switch (GetFIBVersion())
2818 pFkpSizeTab
= WW8FkpSizeTabVer2
;
2822 pFkpSizeTab
= WW8FkpSizeTabVer6
;
2825 pFkpSizeTab
= WW8FkpSizeTabVer8
;
2829 OSL_ENSURE( !this, "Someone forgot to encode nVersion!" );
2833 if (!pPLCF
->Get( nPLCFStart
, nPLCFEnd
, pPage
))
2836 return false; // PLCF completely processed
2839 long nPo
= SVBT16ToShort( (sal_uInt8
*)pPage
);
2840 nPo
<<= 9; // shift as LONG
2842 long nAktFkpFilePos
= pFkp
? pFkp
->GetFilePos() : -1;
2843 if (nAktFkpFilePos
== nPo
)
2844 pFkp
->Reset(GetStartFc());
2848 std::find_if(maFkpCache
.begin(), maFkpCache
.end(), SamePos(nPo
));
2849 if (aIter
!= maFkpCache
.end())
2852 pFkp
->Reset(GetStartFc());
2854 else if (0 != (pFkp
= new WW8Fkp(GetFIBVersion(), pFKPStrm
, pDataStrm
, nPo
,
2855 pFkpSizeTab
[ ePLCF
], ePLCF
, GetStartFc())))
2857 maFkpCache
.push_back(pFkp
);
2859 if (maFkpCache
.size() > eMaxCache
)
2861 delete maFkpCache
.front();
2862 maFkpCache
.pop_front();
2867 SetStartFc( -1 ); // only the first time
2871 WW8PLCFx_Fc_FKP::WW8PLCFx_Fc_FKP(SvStream
* pSt
, SvStream
* pTblSt
,
2872 SvStream
* pDataSt
, const WW8Fib
& rFib
, ePLCFT ePl
, WW8_FC nStartFcL
)
2873 : WW8PLCFx(rFib
.GetFIBVersion(), true), pFKPStrm(pSt
), pDataStrm(pDataSt
),
2874 pFkp(0), ePLCF(ePl
), pPCDAttrs(0)
2876 SetStartFc(nStartFcL
);
2877 long nLenStruct
= (8 > rFib
.nVersion
) ? 2 : 4;
2880 pPLCF
= new WW8PLCF(*pTblSt
, rFib
.fcPlcfbteChpx
, rFib
.lcbPlcfbteChpx
,
2881 nLenStruct
, GetStartFc(), rFib
.pnChpFirst
, rFib
.cpnBteChp
);
2885 pPLCF
= new WW8PLCF(*pTblSt
, rFib
.fcPlcfbtePapx
, rFib
.lcbPlcfbtePapx
,
2886 nLenStruct
, GetStartFc(), rFib
.pnPapFirst
, rFib
.cpnBtePap
);
2890 WW8PLCFx_Fc_FKP::~WW8PLCFx_Fc_FKP()
2892 myiter aEnd
= maFkpCache
.end();
2893 for (myiter aIter
= maFkpCache
.begin(); aIter
!= aEnd
; ++aIter
)
2899 sal_uLong
WW8PLCFx_Fc_FKP::GetIdx() const
2901 sal_uLong u
= pPLCF
->GetIdx() << 8;
2903 u
|= pFkp
->GetIdx();
2907 void WW8PLCFx_Fc_FKP::SetIdx( sal_uLong nIdx
)
2909 if( !( nIdx
& 0xffffff00L
) )
2911 pPLCF
->SetIdx( nIdx
>> 8 );
2915 { // there was a Fkp
2916 // Set PLCF one position back to retrieve the address of the Fkp
2917 pPLCF
->SetIdx( ( nIdx
>> 8 ) - 1 );
2918 if (NewFkp()) // read Fkp again
2920 sal_uInt8 nFkpIdx
= static_cast<sal_uInt8
>(nIdx
& 0xff);
2921 pFkp
->SetIdx(nFkpIdx
); // set Fkp-Pos again
2926 bool WW8PLCFx_Fc_FKP::SeekPos(WW8_FC nFcPos
)
2928 // StartPos for next Where()
2929 SetStartFc( nFcPos
);
2931 // find StartPos for next pPLCF->Get()
2932 bool bRet
= pPLCF
->SeekPos(nFcPos
);
2934 // make FKP invalid?
2935 WW8_CP nPLCFStart
, nPLCFEnd
;
2937 if( pFkp
&& pPLCF
->Get( nPLCFStart
, nPLCFEnd
, pPage
) )
2939 long nPo
= SVBT16ToShort( (sal_uInt8
*)pPage
);
2940 nPo
<<= 9; // shift as LONG
2941 if (nPo
!= pFkp
->GetFilePos())
2944 pFkp
->SeekPos( nFcPos
);
2949 WW8_FC
WW8PLCFx_Fc_FKP::Where()
2956 WW8_FC nP
= pFkp
->Where();
2957 if( nP
!= WW8_FC_MAX
)
2960 pFkp
= 0; // FKP finished -> get new
2961 return Where(); // easiest way: do it recursively
2964 sal_uInt8
* WW8PLCFx_Fc_FKP::GetSprmsAndPos(WW8_FC
& rStart
, WW8_FC
& rEnd
, sal_Int32
& rLen
)
2966 rLen
= 0; // Default
2967 rStart
= rEnd
= WW8_FC_MAX
;
2969 if( !pFkp
) // Fkp not there ?
2975 sal_uInt8
* pPos
= pFkp
->Get( rStart
, rEnd
, rLen
);
2976 if( rStart
== WW8_FC_MAX
) //Not found
2981 void WW8PLCFx_Fc_FKP::advance()
2990 if( pFkp
->Where() == WW8_FC_MAX
)
2994 sal_uInt16
WW8PLCFx_Fc_FKP::GetIstd() const
2996 return pFkp
? pFkp
->GetIstd() : 0xFFFF;
2999 void WW8PLCFx_Fc_FKP::GetPCDSprms( WW8PLCFxDesc
& rDesc
)
3002 rDesc
.nSprmsLen
= 0;
3007 OSL_FAIL("+Problem: GetPCDSprms: NewFkp necessary (not possible!)" );
3011 pPCDAttrs
->GetSprms(&rDesc
);
3015 const sal_uInt8
* WW8PLCFx_Fc_FKP::HasSprm( sal_uInt16 nId
)
3017 // const would be nicer, but for that, NewFkp() would need to be replaced or eliminated
3020 OSL_FAIL( "+Motz: HasSprm: NewFkp needed ( no const possible )" );
3021 // happens in BugDoc 31722
3026 const sal_uInt8
* pRes
= pFkp
->HasSprm( nId
);
3031 GetPCDSprms( aDesc
);
3035 WW8SprmIter
aIter(aDesc
.pMemPos
, aDesc
.nSprmsLen
,
3036 pFkp
->GetSprmParser());
3037 pRes
= aIter
.FindSprm(nId
);
3044 bool WW8PLCFx_Fc_FKP::HasSprm(sal_uInt16 nId
, std::vector
<const sal_uInt8
*> &rResult
)
3046 // const would be nicer, but for that, NewFkp() would need to be replaced or eliminated
3049 OSL_FAIL( "+Motz: HasSprm: NewFkp needed ( no const possible )" );
3050 // happens in BugDoc 31722
3055 pFkp
->HasSprm(nId
, rResult
);
3058 GetPCDSprms( aDesc
);
3062 WW8SprmIter
aIter(aDesc
.pMemPos
, aDesc
.nSprmsLen
,
3063 pFkp
->GetSprmParser());
3064 while(aIter
.GetSprms())
3066 if (aIter
.GetAktId() == nId
)
3067 rResult
.push_back(aIter
.GetAktParams());
3071 return !rResult
.empty();
3074 WW8PLCFx_Cp_FKP::WW8PLCFx_Cp_FKP( SvStream
* pSt
, SvStream
* pTblSt
,
3075 SvStream
* pDataSt
, const WW8ScannerBase
& rBase
, ePLCFT ePl
)
3076 : WW8PLCFx_Fc_FKP(pSt
, pTblSt
, pDataSt
, *rBase
.pWw8Fib
, ePl
,
3077 rBase
.WW8Cp2Fc(0)), rSBase(rBase
), nAttrStart(-1), nAttrEnd(-1),
3079 bComplex( (7 < rBase
.pWw8Fib
->nVersion
) || (0 != rBase
.pWw8Fib
->fComplex
) )
3081 ResetAttrStartEnd();
3083 pPcd
= rSBase
.pPiecePLCF
? new WW8PLCFx_PCD(GetFIBVersion(),
3084 rBase
.pPiecePLCF
, 0, IsSevenMinus(GetFIBVersion())) : 0;
3087 Make a copy of the piece attributes for so that the calls to HasSprm on a
3088 Fc_FKP will be able to take into account the current piece attributes,
3089 despite the fact that such attributes can only be found through a cp based
3094 pPCDAttrs
= rSBase
.pPLCFx_PCDAttrs
? new WW8PLCFx_PCDAttrs(
3095 rSBase
.pWw8Fib
->GetFIBVersion(), pPcd
, &rSBase
) : 0;
3098 pPieceIter
= rSBase
.pPieceIter
;
3101 WW8PLCFx_Cp_FKP::~WW8PLCFx_Cp_FKP()
3106 void WW8PLCFx_Cp_FKP::ResetAttrStartEnd()
3113 sal_uLong
WW8PLCFx_Cp_FKP::GetPCDIMax() const
3115 return pPcd
? pPcd
->GetIMax() : 0;
3118 sal_uLong
WW8PLCFx_Cp_FKP::GetPCDIdx() const
3120 return pPcd
? pPcd
->GetIdx() : 0;
3123 void WW8PLCFx_Cp_FKP::SetPCDIdx( sal_uLong nIdx
)
3126 pPcd
->SetIdx( nIdx
);
3129 bool WW8PLCFx_Cp_FKP::SeekPos(WW8_CP nCpPos
)
3131 if( pPcd
) // Complex
3133 if( !pPcd
->SeekPos( nCpPos
) ) // set piece
3135 if (pPCDAttrs
&& !pPCDAttrs
->GetIter()->SeekPos(nCpPos
))
3137 return WW8PLCFx_Fc_FKP::SeekPos(pPcd
->AktPieceStartCp2Fc(nCpPos
));
3139 // NO piece table !!!
3140 return WW8PLCFx_Fc_FKP::SeekPos( rSBase
.WW8Cp2Fc(nCpPos
) );
3143 WW8_CP
WW8PLCFx_Cp_FKP::Where()
3145 WW8_FC nFc
= WW8PLCFx_Fc_FKP::Where();
3147 return pPcd
->AktPieceStartFc2Cp( nFc
); // identify piece
3148 return rSBase
.WW8Fc2Cp( nFc
); // NO piece table !!!
3151 void WW8PLCFx_Cp_FKP::GetSprms(WW8PLCFxDesc
* p
)
3153 WW8_CP nOrigCp
= p
->nStartPos
;
3155 if (!GetDirty()) //Normal case
3157 p
->pMemPos
= WW8PLCFx_Fc_FKP::GetSprmsAndPos(p
->nStartPos
, p
->nEndPos
,
3163 For the odd case where we have a location in a fastsaved file which
3164 does not have an entry in the FKP, perhaps its para end is in the next
3165 piece, or perhaps the cp just doesn't exist at all in this document.
3166 AdvSprm doesn't know so it sets the PLCF as dirty and we figure out
3167 in this method what the situation is
3169 It doesn't exist then the piece iterator will not be able to find it.
3170 Otherwise our cool fastsave algorithm can be brought to bear on the
3175 sal_uLong nOldPos
= pPieceIter
->GetIdx();
3176 bool bOk
= pPieceIter
->SeekPos(nOrigCp
);
3177 pPieceIter
->SetIdx( nOldPos
);
3182 if( pPcd
) // piece table available
3184 // Init ( no ++ called, yet )
3185 if( (nAttrStart
> nAttrEnd
) || (nAttrStart
== -1) )
3187 p
->bRealLineEnd
= (ePLCF
== PAP
);
3189 if ( ((ePLCF
== PAP
) || (ePLCF
== CHP
)) && (nOrigCp
!= WW8_CP_MAX
) )
3191 bool bIsUnicode
=false;
3193 To find the end of a paragraph for a character in a
3194 complex format file.
3196 It is necessary to know the piece that contains the
3197 character and the FC assigned to the character.
3200 //We set the piece iterator to the piece that contains the
3201 //character, now we have the correct piece for this character
3202 sal_uLong nOldPos
= pPieceIter
->GetIdx();
3203 p
->nStartPos
= nOrigCp
;
3204 pPieceIter
->SeekPos( p
->nStartPos
);
3206 //This is the FC assigned to the character, but we already
3207 //have the result of the next stage, so we can skip this step
3208 //WW8_FC nStartFc = rSBase.WW8Cp2Fc(p->nStartPos, &bIsUnicode);
3211 Using the FC of the character, first search the FKP that
3212 describes the character to find the smallest FC in the rgfc
3213 that is larger than the character FC.
3215 //But the search has already been done, the next largest FC is
3217 WW8_FC nOldEndPos
= p
->nEndPos
;
3220 If the FC found in the FKP is less than or equal to the limit
3221 FC of the piece, the end of the paragraph that contains the
3222 character is at the FKP FC minus 1.
3224 WW8_CP nCpStart
, nCpEnd
;
3226 pPieceIter
->Get(nCpStart
, nCpEnd
, pData
);
3228 WW8_FC nLimitFC
= SVBT32ToUInt32( ((WW8_PCD
*)pData
)->fc
);
3229 WW8_FC nBeginLimitFC
= nLimitFC
;
3230 if (IsEightPlus(GetFIBVersion()))
3233 WW8PLCFx_PCD::TransformPieceAddress(nLimitFC
,
3237 nLimitFC
= nBeginLimitFC
+
3238 (nCpEnd
- nCpStart
) * (bIsUnicode
? 2 : 1);
3240 if (nOldEndPos
<= nLimitFC
)
3242 p
->nEndPos
= nCpEnd
-
3243 (nLimitFC
-nOldEndPos
) / (bIsUnicode
? 2 : 1);
3248 p
->nEndPos
= nCpEnd
;
3252 If the FKP FC that was found was greater than the FC
3253 of the end of the piece, scan piece by piece toward
3254 the end of the document until a piece is found that
3255 contains a paragraph end mark.
3259 It's possible to check if a piece contains a paragraph
3260 mark by using the FC of the beginning of the piece to
3261 search in the FKPs for the smallest FC in the FKP rgfc
3262 that is greater than the FC of the beginning of the
3263 piece. If the FC found is less than or equal to the
3264 limit FC of the piece, then the character that ends
3265 the paragraph is the character immediately before the
3269 pPieceIter
->advance();
3271 for (;pPieceIter
->GetIdx() < pPieceIter
->GetIMax();
3272 pPieceIter
->advance())
3274 if( !pPieceIter
->Get( nCpStart
, nCpEnd
, pData
) )
3276 OSL_ENSURE( !this, "piece iter broken!" );
3280 sal_Int32 nFcStart
=SVBT32ToUInt32(((WW8_PCD
*)pData
)->fc
);
3282 if (IsEightPlus(GetFIBVersion()))
3285 WW8PLCFx_PCD::TransformPieceAddress(
3286 nFcStart
,bIsUnicode
);
3289 nLimitFC
= nFcStart
+ (nCpEnd
- nCpStart
) *
3290 (bIsUnicode
? 2 : 1);
3292 //if it doesn't exist, skip it
3293 if (!SeekPos(nCpStart
))
3296 WW8_FC nOne
,nSmallest
;
3297 p
->pMemPos
= WW8PLCFx_Fc_FKP::GetSprmsAndPos(nOne
,
3298 nSmallest
, p
->nSprmsLen
);
3300 if (nSmallest
<= nLimitFC
)
3302 WW8_CP nEndPos
= nCpEnd
-
3303 (nLimitFC
-nSmallest
) / (bIsUnicode
? 2 : 1);
3305 OSL_ENSURE(nEndPos
>= p
->nStartPos
, "EndPos before StartPos");
3307 if (nEndPos
>= p
->nStartPos
)
3308 p
->nEndPos
= nEndPos
;
3315 pPieceIter
->SetIdx( nOldPos
);
3318 pPcd
->AktPieceFc2Cp( p
->nStartPos
, p
->nEndPos
,&rSBase
);
3322 p
->nStartPos
= nAttrStart
;
3323 p
->nEndPos
= nAttrEnd
;
3324 p
->bRealLineEnd
= bLineEnd
;
3327 else // NO piece table !!!
3329 p
->nStartPos
= rSBase
.WW8Fc2Cp( p
->nStartPos
);
3330 p
->nEndPos
= rSBase
.WW8Fc2Cp( p
->nEndPos
);
3331 p
->bRealLineEnd
= ePLCF
== PAP
;
3335 void WW8PLCFx_Cp_FKP::advance()
3337 WW8PLCFx_Fc_FKP::advance();
3338 // !pPcd: emergency break
3339 if ( !bComplex
|| !pPcd
)
3342 if( GetPCDIdx() >= GetPCDIMax() ) // End of PLCF
3344 nAttrStart
= nAttrEnd
= WW8_CP_MAX
;
3348 sal_Int32 nFkpLen
; // Fkp entry
3350 WW8PLCFx_Fc_FKP::GetSprmsAndPos(nAttrStart
, nAttrEnd
, nFkpLen
);
3352 pPcd
->AktPieceFc2Cp( nAttrStart
, nAttrEnd
, &rSBase
);
3353 bLineEnd
= (ePLCF
== PAP
);
3356 WW8PLCFx_SEPX::WW8PLCFx_SEPX(SvStream
* pSt
, SvStream
* pTblSt
,
3357 const WW8Fib
& rFib
, WW8_CP nStartCp
)
3358 : WW8PLCFx(rFib
.GetFIBVersion(), true), maSprmParser(rFib
.GetFIBVersion()),
3359 pStrm(pSt
), nArrMax(256), nSprmSiz(0)
3361 pPLCF
= rFib
.lcbPlcfsed
3362 ? new WW8PLCF(*pTblSt
, rFib
.fcPlcfsed
, rFib
.lcbPlcfsed
,
3363 GetFIBVersion() <= ww::eWW2
? 6 : 12, nStartCp
)
3366 pSprms
= new sal_uInt8
[nArrMax
]; // maximum length
3369 WW8PLCFx_SEPX::~WW8PLCFx_SEPX()
3375 sal_uLong
WW8PLCFx_SEPX::GetIdx() const
3377 return pPLCF
? pPLCF
->GetIdx() : 0;
3380 void WW8PLCFx_SEPX::SetIdx( sal_uLong nIdx
)
3382 if( pPLCF
) pPLCF
->SetIdx( nIdx
);
3385 bool WW8PLCFx_SEPX::SeekPos(WW8_CP nCpPos
)
3387 return pPLCF
? pPLCF
->SeekPos( nCpPos
) : 0;
3390 WW8_CP
WW8PLCFx_SEPX::Where()
3392 return pPLCF
? pPLCF
->Where() : 0;
3395 void WW8PLCFx_SEPX::GetSprms(WW8PLCFxDesc
* p
)
3397 if( !pPLCF
) return;
3401 p
->bRealLineEnd
= false;
3402 if (!pPLCF
->Get( p
->nStartPos
, p
->nEndPos
, pData
))
3404 p
->nStartPos
= p
->nEndPos
= WW8_CP_MAX
; // PLCF completely processed
3410 sal_uInt32 nPo
= SVBT32ToUInt32( (sal_uInt8
*)pData
+2 );
3411 if (nPo
== 0xFFFFFFFF)
3413 p
->nStartPos
= p
->nEndPos
= WW8_CP_MAX
; // Sepx empty
3422 if (GetFIBVersion() <= ww::eWW2
) // eWW6 ?, docs say yes, but...
3431 if( nSprmSiz
> nArrMax
)
3434 nArrMax
= nSprmSiz
; // Get more memory
3435 pSprms
= new sal_uInt8
[nArrMax
];
3437 nSprmSiz
= pStrm
->Read(pSprms
, nSprmSiz
); // read Sprms
3439 p
->nSprmsLen
= nSprmSiz
;
3440 p
->pMemPos
= pSprms
; // return Position
3445 void WW8PLCFx_SEPX::advance()
3451 const sal_uInt8
* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId
) const
3453 return HasSprm( nId
, pSprms
, nSprmSiz
);
3456 const sal_uInt8
* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId
, const sal_uInt8
* pOtherSprms
,
3457 long nOtherSprmSiz
) const
3459 const sal_uInt8
*pRet
= 0;
3462 WW8SprmIter
aIter(pOtherSprms
, nOtherSprmSiz
, maSprmParser
);
3463 pRet
= aIter
.FindSprm(nId
);
3468 bool WW8PLCFx_SEPX::Find4Sprms(sal_uInt16 nId1
,sal_uInt16 nId2
,sal_uInt16 nId3
,sal_uInt16 nId4
,
3469 sal_uInt8
*& p1
, sal_uInt8
*& p2
, sal_uInt8
*& p3
, sal_uInt8
*& p4
) const
3474 bool bFound
= false;
3480 sal_uInt8
* pSp
= pSprms
;
3482 while (i
+ maSprmParser
.MinSprmLen() <= nSprmSiz
)
3485 sal_uInt16 nAktId
= maSprmParser
.GetSprmId(pSp
);
3487 if( nAktId
== nId1
)
3488 p1
= pSp
+ maSprmParser
.DistanceToData(nId1
);
3489 else if( nAktId
== nId2
)
3490 p2
= pSp
+ maSprmParser
.DistanceToData(nId2
);
3491 else if( nAktId
== nId3
)
3492 p3
= pSp
+ maSprmParser
.DistanceToData(nId3
);
3493 else if( nAktId
== nId4
)
3494 p4
= pSp
+ maSprmParser
.DistanceToData(nId4
);
3498 // increment pointer so that it points to next SPRM
3499 sal_uInt16 x
= maSprmParser
.GetSprmSize(nAktId
, pSp
);
3506 const sal_uInt8
* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId
, sal_uInt8 n2nd
) const
3511 sal_uInt8
* pSp
= pSprms
;
3514 while (i
+ maSprmParser
.MinSprmLen() <= nSprmSiz
)
3517 sal_uInt16 nAktId
= maSprmParser
.GetSprmId(pSp
);
3520 sal_uInt8
*pRet
= pSp
+ maSprmParser
.DistanceToData(nId
);
3524 // increment pointer so that it points to next SPRM
3525 sal_uInt16 x
= maSprmParser
.GetSprmSize(nAktId
, pSp
);
3530 return 0; // Sprm not found
3534 WW8PLCFx_SubDoc::WW8PLCFx_SubDoc(SvStream
* pSt
, ww::WordVersion eVersion
,
3535 WW8_CP nStartCp
, long nFcRef
, long nLenRef
, long nFcTxt
, long nLenTxt
,
3537 : WW8PLCFx(eVersion
, true), pRef(0), pTxt(0)
3539 if( nLenRef
&& nLenTxt
)
3541 pRef
= new WW8PLCF(*pSt
, nFcRef
, nLenRef
, nStruct
, nStartCp
);
3542 pTxt
= new WW8PLCF(*pSt
, nFcTxt
, nLenTxt
, 0, nStartCp
);
3546 WW8PLCFx_SubDoc::~WW8PLCFx_SubDoc()
3552 sal_uLong
WW8PLCFx_SubDoc::GetIdx() const
3554 // Probably pTxt ... no need for it
3556 return ( pRef
->GetIdx() << 16 | pTxt
->GetIdx() );
3560 void WW8PLCFx_SubDoc::SetIdx( sal_uLong nIdx
)
3564 pRef
->SetIdx( nIdx
>> 16 );
3565 // Probably pTxt ... no need for it
3566 pTxt
->SetIdx( nIdx
& 0xFFFF );
3570 bool WW8PLCFx_SubDoc::SeekPos( WW8_CP nCpPos
)
3572 return ( pRef
) ? pRef
->SeekPos( nCpPos
) : false;
3575 WW8_CP
WW8PLCFx_SubDoc::Where()
3577 return ( pRef
) ? pRef
->Where() : WW8_CP_MAX
;
3580 void WW8PLCFx_SubDoc::GetSprms(WW8PLCFxDesc
* p
)
3582 p
->nStartPos
= p
->nEndPos
= WW8_CP_MAX
;
3585 p
->bRealLineEnd
= false;
3590 sal_uLong nNr
= pRef
->GetIdx();
3594 if (!pRef
->Get(p
->nStartPos
, nFoo
, pData
))
3596 p
->nEndPos
= p
->nStartPos
= WW8_CP_MAX
;
3600 p
->nEndPos
= p
->nStartPos
+ 1;
3607 if (!pTxt
->Get(p
->nCp2OrIdx
, p
->nSprmsLen
, pData
))
3609 p
->nEndPos
= p
->nStartPos
= WW8_CP_MAX
;
3614 p
->nSprmsLen
-= p
->nCp2OrIdx
;
3617 void WW8PLCFx_SubDoc::advance()
3627 WW8PLCFx_FLD::WW8PLCFx_FLD( SvStream
* pSt
, const WW8Fib
& rMyFib
, short nType
)
3628 : WW8PLCFx(rMyFib
.GetFIBVersion(), true), pPLCF(0), rFib(rMyFib
)
3635 nFc
= rFib
.fcPlcffldHdr
;
3636 nLen
= rFib
.lcbPlcffldHdr
;
3639 nFc
= rFib
.fcPlcffldFtn
;
3640 nLen
= rFib
.lcbPlcffldFtn
;
3643 nFc
= rFib
.fcPlcffldEdn
;
3644 nLen
= rFib
.lcbPlcffldEdn
;
3647 nFc
= rFib
.fcPlcffldAtn
;
3648 nLen
= rFib
.lcbPlcffldAtn
;
3651 nFc
= rFib
.fcPlcffldTxbx
;
3652 nLen
= rFib
.lcbPlcffldTxbx
;
3655 nFc
= rFib
.fcPlcffldHdrTxbx
;
3656 nLen
= rFib
.lcbPlcffldHdrTxbx
;
3659 nFc
= rFib
.fcPlcffldMom
;
3660 nLen
= rFib
.lcbPlcffldMom
;
3665 pPLCF
= new WW8PLCFspecial( pSt
, nFc
, nLen
, 2 );
3668 WW8PLCFx_FLD::~WW8PLCFx_FLD()
3673 sal_uLong
WW8PLCFx_FLD::GetIdx() const
3675 return pPLCF
? pPLCF
->GetIdx() : 0;
3678 void WW8PLCFx_FLD::SetIdx( sal_uLong nIdx
)
3681 pPLCF
->SetIdx( nIdx
);
3684 bool WW8PLCFx_FLD::SeekPos(WW8_CP nCpPos
)
3686 return pPLCF
? pPLCF
->SeekPosExact( nCpPos
) : false;
3689 WW8_CP
WW8PLCFx_FLD::Where()
3691 return pPLCF
? pPLCF
->Where() : WW8_CP_MAX
;
3694 bool WW8PLCFx_FLD::StartPosIsFieldStart()
3699 (!pPLCF
|| !pPLCF
->Get(nTest
, pData
) ||
3700 ((((sal_uInt8
*)pData
)[0] & 0x1f) != 0x13))
3706 bool WW8PLCFx_FLD::EndPosIsFieldEnd()
3712 long n
= pPLCF
->GetIdx();
3718 if ( pPLCF
->Get(nTest
, pData
) && ((((sal_uInt8
*)pData
)[0] & 0x1f) == 0x15) )
3727 void WW8PLCFx_FLD::GetSprms(WW8PLCFxDesc
* p
)
3729 p
->nStartPos
= p
->nEndPos
= WW8_CP_MAX
;
3732 p
->bRealLineEnd
= false;
3736 p
->nStartPos
= WW8_CP_MAX
; // there are no fields
3740 long n
= pPLCF
->GetIdx();
3744 if (!pPLCF
->Get(nP
, pData
)) // end of PLCFspecial?
3746 p
->nStartPos
= WW8_CP_MAX
; // PLCF completely processed
3753 if (!pPLCF
->Get(nP
, pData
)) // end of PLCFspecial?
3755 p
->nStartPos
= WW8_CP_MAX
; // PLCF completely processed
3763 p
->nCp2OrIdx
= pPLCF
->GetIdx();
3766 void WW8PLCFx_FLD::advance()
3771 bool WW8PLCFx_FLD::GetPara(long nIdx
, WW8FieldDesc
& rF
)
3773 OSL_ENSURE( pPLCF
, "Call without PLCFspecial field" );
3777 long n
= pPLCF
->GetIdx();
3778 pPLCF
->SetIdx(nIdx
);
3780 bool bOk
= WW8GetFieldPara(*pPLCF
, rF
);
3788 /* to be optimized like this: */
3789 void WW8ReadSTTBF(bool bVer8
, SvStream
& rStrm
, sal_uInt32 nStart
, sal_Int32 nLen
,
3790 sal_uInt16 nExtraLen
, rtl_TextEncoding eCS
, std::vector
<String
> &rArray
,
3791 std::vector
<ww::bytes
>* pExtraArray
, ::std::vector
<String
>* pValueArray
)
3793 if (nLen
==0) // Handle Empty STTBF
3796 sal_Size nOldPos
= rStrm
.Tell();
3797 if (checkSeek(rStrm
, nStart
))
3799 sal_uInt16
nLen2(0);
3800 rStrm
>> nLen2
; // bVer67: total length of structure
3801 // bVer8 : count of strings
3805 sal_uInt16
nStrings(0);
3806 bool bUnicode
= (0xFFFF == nLen2
);
3814 for (sal_uInt16 i
=0; i
< nStrings
; ++i
)
3817 rArray
.push_back(read_uInt16_PascalString(rStrm
));
3820 OString aTmp
= read_lenPrefixed_uInt8s_ToOString
<sal_uInt8
>(rStrm
);
3821 rArray
.push_back(OStringToOUString(aTmp
, eCS
));
3824 // Skip the extra data
3829 ww::bytes extraData
;
3830 for (sal_uInt16 j
= 0; j
< nExtraLen
; ++j
)
3834 extraData
.push_back(iTmp
);
3836 pExtraArray
->push_back(extraData
);
3839 rStrm
.SeekRel( nExtraLen
);
3842 // read the value of the document variables, if requested.
3845 for (sal_uInt16 i
=0; i
< nStrings
; ++i
)
3848 pValueArray
->push_back(read_uInt16_PascalString(rStrm
));
3851 OString aTmp
= read_lenPrefixed_uInt8s_ToOString
<sal_uInt8
>(rStrm
);
3852 pValueArray
->push_back(OStringToOUString(aTmp
, eCS
));
3861 OSL_ENSURE(nLen2
== nLen
,
3862 "Fib length and read length are different");
3863 if (nLen
> USHRT_MAX
)
3867 nLen2
= static_cast<sal_uInt16
>(nLen
);
3869 sal_uLong nRead
= 0;
3870 for( nLen2
-= 2; nRead
< nLen2
; )
3872 sal_uInt8
nBChar(0);
3877 OString aTmp
= read_uInt8s_ToOString(rStrm
, nBChar
);
3878 nRead
+= aTmp
.getLength();
3879 rArray
.push_back(OStringToOUString(aTmp
, eCS
));
3882 rArray
.push_back(aEmptyStr
);
3884 // Skip the extra data (for bVer67 versions this must come from
3885 // external knowledge)
3890 ww::bytes extraData
;
3891 for (sal_uInt16 i
=0;i
< nExtraLen
;++i
)
3895 extraData
.push_back(iTmp
);
3897 pExtraArray
->push_back(extraData
);
3900 rStrm
.SeekRel( nExtraLen
);
3906 rStrm
.Seek(nOldPos
);
3909 WW8PLCFx_Book::WW8PLCFx_Book(SvStream
* pTblSt
, const WW8Fib
& rFib
)
3910 : WW8PLCFx(rFib
.GetFIBVersion(), false), pStatus(0), nIsEnd(0), nBookmarkId(1)
3912 if( !rFib
.fcPlcfbkf
|| !rFib
.lcbPlcfbkf
|| !rFib
.fcPlcfbkl
||
3913 !rFib
.lcbPlcfbkl
|| !rFib
.fcSttbfbkmk
|| !rFib
.lcbSttbfbkmk
)
3915 pBook
[0] = pBook
[1] = 0;
3920 pBook
[0] = new WW8PLCFspecial(pTblSt
,rFib
.fcPlcfbkf
,rFib
.lcbPlcfbkf
,4);
3922 pBook
[1] = new WW8PLCFspecial(pTblSt
,rFib
.fcPlcfbkl
,rFib
.lcbPlcfbkl
,0);
3924 rtl_TextEncoding eStructChrSet
= WW8Fib::GetFIBCharset(rFib
.chseTables
);
3926 WW8ReadSTTBF( (7 < rFib
.nVersion
), *pTblSt
, rFib
.fcSttbfbkmk
,
3927 rFib
.lcbSttbfbkmk
, 0, eStructChrSet
, aBookNames
);
3929 nIMax
= aBookNames
.size();
3931 if( pBook
[0]->GetIMax() < nIMax
) // Count of Bookmarks
3932 nIMax
= pBook
[0]->GetIMax();
3933 if( pBook
[1]->GetIMax() < nIMax
)
3934 nIMax
= pBook
[1]->GetIMax();
3935 pStatus
= new eBookStatus
[ nIMax
];
3936 memset( pStatus
, 0, nIMax
* sizeof( eBookStatus
) );
3940 WW8PLCFx_Book::~WW8PLCFx_Book()
3947 sal_uLong
WW8PLCFx_Book::GetIdx() const
3949 return nIMax
? pBook
[0]->GetIdx() : 0;
3952 void WW8PLCFx_Book::SetIdx( sal_uLong nI
)
3955 pBook
[0]->SetIdx( nI
);
3958 sal_uLong
WW8PLCFx_Book::GetIdx2() const
3960 return nIMax
? ( pBook
[1]->GetIdx() | ( ( nIsEnd
) ? 0x80000000 : 0 ) ) : 0;
3963 void WW8PLCFx_Book::SetIdx2( sal_uLong nI
)
3967 pBook
[1]->SetIdx( nI
& 0x7fffffff );
3968 nIsEnd
= (sal_uInt16
)( ( nI
>> 31 ) & 1 ); // 0 oder 1
3972 bool WW8PLCFx_Book::SeekPos(WW8_CP nCpPos
)
3977 bool bOk
= pBook
[0]->SeekPosExact( nCpPos
);
3978 bOk
&= pBook
[1]->SeekPosExact( nCpPos
);
3984 WW8_CP
WW8PLCFx_Book::Where()
3986 return pBook
[nIsEnd
]->Where();
3989 long WW8PLCFx_Book::GetNoSprms( WW8_CP
& rStart
, WW8_CP
& rEnd
, sal_Int32
& rLen
)
3995 if (!pBook
[0] || !pBook
[1] || !nIMax
|| (pBook
[nIsEnd
]->GetIdx()) >= nIMax
)
3997 rStart
= rEnd
= WW8_CP_MAX
;
4001 pBook
[nIsEnd
]->Get( rStart
, pData
); // query position
4002 return pBook
[nIsEnd
]->GetIdx();
4005 // Der Operator ++ hat eine Tuecke: Wenn 2 Bookmarks aneinandergrenzen, dann
4006 // sollte erst das Ende des ersten und dann der Anfang des 2. erreicht werden.
4007 // Liegen jedoch 2 Bookmarks der Laenge 0 aufeinander, *muss* von jedem Bookmark
4008 // erst der Anfang und dann das Ende gefunden werden.
4012 // ist noch nicht geloest, dabei muesste ich in den Anfangs- und Endindices
4013 // vor- und zurueckspringen, wobei ein weiterer Index oder ein Bitfeld
4014 // oder etwas aehnliches zum Merken der bereits abgearbeiteten Bookmarks
4016 void WW8PLCFx_Book::advance()
4018 if( pBook
[0] && pBook
[1] && nIMax
)
4020 (*pBook
[nIsEnd
]).advance();
4022 sal_uLong l0
= pBook
[0]->Where();
4023 sal_uLong l1
= pBook
[1]->Where();
4029 nIsEnd
= ( nIsEnd
) ? 0 : 1;
4033 long WW8PLCFx_Book::GetLen() const
4037 OSL_ENSURE( !this, "Incorrect call (1) of PLCF_Book::GetLen()" );
4042 if( !pBook
[0]->Get( nStartPos
, p
) )
4044 OSL_ENSURE( !this, "Incorrect call (2) of PLCF_Book::GetLen()" );
4047 sal_uInt16 nEndIdx
= SVBT16ToShort( *((SVBT16
*)p
) );
4048 long nNum
= pBook
[1]->GetPos( nEndIdx
);
4053 void WW8PLCFx_Book::SetStatus(sal_uInt16 nIndex
, eBookStatus eStat
)
4055 OSL_ENSURE(nIndex
< nIMax
, "set status of non existing bookmark!");
4056 pStatus
[nIndex
] = (eBookStatus
)( pStatus
[nIndex
] | eStat
);
4059 eBookStatus
WW8PLCFx_Book::GetStatus() const
4063 long nEndIdx
= GetHandle();
4064 return ( nEndIdx
< nIMax
) ? pStatus
[nEndIdx
] : BOOK_NORMAL
;
4067 long WW8PLCFx_Book::GetHandle() const
4069 if( !pBook
[0] || !pBook
[1] )
4073 return pBook
[1]->GetIdx();
4076 if (const void* p
= pBook
[0]->GetData(pBook
[0]->GetIdx()))
4077 return SVBT16ToShort( *((SVBT16
*)p
) );
4083 String
WW8PLCFx_Book::GetBookmark(long nStart
,long nEnd
, sal_uInt16
&nIndex
)
4085 bool bFound
= false;
4087 if( pBook
[0] && pBook
[1] )
4089 WW8_CP nStartAkt
, nEndAkt
;
4095 if( pBook
[0]->GetData( i
, nStartAkt
, p
) && p
)
4096 nEndIdx
= SVBT16ToShort( *((SVBT16
*)p
) );
4099 OSL_ENSURE( !this, "Bookmark-EndIdx not readable" );
4103 nEndAkt
= pBook
[1]->GetPos( nEndIdx
);
4105 if ((nStartAkt
>= nStart
) && (nEndAkt
<= nEnd
))
4113 while (i
< pBook
[0]->GetIMax());
4115 return bFound
? aBookNames
[i
] : aEmptyStr
;
4118 OUString
WW8PLCFx_Book::GetUniqueBookmarkName(const OUString
&rSuggestedName
)
4120 OUString
aRet(rSuggestedName
.isEmpty() ? OUString("Unnamed") : rSuggestedName
);
4122 while (i
< aBookNames
.size())
4124 if (aRet
.equals(aBookNames
[i
]))
4126 sal_Int32 len
= aRet
.getLength();
4127 sal_Int32 p
= len
- 1;
4128 while (p
> 0 && aRet
[p
] >= '0' && aRet
[p
] <= '9')
4130 aRet
= aRet
.copy(0, p
+1) + OUString::valueOf(nBookmarkId
++);
4131 i
= 0; // start search from beginning
4139 bool WW8PLCFx_Book::MapName(String
& rName
)
4141 if( !pBook
[0] || !pBook
[1] )
4144 bool bFound
= false;
4148 if (COMPARE_EQUAL
== rName
.CompareIgnoreCaseToAscii(aBookNames
[i
]))
4150 rName
= aBookNames
[i
];
4155 while (!bFound
&& i
< pBook
[0]->GetIMax());
4159 const String
* WW8PLCFx_Book::GetName() const
4161 const String
*pRet
= 0;
4162 if (!nIsEnd
&& (pBook
[0]->GetIdx() < nIMax
))
4163 pRet
= &(aBookNames
[pBook
[0]->GetIdx()]);
4169 // Am Ende eines Absatzes reichen bei WW6 die Attribute bis hinter das <CR>.
4170 // Das wird fuer die Verwendung mit dem SW um 1 Zeichen zurueckgesetzt, wenn
4171 // dadurch kein AErger zu erwarten ist.
4172 void WW8PLCFMan::AdjustEnds( WW8PLCFxDesc
& rDesc
)
4174 //Store old end position for supercool new property finder that uses
4175 //cp instead of fc's as nature intended
4176 rDesc
.nOrigEndPos
= rDesc
.nEndPos
;
4177 rDesc
.nOrigStartPos
= rDesc
.nStartPos
;
4180 Normally given ^XXX{para end}^ we don't actually insert a para end
4181 character into the document, so we clip the para end property one to the
4182 left to make the para properties end when the paragraph text does. In a
4183 drawing textbox we actually do insert a para end character, so we don't
4184 clip it. Making the para end properties end after the para end char.
4186 if (GetDoingDrawTextBox())
4189 if ( (&rDesc
== pPap
) && rDesc
.bRealLineEnd
)
4191 if ( pPap
->nEndPos
!= WW8_CP_MAX
) // Para adjust
4193 nLineEnd
= pPap
->nEndPos
;// nLineEnd zeigt *hinter* das <CR>
4194 pPap
->nEndPos
--; // Absatzende um 1 Zeichen verkuerzen
4196 // gibt es bereits ein CharAttr-Ende das auf das jetzige
4197 // Absatzende zeigt ? ... dann auch um 1 Zeichen verkuerzen
4198 if (pChp
->nEndPos
== nLineEnd
)
4201 // gibt es bereits ein Sep-Ende, das auf das jetzige Absatzende
4202 // zeigt ? ... dann auch um 1 Zeichen verkuerzen
4203 if( pSep
->nEndPos
== nLineEnd
)
4207 else if ( (&rDesc
== pChp
) || (&rDesc
== pSep
) )
4209 // Char Adjust oder Sep Adjust Wenn Ende Char-Attr == Absatzende ...
4210 if( (rDesc
.nEndPos
== nLineEnd
) && (rDesc
.nEndPos
> rDesc
.nStartPos
) )
4211 rDesc
.nEndPos
--; // ... dann um 1 Zeichen verkuerzen
4215 void WW8PLCFxDesc::ReduceByOffset()
4217 OSL_ENSURE((WW8_CP_MAX
== nStartPos
) || (nStartPos
<= nEndPos
),
4218 "Attr-Anfang und -Ende ueber Kreuz" );
4220 if( nStartPos
!= WW8_CP_MAX
)
4224 Force the property change to happen at the beginning of this
4225 subdocument, same as in GetNewNoSprms, except that the target type is
4226 attributes attached to a piece that might span subdocument boundaries
4228 if (nCpOfs
> nStartPos
)
4231 nStartPos
-= nCpOfs
;
4233 if( nEndPos
!= WW8_CP_MAX
)
4235 OSL_ENSURE(nCpOfs
<= nEndPos
,
4236 "oh oh, so much for the subdocument piece theory");
4241 void WW8PLCFMan::GetNewSprms( WW8PLCFxDesc
& rDesc
)
4243 rDesc
.pPLCFx
->GetSprms(&rDesc
);
4244 rDesc
.ReduceByOffset();
4246 rDesc
.bFirstSprm
= true;
4247 AdjustEnds( rDesc
);
4248 rDesc
.nOrigSprmsLen
= rDesc
.nSprmsLen
;
4251 void WW8PLCFMan::GetNewNoSprms( WW8PLCFxDesc
& rDesc
)
4253 rDesc
.nCp2OrIdx
= rDesc
.pPLCFx
->GetNoSprms(rDesc
.nStartPos
, rDesc
.nEndPos
,
4256 OSL_ENSURE((WW8_CP_MAX
== rDesc
.nStartPos
) || (rDesc
.nStartPos
<= rDesc
.nEndPos
),
4257 "Attr-Anfang und -Ende ueber Kreuz" );
4259 rDesc
.ReduceByOffset();
4261 rDesc
.bFirstSprm
= true;
4262 rDesc
.nOrigSprmsLen
= rDesc
.nSprmsLen
;
4265 sal_uInt16
WW8PLCFMan::GetId(const WW8PLCFxDesc
* p
) const
4267 sal_uInt16 nId
= 0; // Id = 0 for empty attributes
4277 else if (p
->nSprmsLen
>= maSprmParser
.MinSprmLen())
4278 nId
= maSprmParser
.GetSprmId(p
->pMemPos
);
4283 WW8PLCFMan::WW8PLCFMan(WW8ScannerBase
* pBase
, ManTypes nType
, long nStartCp
,
4284 bool bDoingDrawTextBox
)
4285 : maSprmParser(pBase
->pWw8Fib
->GetFIBVersion()),
4286 mbDoingDrawTextBox(bDoingDrawTextBox
)
4288 pWwFib
= pBase
->pWw8Fib
;
4290 nLastWhereIdxCp
= 0;
4291 memset( aD
, 0, sizeof( aD
) );
4292 nLineEnd
= WW8_CP_MAX
;
4296 if( MAN_MAINTEXT
== nType
)
4298 // Suchreihenfolge der Attribute
4299 nPLCF
= MAN_ANZ_PLCF
;
4306 pPcd
= ( pBase
->pPLCFx_PCD
) ? &aD
[5] : 0;
4307 //pPcdA index == pPcd index + 1
4308 pPcdA
= ( pBase
->pPLCFx_PCDAttrs
) ? &aD
[6] : 0;
4314 pSep
->pPLCFx
= pBase
->pSepPLCF
;
4315 pFtn
->pPLCFx
= pBase
->pFtnPLCF
;
4316 pEdn
->pPLCFx
= pBase
->pEdnPLCF
;
4317 pBkm
->pPLCFx
= pBase
->pBook
;
4318 pAnd
->pPLCFx
= pBase
->pAndPLCF
;
4323 // Suchreihenfolge der Attribute
4326 pBkm
= ( pBase
->pBook
) ? &aD
[1] : 0;
4328 pPcd
= ( pBase
->pPLCFx_PCD
) ? &aD
[2] : 0;
4329 //pPcdA index == pPcd index + 1
4330 pPcdA
= ( pBase
->pPLCFx_PCDAttrs
) ? &aD
[3] : 0;
4334 pSep
= &aD
[6]; // Dummy
4336 pAnd
= pFtn
= pEdn
= 0; // unbenutzt bei SpezText
4339 pChp
->pPLCFx
= pBase
->pChpPLCF
;
4340 pPap
->pPLCFx
= pBase
->pPapPLCF
;
4342 pPcd
->pPLCFx
= pBase
->pPLCFx_PCD
;
4344 pPcdA
->pPLCFx
= pBase
->pPLCFx_PCDAttrs
;
4346 pBkm
->pPLCFx
= pBase
->pBook
;
4348 pMagicTables
= pBase
->pMagicTables
;
4349 pSubdocs
= pBase
->pSubdocs
;
4350 pExtendedAtrds
= pBase
->pExtendedAtrds
;
4352 switch( nType
) // Feld-Initialisierung
4355 pFld
->pPLCFx
= pBase
->pFldHdFtPLCF
;
4356 pFdoa
= pBase
->pHdFtFdoa
;
4357 pTxbx
= pBase
->pHdFtTxbx
;
4358 pTxbxBkd
= pBase
->pHdFtTxbxBkd
;
4361 pFld
->pPLCFx
= pBase
->pFldFtnPLCF
;
4362 pFdoa
= pTxbx
= pTxbxBkd
= 0;
4365 pFld
->pPLCFx
= pBase
->pFldEdnPLCF
;
4366 pFdoa
= pTxbx
= pTxbxBkd
= 0;
4369 pFld
->pPLCFx
= pBase
->pFldAndPLCF
;
4370 pFdoa
= pTxbx
= pTxbxBkd
= 0;
4373 pFld
->pPLCFx
= pBase
->pFldTxbxPLCF
;
4374 pTxbx
= pBase
->pMainTxbx
;
4375 pTxbxBkd
= pBase
->pMainTxbxBkd
;
4379 pFld
->pPLCFx
= pBase
->pFldTxbxHdFtPLCF
;
4380 pTxbx
= pBase
->pHdFtTxbx
;
4381 pTxbxBkd
= pBase
->pHdFtTxbxBkd
;
4385 pFld
->pPLCFx
= pBase
->pFldPLCF
;
4386 pFdoa
= pBase
->pMainFdoa
;
4387 pTxbx
= pBase
->pMainTxbx
;
4388 pTxbxBkd
= pBase
->pMainTxbxBkd
;
4392 nCpO
= pWwFib
->GetBaseCp(nType
);
4394 if( nStartCp
|| nCpO
)
4395 SeekPos( nStartCp
); // PLCFe auf Text-StartPos einstellen
4397 // initialisieren der Member-Vars Low-Level
4398 GetChpPLCF()->ResetAttrStartEnd();
4399 GetPapPLCF()->ResetAttrStartEnd();
4400 for( i
=0; i
< nPLCF
; i
++)
4402 WW8PLCFxDesc
* p
= &aD
[i
];
4406 For subdocuments we modify the cp of properties to be relative to
4407 the beginning of subdocuments, we should also do the same for
4408 piecetable changes, and piecetable properties, otherwise a piece
4409 change that happens in a subdocument is lost.
4411 p
->nCpOfs
= ( p
== pChp
|| p
== pPap
|| p
== pBkm
|| p
== pPcd
||
4412 p
== pPcdA
) ? nCpO
: 0;
4415 p
->bFirstSprm
= false;
4418 if ((p
== pChp
) || (p
== pPap
))
4419 p
->nStartPos
= p
->nEndPos
= nStartCp
;
4421 p
->nStartPos
= p
->nEndPos
= WW8_CP_MAX
;
4424 // initialisieren der Member-Vars High-Level
4425 for( i
=0; i
<nPLCF
; i
++){
4426 WW8PLCFxDesc
* p
= &aD
[i
];
4430 p
->nStartPos
= p
->nEndPos
= WW8_CP_MAX
;
4434 if( p
->pPLCFx
->IsSprm() )
4436 // Vorsicht: nEndPos muss bereits
4437 p
->pIdStk
= new std::stack
<sal_uInt16
>;
4438 if ((p
== pChp
) || (p
== pPap
))
4440 WW8_CP nTemp
= p
->nEndPos
+p
->nCpOfs
;
4443 p
->nStartPos
= nTemp
;
4444 if (!(*p
->pPLCFx
).SeekPos(p
->nStartPos
))
4445 p
->nEndPos
= p
->nStartPos
= WW8_CP_MAX
;
4450 GetNewSprms( *p
); // bei allen PLCFen initialisiert sein
4452 else if( p
->pPLCFx
)
4453 GetNewNoSprms( *p
);
4457 WW8PLCFMan::~WW8PLCFMan()
4459 for( sal_uInt16 i
=0; i
<nPLCF
; i
++)
4460 delete aD
[i
].pIdStk
;
4463 // 0. welche Attr.-Klasse,
4464 // 1. ob ein Attr.-Start ist,
4465 // 2. CP, wo ist naechste Attr.-Aenderung
4466 sal_uInt16
WW8PLCFMan::WhereIdx(bool* pbStart
, long* pPos
) const
4468 OSL_ENSURE(nPLCF
,"What the hell");
4469 long nNext
= LONG_MAX
; // SuchReihenfolge:
4470 sal_uInt16 nNextIdx
= nPLCF
;// first ending found ( CHP, PAP, ( SEP ) ),
4471 bool bStart
= true; // dann Anfaenge finden ( ( SEP ), PAP, CHP )
4473 const WW8PLCFxDesc
* pD
;
4474 for (i
=0; i
< nPLCF
; i
++)
4479 if( (pD
->nEndPos
< nNext
) && (pD
->nStartPos
== WW8_CP_MAX
) )
4481 // sonst ist Anfang = Ende
4482 nNext
= pD
->nEndPos
;
4488 for (i
=nPLCF
; i
> 0; i
--)
4493 if( pD
->nStartPos
< nNext
)
4495 nNext
= pD
->nStartPos
;
4508 // gibt die CP-Pos der naechsten Attribut-Aenderung zurueck
4509 WW8_CP
WW8PLCFMan::Where() const
4516 void WW8PLCFMan::SeekPos( long nNewCp
)
4518 pChp
->pPLCFx
->SeekPos( nNewCp
+ nCpO
); // Attribute neu
4519 pPap
->pPLCFx
->SeekPos( nNewCp
+ nCpO
); // aufsetzen
4520 pFld
->pPLCFx
->SeekPos( nNewCp
);
4522 pPcd
->pPLCFx
->SeekPos( nNewCp
+ nCpO
);
4524 pBkm
->pPLCFx
->SeekPos( nNewCp
+ nCpO
);
4527 void WW8PLCFMan::SaveAllPLCFx( WW8PLCFxSaveAll
& rSave
) const
4531 pPcd
->Save( rSave
.aS
[n
++] );
4533 pPcdA
->Save( rSave
.aS
[n
++] );
4535 for(i
=0; i
<nPLCF
; ++i
)
4536 if( pPcd
!= &aD
[i
] && pPcdA
!= &aD
[i
] )
4537 aD
[i
].Save( rSave
.aS
[n
++] );
4540 void WW8PLCFMan::RestoreAllPLCFx( const WW8PLCFxSaveAll
& rSave
)
4544 pPcd
->Restore( rSave
.aS
[n
++] );
4546 pPcdA
->Restore( rSave
.aS
[n
++] );
4548 for(i
=0; i
<nPLCF
; ++i
)
4549 if( pPcd
!= &aD
[i
] && pPcdA
!= &aD
[i
] )
4550 aD
[i
].Restore( rSave
.aS
[n
++] );
4553 void WW8PLCFMan::GetSprmStart( short nIdx
, WW8PLCFManResult
* pRes
) const
4555 memset( pRes
, 0, sizeof( WW8PLCFManResult
) );
4561 const WW8PLCFxDesc
* p
= &aD
[nIdx
];
4563 // first Sprm in a Group
4567 pRes
->nFlags
|= MAN_MASK_NEW_PAP
;
4568 else if( p
== pSep
)
4569 pRes
->nFlags
|= MAN_MASK_NEW_SEP
;
4571 pRes
->pMemPos
= p
->pMemPos
;
4572 pRes
->nSprmId
= GetId(p
);
4573 pRes
->nCp2OrIdx
= p
->nCp2OrIdx
;
4574 if ((p
== pFtn
) || (p
== pEdn
) || (p
== pAnd
))
4575 pRes
->nMemLen
= p
->nSprmsLen
;
4576 else if (p
->nSprmsLen
>= maSprmParser
.MinSprmLen()) //Normal
4578 // Length of actual sprm
4579 pRes
->nMemLen
= maSprmParser
.GetSprmSize(pRes
->nSprmId
, pRes
->pMemPos
);
4583 void WW8PLCFMan::GetSprmEnd( short nIdx
, WW8PLCFManResult
* pRes
) const
4585 memset( pRes
, 0, sizeof( WW8PLCFManResult
) );
4587 const WW8PLCFxDesc
* p
= &aD
[nIdx
];
4589 if (!(p
->pIdStk
->empty()))
4590 pRes
->nSprmId
= p
->pIdStk
->top(); // get end position
4593 OSL_ENSURE( !this, "No Id on the Stack" );
4598 void WW8PLCFMan::GetNoSprmStart( short nIdx
, WW8PLCFManResult
* pRes
) const
4600 const WW8PLCFxDesc
* p
= &aD
[nIdx
];
4602 pRes
->nCpPos
= p
->nStartPos
;
4603 pRes
->nMemLen
= p
->nSprmsLen
;
4604 pRes
->nCp2OrIdx
= p
->nCp2OrIdx
;
4607 pRes
->nSprmId
= eFLD
;
4608 else if( p
== pFtn
)
4609 pRes
->nSprmId
= eFTN
;
4610 else if( p
== pEdn
)
4611 pRes
->nSprmId
= eEDN
;
4612 else if( p
== pBkm
)
4613 pRes
->nSprmId
= eBKN
;
4614 else if( p
== pAnd
)
4615 pRes
->nSprmId
= eAND
;
4616 else if( p
== pPcd
)
4618 //We slave the piece table attributes to the piece table, the piece
4619 //table attribute iterator contains the sprms for this piece.
4620 GetSprmStart( nIdx
+1, pRes
);
4623 pRes
->nSprmId
= 0; // default: not found
4626 void WW8PLCFMan::GetNoSprmEnd( short nIdx
, WW8PLCFManResult
* pRes
) const
4628 pRes
->nMemLen
= -1; // Ende-Kennzeichen
4630 if( &aD
[nIdx
] == pBkm
)
4631 pRes
->nSprmId
= eBKN
;
4632 else if( &aD
[nIdx
] == pPcd
)
4634 //We slave the piece table attributes to the piece table, the piece
4635 //table attribute iterator contains the sprms for this piece.
4636 GetSprmEnd( nIdx
+1, pRes
);
4642 bool WW8PLCFMan::TransferOpenSprms(std::stack
<sal_uInt16
> &rStack
)
4644 for (int i
= 0; i
< nPLCF
; ++i
)
4646 WW8PLCFxDesc
* p
= &aD
[i
];
4647 if (!p
|| !p
->pIdStk
)
4649 while (!p
->pIdStk
->empty())
4651 rStack
.push(p
->pIdStk
->top());
4655 return rStack
.empty();
4658 void WW8PLCFMan::AdvSprm(short nIdx
, bool bStart
)
4660 WW8PLCFxDesc
* p
= &aD
[nIdx
]; // Sprm-Klasse(!) ermitteln
4662 p
->bFirstSprm
= false;
4665 sal_uInt16 nLastId
= GetId(p
);
4666 p
->pIdStk
->push(nLastId
); // merke Id fuer Attribut-Ende
4670 Pruefe, ob noch Sprm(s) abzuarbeiten sind
4674 // Length of last sprm
4675 sal_uInt16 nSprmL
= maSprmParser
.GetSprmSize(nLastId
, p
->pMemPos
);
4677 // Gesamtlaenge Sprms um SprmLaenge verringern
4678 p
->nSprmsLen
-= nSprmL
;
4680 // Pos des evtl. naechsten Sprm
4681 if (p
->nSprmsLen
< maSprmParser
.MinSprmLen())
4683 // sicherheitshalber auf Null setzen, da Enden folgen!
4688 p
->pMemPos
+= nSprmL
;
4693 if (p
->nSprmsLen
< maSprmParser
.MinSprmLen())
4694 p
->nStartPos
= WW8_CP_MAX
; // es folgen Enden
4698 if (!(p
->pIdStk
->empty()))
4700 if (p
->pIdStk
->empty())
4702 if ( (p
== pChp
) || (p
== pPap
) )
4706 p
->nStartPos
= p
->nOrigEndPos
+p
->nCpOfs
;
4709 On failed seek we have run out of sprms, probably. But if its
4710 a fastsaved file (has pPcd) then we may be just in a sprm free
4711 gap between pieces that have them, so set dirty flag in sprm
4712 finder to consider than.
4714 if (!(*p
->pPLCFx
).SeekPos(p
->nStartPos
))
4716 p
->nEndPos
= WW8_CP_MAX
;
4717 p
->pPLCFx
->SetDirty(true);
4719 if (!p
->pPLCFx
->GetDirty() || pPcd
)
4721 p
->pPLCFx
->SetDirty(false);
4725 To get the character and paragraph properties you first get
4726 the pap and chp and then apply the fastsaved pPcd properties
4727 to the range. If a pap or chp starts inside the pPcd range
4728 then we must bring the current pPcd range to a halt so as to
4729 end those sprms, then the pap/chp will be processed, and then
4730 we must force a restart of the pPcd on that pap/chp starting
4731 boundary. Doing that effectively means that the pPcd sprms will
4732 be applied to the new range. Not doing it means that the pPcd
4733 sprms will only be applied to the first pap/chp set of
4734 properties contained in the pap/chp range.
4736 So we bring the pPcd to a halt on this location here, by
4737 settings its end to the current start, then store the starting
4738 position of the current range to clipstart. The pPcd sprms
4739 will end as normal (albeit earlier than originally expected),
4740 and the existance of a clipstart will force the pPcd iterater
4741 to reread the current set of sprms instead of advancing to its
4742 next set. Then the clipstart will be set as the starting
4743 position which will force them to be applied directly after
4746 if (pPcd
&& ((p
->nStartPos
> pPcd
->nStartPos
) ||
4747 (pPcd
->nStartPos
== WW8_CP_MAX
)) &&
4748 (pPcd
->nEndPos
!= p
->nStartPos
))
4750 pPcd
->nEndPos
= p
->nStartPos
;
4751 ((WW8PLCFx_PCD
*)(pPcd
->pPLCFx
))->SetClipStart(
4758 p
->pPLCFx
->advance(); // next Group of Sprms
4759 p
->pMemPos
= 0; // !!!
4763 OSL_ENSURE( p
->nStartPos
<= p
->nEndPos
, "Attribut ueber Kreuz" );
4768 void WW8PLCFMan::AdvNoSprm(short nIdx
, bool bStart
)
4771 For the case of a piece table we slave the piece table attribute iterator
4772 to the piece table and access it through that only. They are two separate
4773 structures, but act together as one logical one. The attributes only go
4774 to the next entry when the piece changes
4776 WW8PLCFxDesc
* p
= &aD
[nIdx
];
4780 AdvSprm(nIdx
+1,bStart
);
4782 p
->nStartPos
= aD
[nIdx
+1].nStartPos
;
4785 if (aD
[nIdx
+1].pIdStk
->empty())
4787 WW8PLCFx_PCD
*pTemp
= (WW8PLCFx_PCD
*)(pPcd
->pPLCFx
);
4790 As per normal, go on to the next set of properties, i.e. we
4791 have traversed over to the next piece. With a clipstart set
4792 we are being told to reread the current piece sprms so as to
4793 reapply them to a new chp or pap range.
4795 if (pTemp
->GetClipStart() == -1)
4796 p
->pPLCFx
->advance();
4799 GetNewSprms( aD
[nIdx
+1] );
4800 GetNewNoSprms( *p
);
4801 if (pTemp
->GetClipStart() != -1)
4804 #i2325#, now we will force our starting position to the
4805 clipping start so as to force the application of these
4806 sprms after the current pap/chp sprms so as to apply the
4807 fastsave sprms to the current range.
4809 p
->nStartPos
= pTemp
->GetClipStart();
4810 pTemp
->SetClipStart(-1);
4816 { // NoSprm ohne Ende
4817 p
->pPLCFx
->advance();
4818 p
->pMemPos
= 0; // MemPos ungueltig
4820 GetNewNoSprms( *p
);
4824 void WW8PLCFMan::advance()
4827 sal_uInt16 nIdx
= WhereIdx(&bStart
);
4830 WW8PLCFxDesc
* p
= &aD
[nIdx
];
4832 p
->bFirstSprm
= true; // Default
4834 if( p
->pPLCFx
->IsSprm() )
4835 AdvSprm( nIdx
, bStart
);
4837 AdvNoSprm( nIdx
, bStart
);
4841 // Rueckgabe true fuer Anfang eines Attributes oder Fehler,
4842 // false fuer Ende d. Attr
4843 // Restliche Rueckgabewerte werden in der vom Aufrufer zu stellenden Struktur
4844 // WW8PclxManResults geliefert.
4845 bool WW8PLCFMan::Get(WW8PLCFManResult
* pRes
) const
4847 memset( pRes
, 0, sizeof( WW8PLCFManResult
) );
4849 sal_uInt16 nIdx
= WhereIdx(&bStart
);
4853 OSL_ENSURE( !this, "Position not found" );
4857 if( aD
[nIdx
].pPLCFx
->IsSprm() )
4861 GetSprmStart( nIdx
, pRes
);
4866 GetSprmEnd( nIdx
, pRes
);
4874 GetNoSprmStart( nIdx
, pRes
);
4879 GetNoSprmEnd( nIdx
, pRes
);
4885 sal_uInt16
WW8PLCFMan::GetColl() const
4888 return pPap
->pPLCFx
->GetIstd();
4891 OSL_ENSURE( !this, "GetColl ohne PLCF_Pap" );
4896 WW8PLCFx_FLD
* WW8PLCFMan::GetFld() const
4898 return (WW8PLCFx_FLD
*)pFld
->pPLCFx
;
4901 const sal_uInt8
* WW8PLCFMan::HasParaSprm( sal_uInt16 nId
) const
4903 return ((WW8PLCFx_Cp_FKP
*)pPap
->pPLCFx
)->HasSprm( nId
);
4906 const sal_uInt8
* WW8PLCFMan::HasCharSprm( sal_uInt16 nId
) const
4908 return ((WW8PLCFx_Cp_FKP
*)pChp
->pPLCFx
)->HasSprm( nId
);
4911 bool WW8PLCFMan::HasCharSprm(sal_uInt16 nId
,
4912 std::vector
<const sal_uInt8
*> &rResult
) const
4914 return ((WW8PLCFx_Cp_FKP
*)pChp
->pPLCFx
)->HasSprm(nId
, rResult
);
4919 void WW8PLCFx::Save( WW8PLCFxSave1
& rSave
) const
4921 rSave
.nPLCFxPos
= GetIdx();
4922 rSave
.nPLCFxPos2
= GetIdx2();
4923 rSave
.nPLCFxMemOfs
= 0;
4924 rSave
.nStartFC
= GetStartFc();
4927 void WW8PLCFx::Restore( const WW8PLCFxSave1
& rSave
)
4929 SetIdx( rSave
.nPLCFxPos
);
4930 SetIdx2( rSave
.nPLCFxPos2
);
4931 SetStartFc( rSave
.nStartFC
);
4934 sal_uLong
WW8PLCFx_Cp_FKP::GetIdx2() const
4939 void WW8PLCFx_Cp_FKP::SetIdx2( sal_uLong nIdx
)
4944 void WW8PLCFx_Cp_FKP::Save( WW8PLCFxSave1
& rSave
) const
4946 WW8PLCFx::Save( rSave
);
4948 rSave
.nAttrStart
= nAttrStart
;
4949 rSave
.nAttrEnd
= nAttrEnd
;
4950 rSave
.bLineEnd
= bLineEnd
;
4953 void WW8PLCFx_Cp_FKP::Restore( const WW8PLCFxSave1
& rSave
)
4955 WW8PLCFx::Restore( rSave
);
4957 nAttrStart
= rSave
.nAttrStart
;
4958 nAttrEnd
= rSave
.nAttrEnd
;
4959 bLineEnd
= rSave
.bLineEnd
;
4962 void WW8PLCFxDesc::Save( WW8PLCFxSave1
& rSave
) const
4966 pPLCFx
->Save( rSave
);
4967 if( pPLCFx
->IsSprm() )
4970 aD
.nStartPos
= nOrigStartPos
+nCpOfs
;
4971 aD
.nCpOfs
= rSave
.nCpOfs
= nCpOfs
;
4972 if (!(pPLCFx
->SeekPos(aD
.nStartPos
)))
4974 aD
.nEndPos
= WW8_CP_MAX
;
4975 pPLCFx
->SetDirty(true);
4977 pPLCFx
->GetSprms(&aD
);
4978 pPLCFx
->SetDirty(false);
4979 aD
.ReduceByOffset();
4980 rSave
.nStartCp
= aD
.nStartPos
;
4981 rSave
.nPLCFxMemOfs
= nOrigSprmsLen
- nSprmsLen
;
4986 void WW8PLCFxDesc::Restore( const WW8PLCFxSave1
& rSave
)
4990 pPLCFx
->Restore( rSave
);
4991 if( pPLCFx
->IsSprm() )
4994 aD
.nStartPos
= rSave
.nStartCp
+rSave
.nCpOfs
;
4995 nCpOfs
= aD
.nCpOfs
= rSave
.nCpOfs
;
4996 if (!(pPLCFx
->SeekPos(aD
.nStartPos
)))
4998 aD
.nEndPos
= WW8_CP_MAX
;
4999 pPLCFx
->SetDirty(true);
5001 pPLCFx
->GetSprms(&aD
);
5002 pPLCFx
->SetDirty(false);
5003 aD
.ReduceByOffset();
5004 pMemPos
= aD
.pMemPos
+ rSave
.nPLCFxMemOfs
;
5013 sal_uInt32
Readcb(SvStream
& rSt
, ww::WordVersion eVer
)
5015 if (eVer
<= ww::eWW2
)
5030 WW8_CP
WW8Fib::GetBaseCp(ManTypes nType
) const
5043 nOffset
= ccpText
+ ccpFtn
;
5046 A subdocument of this kind (MAN_MACRO) probably exists in some defunct
5047 version of MSWord, but now ccpMcr is always 0. If some example that
5048 uses this comes to light, this is the likely calculation required
5051 nOffset = ccpText + ccpFtn + ccpHdr;
5056 nOffset
= ccpText
+ ccpFtn
+ ccpHdr
+ ccpMcr
;
5059 nOffset
= ccpText
+ ccpFtn
+ ccpHdr
+ ccpMcr
+ ccpAtn
;
5062 nOffset
= ccpText
+ ccpFtn
+ ccpHdr
+ ccpMcr
+ ccpAtn
+ ccpEdn
;
5065 nOffset
= ccpText
+ ccpFtn
+ ccpHdr
+ ccpMcr
+ ccpAtn
+ ccpEdn
+
5072 ww::WordVersion
WW8Fib::GetFIBVersion() const
5074 ww::WordVersion eVer
= ww::eWW8
;
5076 * Word for Windows 2 I think (1.X might work too if anyone has an example.
5077 * Various pages claim that the fileformats of Word 1 and 2 for Windows are
5078 * equivalent to Word for Macintosh 4 and 5. On the other hand
5080 * wIdents for Word for Mac versions...
5083 * 0xFE37 for Word 4 et 5.
5086 * http://cmsdoc.cern.ch/documents/docformat/CMS_CERN_LetterHead.word is
5087 * claimed to be "Word 5 for Mac" by Office etc and has that wIdent, but
5088 * its format isn't the same as that of Word 2 for windows. Nor is it
5089 * the same as that of Word for DOS/PCWord 5
5091 if (wIdent
== 0xa5db)
5111 WW8Fib::WW8Fib(SvStream
& rSt
, sal_uInt8 nWantedVersion
, sal_uInt32 nOffset
)
5114 memset(this, 0, sizeof(*this));
5117 sal_uInt8 aVer8Bits1
; // nur ab WinWord 8 benutzt
5118 rSt
.Seek( nOffset
);
5120 Wunsch-Nr vermerken, File-Versionsnummer ermitteln
5121 und gegen Wunsch-Nr. checken !
5123 nVersion
= nWantedVersion
;
5127 if( 0 != rSt
.GetError() )
5131 // note: 6 stands for "6 OR 7", 7 stands for "ONLY 7"
5135 nFibMin
= 0x0065; // von 101 WinWord 6.0
5137 // und 103 WinWord 6.0 fuer Macintosh
5139 nFibMax
= 0x0069; // bis 105 WinWord 95
5142 nFibMin
= 0x0069; // von 105 WinWord 95
5143 nFibMax
= 0x0069; // bis 105 WinWord 95
5146 nFibMin
= 0x006A; // von 106 WinWord 97
5147 nFibMax
= 0x00c1; // bis 193 WinWord 97 (?)
5150 nFibMin
= 0; // Programm-Fehler!
5153 OSL_ENSURE( !this, "Es wurde vergessen, nVersion zu kodieren!" );
5156 if ( (nFib
< nFibMin
) || (nFib
> nFibMax
) )
5158 nFibError
= ERR_SWG_READ_ERROR
; // Error melden
5159 return; // und hopp raus!
5163 ww::WordVersion eVer
= GetFIBVersion();
5165 // Hilfs-Varis fuer Ver67:
5166 sal_Int16 pnChpFirst_Ver67
=0;
5167 sal_Int16 pnPapFirst_Ver67
=0;
5168 sal_Int16 cpnBteChp_Ver67
=0;
5169 sal_Int16 cpnBtePap_Ver67
=0;
5171 // und auf gehts: FIB einlesen
5180 rSt
>> aVer8Bits1
; // unter Ver67 nur leeres Reservefeld
5181 // Inhalt von aVer8Bits1
5183 // sal_uInt8 fMac :1;
5184 // sal_uInt8 fEmptySpecial :1;
5185 // sal_uInt8 fLoadOverridePage :1;
5186 // sal_uInt8 fFuturesavedUndo :1;
5187 // sal_uInt8 fWord97Saved :1;
5194 // Einschub fuer WW8 *****************************************************
5195 if (IsEightPlus(eVer
))
5199 // Marke: "rgsw" Beginning of the array of shorts
5200 rSt
>> wMagicCreated
;
5201 rSt
>> wMagicRevised
;
5202 rSt
>> wMagicCreatedPrivate
;
5203 rSt
>> wMagicRevisedPrivate
;
5204 rSt
.SeekRel( 9 * sizeof( sal_Int16
) );
5207 // dies sind die 9 unused Felder:
5208 && (bVer67 || WW8ReadINT16( rSt, pnFbpChpFirst_W6 )) // 1
5209 && (bVer67 || WW8ReadINT16( rSt, pnChpFirst_W6 )) // 2
5210 && (bVer67 || WW8ReadINT16( rSt, cpnBteChp_W6 )) // 3
5211 && (bVer67 || WW8ReadINT16( rSt, pnFbpPapFirst_W6 )) // 4
5212 && (bVer67 || WW8ReadINT16( rSt, pnPapFirst_W6 )) // 5
5213 && (bVer67 || WW8ReadINT16( rSt, cpnBtePap_W6 )) // 6
5214 && (bVer67 || WW8ReadINT16( rSt, pnFbpLvcFirst_W6 )) // 7
5215 && (bVer67 || WW8ReadINT16( rSt, pnLvcFirst_W6 )) // 8
5216 && (bVer67 || WW8ReadINT16( rSt, cpnBteLvc_W6 )) // 9
5222 // Ende des Einschubs fuer WW8 *******************************************
5224 // Marke: "rglw" Beginning of the array of longs
5227 // 2 Longs uebergehen, da unwichtiger Quatsch
5228 rSt
.SeekRel( 2 * sizeof( sal_Int32
) );
5230 // weitere 2 Longs nur bei Ver67 ueberspringen
5231 if (IsSevenMinus(eVer
))
5232 rSt
.SeekRel( 2 * sizeof( sal_Int32
) );
5243 // weiteres Long nur bei Ver67 ueberspringen
5244 if (IsSevenMinus(eVer
))
5245 rSt
.SeekRel( 1 * sizeof( sal_Int32
) );
5248 // Einschub fuer WW8 *****************************************************
5249 rSt
>> pnFbpChpFirst
;
5252 rSt
>> pnFbpPapFirst
;
5255 rSt
>> pnFbpLvcFirst
;
5258 rSt
>> fcIslandFirst
;
5263 // Ende des Einschubs fuer WW8 *******************************************
5265 // Marke: "rgfclcb" Beginning of array of FC/LCB pairs.
5267 lcbStshfOrig
= Readcb(rSt
, eVer
);
5269 lcbStshf
= Readcb(rSt
, eVer
);
5270 rSt
>> fcPlcffndRef
;
5271 lcbPlcffndRef
= Readcb(rSt
, eVer
);
5272 rSt
>> fcPlcffndTxt
;
5273 lcbPlcffndTxt
= Readcb(rSt
, eVer
);
5274 rSt
>> fcPlcfandRef
;
5275 lcbPlcfandRef
= Readcb(rSt
, eVer
);
5276 rSt
>> fcPlcfandTxt
;
5277 lcbPlcfandTxt
= Readcb(rSt
, eVer
);
5279 lcbPlcfsed
= Readcb(rSt
, eVer
);
5281 lcbPlcfpad
= Readcb(rSt
, eVer
);
5283 lcbPlcfphe
= Readcb(rSt
, eVer
);
5285 lcbSttbfglsy
= Readcb(rSt
, eVer
);
5287 lcbPlcfglsy
= Readcb(rSt
, eVer
);
5289 lcbPlcfhdd
= Readcb(rSt
, eVer
);
5290 rSt
>> fcPlcfbteChpx
;
5291 lcbPlcfbteChpx
= Readcb(rSt
, eVer
);
5292 rSt
>> fcPlcfbtePapx
;
5293 lcbPlcfbtePapx
= Readcb(rSt
, eVer
);
5295 lcbPlcfsea
= Readcb(rSt
, eVer
);
5297 lcbSttbfffn
= Readcb(rSt
, eVer
);
5298 rSt
>> fcPlcffldMom
;
5299 lcbPlcffldMom
= Readcb(rSt
, eVer
);
5300 rSt
>> fcPlcffldHdr
;
5301 lcbPlcffldHdr
= Readcb(rSt
, eVer
);
5302 rSt
>> fcPlcffldFtn
;
5303 lcbPlcffldFtn
= Readcb(rSt
, eVer
);
5304 rSt
>> fcPlcffldAtn
;
5305 lcbPlcffldAtn
= Readcb(rSt
, eVer
);
5306 rSt
>> fcPlcffldMcr
;
5307 lcbPlcffldMcr
= Readcb(rSt
, eVer
);
5309 lcbSttbfbkmk
= Readcb(rSt
, eVer
);
5311 lcbPlcfbkf
= Readcb(rSt
, eVer
);
5313 lcbPlcfbkl
= Readcb(rSt
, eVer
);
5315 lcbCmds
= Readcb(rSt
, eVer
);
5317 lcbPlcfmcr
= Readcb(rSt
, eVer
);
5319 lcbSttbfmcr
= Readcb(rSt
, eVer
);
5321 lcbPrDrvr
= Readcb(rSt
, eVer
);
5323 lcbPrEnvPort
= Readcb(rSt
, eVer
);
5325 lcbPrEnvLand
= Readcb(rSt
, eVer
);
5327 lcbWss
= Readcb(rSt
, eVer
);
5329 lcbDop
= Readcb(rSt
, eVer
);
5330 rSt
>> fcSttbfAssoc
;
5331 lcbSttbfAssoc
= Readcb(rSt
, eVer
);
5333 lcbClx
= Readcb(rSt
, eVer
);
5334 rSt
>> fcPlcfpgdFtn
;
5335 lcbPlcfpgdFtn
= Readcb(rSt
, eVer
);
5336 rSt
>> fcAutosaveSource
;
5337 lcbAutosaveSource
= Readcb(rSt
, eVer
);
5338 rSt
>> fcGrpStAtnOwners
;
5339 lcbGrpStAtnOwners
= Readcb(rSt
, eVer
);
5340 rSt
>> fcSttbfAtnbkmk
;
5341 lcbSttbfAtnbkmk
= Readcb(rSt
, eVer
);
5343 // weiteres short nur bei Ver67 ueberspringen
5344 if (IsSevenMinus(eVer
))
5346 rSt
.SeekRel( 1*sizeof( sal_Int16
) );
5348 // folgende 4 Shorts existieren nur bei Ver67;
5349 rSt
>> pnChpFirst_Ver67
;
5350 rSt
>> pnPapFirst_Ver67
;
5351 rSt
>> cpnBteChp_Ver67
;
5352 rSt
>> cpnBtePap_Ver67
;
5355 if (eVer
> ww::eWW2
)
5357 rSt
>> fcPlcfdoaMom
;
5358 rSt
>> lcbPlcfdoaMom
;
5359 rSt
>> fcPlcfdoaHdr
;
5360 rSt
>> lcbPlcfdoaHdr
;
5361 rSt
>> fcPlcfspaMom
;
5362 rSt
>> lcbPlcfspaMom
;
5363 rSt
>> fcPlcfspaHdr
;
5364 rSt
>> lcbPlcfspaHdr
;
5366 rSt
>> fcPlcfAtnbkf
;
5367 rSt
>> lcbPlcfAtnbkf
;
5368 rSt
>> fcPlcfAtnbkl
;
5369 rSt
>> lcbPlcfAtnbkl
;
5372 rSt
>> fcFormFldSttbf
;
5373 rSt
>> lcbFormFldSttbf
;
5374 rSt
>> fcPlcfendRef
;
5375 rSt
>> lcbPlcfendRef
;
5376 rSt
>> fcPlcfendTxt
;
5377 rSt
>> lcbPlcfendTxt
;
5378 rSt
>> fcPlcffldEdn
;
5379 rSt
>> lcbPlcffldEdn
;
5380 rSt
>> fcPlcfpgdEdn
;
5381 rSt
>> lcbPlcfpgdEdn
;
5384 rSt
>> fcSttbfRMark
;
5385 rSt
>> lcbSttbfRMark
;
5386 rSt
>> fcSttbfCaption
;
5387 rSt
>> lcbSttbfCaption
;
5388 rSt
>> fcSttbAutoCaption
;
5389 rSt
>> lcbSttbAutoCaption
;
5394 rSt
>> fcPlcftxbxTxt
;
5395 rSt
>> lcbPlcftxbxTxt
;
5396 rSt
>> fcPlcffldTxbx
;
5397 rSt
>> lcbPlcffldTxbx
;
5398 rSt
>> fcPlcfHdrtxbxTxt
;
5399 rSt
>> lcbPlcfHdrtxbxTxt
;
5400 rSt
>> fcPlcffldHdrTxbx
;
5401 rSt
>> lcbPlcffldHdrTxbx
;
5405 rSt
>> lcbSttbttmbd
;
5408 if( 0 == rSt
.GetError() )
5411 fDot
= aBits1
& 0x01 ;
5412 fGlsy
= ( aBits1
& 0x02 ) >> 1;
5413 fComplex
= ( aBits1
& 0x04 ) >> 2;
5414 fHasPic
= ( aBits1
& 0x08 ) >> 3;
5415 cQuickSaves
= ( aBits1
& 0xf0 ) >> 4;
5416 fEncrypted
= aBits2
& 0x01 ;
5417 fWhichTblStm
= ( aBits2
& 0x02 ) >> 1;
5418 fReadOnlyRecommended
= (aBits2
& 0x4) >> 2;
5419 fWriteReservation
= (aBits2
& 0x8) >> 3;
5420 fExtChar
= ( aBits2
& 0x10 ) >> 4;
5421 // dummy = ( aBits2 & 0x20 ) >> 5;
5422 fFarEast
= ( aBits2
& 0x40 ) >> 6; // #i90932#
5423 // dummy = ( aBits2 & 0x80 ) >> 7;
5426 ggfs. Ziel-Varaiblen, aus xxx_Ver67 fuellen
5429 if (IsSevenMinus(eVer
))
5431 pnChpFirst
= pnChpFirst_Ver67
;
5432 pnPapFirst
= pnPapFirst_Ver67
;
5433 cpnBteChp
= cpnBteChp_Ver67
;
5434 cpnBtePap
= cpnBtePap_Ver67
;
5436 else if (IsEightPlus(eVer
))
5438 fMac
= aVer8Bits1
& 0x01 ;
5439 fEmptySpecial
= ( aVer8Bits1
& 0x02 ) >> 1;
5440 fLoadOverridePage
= ( aVer8Bits1
& 0x04 ) >> 2;
5441 fFuturesavedUndo
= ( aVer8Bits1
& 0x08 ) >> 3;
5442 fWord97Saved
= ( aVer8Bits1
& 0x10 ) >> 4;
5443 fWord2000Saved
= ( aVer8Bits1
& 0x20 ) >> 5;
5447 ermittle die Werte fuer PLCF LST und PLF LFO
5448 und PLCF fuer TextBox-Break-Deskriptoren
5450 long nOldPos
= rSt
.Tell();
5459 rSt
>> fcPlcftxbxBkd
;
5460 rSt
>> lcbPlcftxbxBkd
;
5461 rSt
>> fcPlcfHdrtxbxBkd
;
5462 rSt
>> lcbPlcfHdrtxbxBkd
;
5463 if( 0 != rSt
.GetError() )
5465 nFibError
= ERR_SWG_READ_ERROR
;
5468 rSt
.Seek( 0x372 ); // fcSttbListNames
5469 rSt
>> fcSttbListNames
;
5470 rSt
>> lcbSttbListNames
;
5474 rSt
.Seek( 0x382 ); // MagicTables
5481 rSt
.Seek( 0x41A ); // new ATRD
5483 rSt
>> lcbAtrdExtra
;
5486 if( 0 != rSt
.GetError() )
5487 nFibError
= ERR_SWG_READ_ERROR
;
5489 rSt
.Seek( 0x5bc ); // Actual nFib introduced in Word 2003
5492 rSt
.Seek( nOldPos
);
5497 nFibError
= ERR_SWG_READ_ERROR
; // Error melden
5502 WW8Fib::WW8Fib(sal_uInt8 nVer
)
5504 memset(this, 0, sizeof(*this));
5514 csw
= 0x0e; // muss das sein ???
5515 cfclcb
= 0x88; // -""-
5517 pnFbpChpFirst
= pnFbpPapFirst
= pnFbpLvcFirst
= 0x000fffff;
5519 fWord97Saved
= fWord2000Saved
= true;
5521 wMagicCreated
= 0x6143;
5522 wMagicRevised
= 0x6C6F;
5523 wMagicCreatedPrivate
= 0x6E61;
5524 wMagicRevisedPrivate
= 0x3038;
5530 nFib
= nFibBack
= 0x65;
5534 //If nFib is 0x00D9 or greater, then cQuickSaves MUST be 0xF
5535 cQuickSaves
= nFib
>= 0x00D9 ? 0xF : 0;
5538 lid
= 0x409; // LANGUAGE_ENGLISH_US
5540 LanguageType nLang
= Application::GetSettings().GetLanguageTag().getLanguageType();
5541 fFarEast
= MsLangId::isCJK(nLang
);
5547 LanguageTag
aLanguageTag( lid
);
5548 LocaleDataWrapper
aLocaleWrapper( aLanguageTag
);
5549 nNumDecimalSep
= aLocaleWrapper
.getNumDecimalSep()[0];
5552 sal_Unicode
WW8Fib::getNumDecimalSep() const
5554 return nNumDecimalSep
;
5557 bool WW8Fib::WriteHeader(SvStream
& rStrm
)
5559 bool bVer8
= 8 == nVersion
;
5561 size_t nUnencryptedHdr
= bVer8
? 0x44 : 0x24;
5562 sal_uInt8
*pDataPtr
= new sal_uInt8
[ nUnencryptedHdr
];
5563 sal_uInt8
*pData
= pDataPtr
;
5564 memset( pData
, 0, nUnencryptedHdr
);
5566 sal_uLong nPos
= rStrm
.Tell();
5567 cbMac
= rStrm
.Seek( STREAM_SEEK_TO_END
);
5570 Set_UInt16( pData
, wIdent
);
5571 Set_UInt16( pData
, nFib
);
5572 Set_UInt16( pData
, nProduct
);
5573 Set_UInt16( pData
, lid
);
5574 Set_UInt16( pData
, pnNext
);
5576 sal_uInt16 nBits16
= 0;
5577 if( fDot
) nBits16
|= 0x0001;
5578 if( fGlsy
) nBits16
|= 0x0002;
5579 if( fComplex
) nBits16
|= 0x0004;
5580 if( fHasPic
) nBits16
|= 0x0008;
5581 nBits16
|= (0xf0 & ( cQuickSaves
<< 4 ));
5582 if( fEncrypted
) nBits16
|= 0x0100;
5583 if( fWhichTblStm
) nBits16
|= 0x0200;
5585 if (fReadOnlyRecommended
)
5587 if (fWriteReservation
)
5590 if( fExtChar
) nBits16
|= 0x1000;
5591 if( fFarEast
) nBits16
|= 0x4000; // #i90932#
5592 if( fObfuscated
) nBits16
|= 0x8000;
5593 Set_UInt16( pData
, nBits16
);
5595 Set_UInt16( pData
, nFibBack
);
5596 Set_UInt16( pData
, nHash
);
5597 Set_UInt16( pData
, nKey
);
5598 Set_UInt8( pData
, envr
);
5600 sal_uInt8 nBits8
= 0;
5603 if( fMac
) nBits8
|= 0x0001;
5604 if( fEmptySpecial
) nBits8
|= 0x0002;
5605 if( fLoadOverridePage
) nBits8
|= 0x0004;
5606 if( fFuturesavedUndo
) nBits8
|= 0x0008;
5607 if( fWord97Saved
) nBits8
|= 0x0010;
5608 if( fWord2000Saved
) nBits8
|= 0x0020;
5610 // unter Ver67 these are only reserved
5611 Set_UInt8( pData
, nBits8
);
5613 Set_UInt16( pData
, chse
);
5614 Set_UInt16( pData
, chseTables
);
5615 Set_UInt32( pData
, fcMin
);
5616 Set_UInt32( pData
, fcMac
);
5618 // Einschub fuer WW8 *****************************************************
5620 // Marke: "rgsw" Beginning of the array of shorts
5623 Set_UInt16( pData
, csw
);
5624 Set_UInt16( pData
, wMagicCreated
);
5625 Set_UInt16( pData
, wMagicRevised
);
5626 Set_UInt16( pData
, wMagicCreatedPrivate
);
5627 Set_UInt16( pData
, wMagicRevisedPrivate
);
5628 pData
+= 9 * sizeof( sal_Int16
);
5629 Set_UInt16( pData
, lidFE
);
5630 Set_UInt16( pData
, clw
);
5633 // Ende des Einschubs fuer WW8 *******************************************
5635 // Marke: "rglw" Beginning of the array of longs
5636 Set_UInt32( pData
, cbMac
);
5638 rStrm
.Write( pDataPtr
, nUnencryptedHdr
);
5640 return 0 == rStrm
.GetError();
5643 bool WW8Fib::Write(SvStream
& rStrm
)
5645 bool bVer8
= 8 == nVersion
;
5647 WriteHeader( rStrm
);
5649 size_t nUnencryptedHdr
= bVer8
? 0x44 : 0x24;
5651 sal_uInt8
*pDataPtr
= new sal_uInt8
[ fcMin
- nUnencryptedHdr
];
5652 sal_uInt8
*pData
= pDataPtr
;
5653 memset( pData
, 0, fcMin
- nUnencryptedHdr
);
5655 sal_uLong nPos
= rStrm
.Tell();
5656 cbMac
= rStrm
.Seek( STREAM_SEEK_TO_END
);
5659 // 2 Longs uebergehen, da unwichtiger Quatsch
5660 pData
+= 2 * sizeof( sal_Int32
);
5662 // weitere 2 Longs nur bei Ver67 ueberspringen
5664 pData
+= 2 * sizeof( sal_Int32
);
5666 Set_UInt32( pData
, ccpText
);
5667 Set_UInt32( pData
, ccpFtn
);
5668 Set_UInt32( pData
, ccpHdr
);
5669 Set_UInt32( pData
, ccpMcr
);
5670 Set_UInt32( pData
, ccpAtn
);
5671 Set_UInt32( pData
, ccpEdn
);
5672 Set_UInt32( pData
, ccpTxbx
);
5673 Set_UInt32( pData
, ccpHdrTxbx
);
5675 // weiteres Long nur bei Ver67 ueberspringen
5677 pData
+= 1 * sizeof( sal_Int32
);
5679 // Einschub fuer WW8 *****************************************************
5682 Set_UInt32( pData
, pnFbpChpFirst
);
5683 Set_UInt32( pData
, pnChpFirst
);
5684 Set_UInt32( pData
, cpnBteChp
);
5685 Set_UInt32( pData
, pnFbpPapFirst
);
5686 Set_UInt32( pData
, pnPapFirst
);
5687 Set_UInt32( pData
, cpnBtePap
);
5688 Set_UInt32( pData
, pnFbpLvcFirst
);
5689 Set_UInt32( pData
, pnLvcFirst
);
5690 Set_UInt32( pData
, cpnBteLvc
);
5691 Set_UInt32( pData
, fcIslandFirst
);
5692 Set_UInt32( pData
, fcIslandLim
);
5693 Set_UInt16( pData
, cfclcb
);
5695 // Ende des Einschubs fuer WW8 *******************************************
5697 // Marke: "rgfclcb" Beginning of array of FC/LCB pairs.
5698 Set_UInt32( pData
, fcStshfOrig
);
5699 Set_UInt32( pData
, lcbStshfOrig
);
5700 Set_UInt32( pData
, fcStshf
);
5701 Set_UInt32( pData
, lcbStshf
);
5702 Set_UInt32( pData
, fcPlcffndRef
);
5703 Set_UInt32( pData
, lcbPlcffndRef
);
5704 Set_UInt32( pData
, fcPlcffndTxt
);
5705 Set_UInt32( pData
, lcbPlcffndTxt
);
5706 Set_UInt32( pData
, fcPlcfandRef
);
5707 Set_UInt32( pData
, lcbPlcfandRef
);
5708 Set_UInt32( pData
, fcPlcfandTxt
);
5709 Set_UInt32( pData
, lcbPlcfandTxt
);
5710 Set_UInt32( pData
, fcPlcfsed
);
5711 Set_UInt32( pData
, lcbPlcfsed
);
5712 Set_UInt32( pData
, fcPlcfpad
);
5713 Set_UInt32( pData
, lcbPlcfpad
);
5714 Set_UInt32( pData
, fcPlcfphe
);
5715 Set_UInt32( pData
, lcbPlcfphe
);
5716 Set_UInt32( pData
, fcSttbfglsy
);
5717 Set_UInt32( pData
, lcbSttbfglsy
);
5718 Set_UInt32( pData
, fcPlcfglsy
);
5719 Set_UInt32( pData
, lcbPlcfglsy
);
5720 Set_UInt32( pData
, fcPlcfhdd
);
5721 Set_UInt32( pData
, lcbPlcfhdd
);
5722 Set_UInt32( pData
, fcPlcfbteChpx
);
5723 Set_UInt32( pData
, lcbPlcfbteChpx
);
5724 Set_UInt32( pData
, fcPlcfbtePapx
);
5725 Set_UInt32( pData
, lcbPlcfbtePapx
);
5726 Set_UInt32( pData
, fcPlcfsea
);
5727 Set_UInt32( pData
, lcbPlcfsea
);
5728 Set_UInt32( pData
, fcSttbfffn
);
5729 Set_UInt32( pData
, lcbSttbfffn
);
5730 Set_UInt32( pData
, fcPlcffldMom
);
5731 Set_UInt32( pData
, lcbPlcffldMom
);
5732 Set_UInt32( pData
, fcPlcffldHdr
);
5733 Set_UInt32( pData
, lcbPlcffldHdr
);
5734 Set_UInt32( pData
, fcPlcffldFtn
);
5735 Set_UInt32( pData
, lcbPlcffldFtn
);
5736 Set_UInt32( pData
, fcPlcffldAtn
);
5737 Set_UInt32( pData
, lcbPlcffldAtn
);
5738 Set_UInt32( pData
, fcPlcffldMcr
);
5739 Set_UInt32( pData
, lcbPlcffldMcr
);
5740 Set_UInt32( pData
, fcSttbfbkmk
);
5741 Set_UInt32( pData
, lcbSttbfbkmk
);
5742 Set_UInt32( pData
, fcPlcfbkf
);
5743 Set_UInt32( pData
, lcbPlcfbkf
);
5744 Set_UInt32( pData
, fcPlcfbkl
);
5745 Set_UInt32( pData
, lcbPlcfbkl
);
5746 Set_UInt32( pData
, fcCmds
);
5747 Set_UInt32( pData
, lcbCmds
);
5748 Set_UInt32( pData
, fcPlcfmcr
);
5749 Set_UInt32( pData
, lcbPlcfmcr
);
5750 Set_UInt32( pData
, fcSttbfmcr
);
5751 Set_UInt32( pData
, lcbSttbfmcr
);
5752 Set_UInt32( pData
, fcPrDrvr
);
5753 Set_UInt32( pData
, lcbPrDrvr
);
5754 Set_UInt32( pData
, fcPrEnvPort
);
5755 Set_UInt32( pData
, lcbPrEnvPort
);
5756 Set_UInt32( pData
, fcPrEnvLand
);
5757 Set_UInt32( pData
, lcbPrEnvLand
);
5758 Set_UInt32( pData
, fcWss
);
5759 Set_UInt32( pData
, lcbWss
);
5760 Set_UInt32( pData
, fcDop
);
5761 Set_UInt32( pData
, lcbDop
);
5762 Set_UInt32( pData
, fcSttbfAssoc
);
5763 Set_UInt32( pData
, lcbSttbfAssoc
);
5764 Set_UInt32( pData
, fcClx
);
5765 Set_UInt32( pData
, lcbClx
);
5766 Set_UInt32( pData
, fcPlcfpgdFtn
);
5767 Set_UInt32( pData
, lcbPlcfpgdFtn
);
5768 Set_UInt32( pData
, fcAutosaveSource
);
5769 Set_UInt32( pData
, lcbAutosaveSource
);
5770 Set_UInt32( pData
, fcGrpStAtnOwners
);
5771 Set_UInt32( pData
, lcbGrpStAtnOwners
);
5772 Set_UInt32( pData
, fcSttbfAtnbkmk
);
5773 Set_UInt32( pData
, lcbSttbfAtnbkmk
);
5775 // weiteres short nur bei Ver67 ueberspringen
5778 pData
+= 1*sizeof( sal_Int16
);
5779 Set_UInt16( pData
, (sal_uInt16
)pnChpFirst
);
5780 Set_UInt16( pData
, (sal_uInt16
)pnPapFirst
);
5781 Set_UInt16( pData
, (sal_uInt16
)cpnBteChp
);
5782 Set_UInt16( pData
, (sal_uInt16
)cpnBtePap
);
5785 Set_UInt32( pData
, fcPlcfdoaMom
); // nur bei Ver67, in Ver8 unused
5786 Set_UInt32( pData
, lcbPlcfdoaMom
); // nur bei Ver67, in Ver8 unused
5787 Set_UInt32( pData
, fcPlcfdoaHdr
); // nur bei Ver67, in Ver8 unused
5788 Set_UInt32( pData
, lcbPlcfdoaHdr
); // nur bei Ver67, in Ver8 unused
5790 Set_UInt32( pData
, fcPlcfspaMom
); // in Ver67 leere Reserve
5791 Set_UInt32( pData
, lcbPlcfspaMom
); // in Ver67 leere Reserve
5792 Set_UInt32( pData
, fcPlcfspaHdr
); // in Ver67 leere Reserve
5793 Set_UInt32( pData
, lcbPlcfspaHdr
); // in Ver67 leere Reserve
5795 Set_UInt32( pData
, fcPlcfAtnbkf
);
5796 Set_UInt32( pData
, lcbPlcfAtnbkf
);
5797 Set_UInt32( pData
, fcPlcfAtnbkl
);
5798 Set_UInt32( pData
, lcbPlcfAtnbkl
);
5799 Set_UInt32( pData
, fcPms
);
5800 Set_UInt32( pData
, lcbPMS
);
5801 Set_UInt32( pData
, fcFormFldSttbf
);
5802 Set_UInt32( pData
, lcbFormFldSttbf
);
5803 Set_UInt32( pData
, fcPlcfendRef
);
5804 Set_UInt32( pData
, lcbPlcfendRef
);
5805 Set_UInt32( pData
, fcPlcfendTxt
);
5806 Set_UInt32( pData
, lcbPlcfendTxt
);
5807 Set_UInt32( pData
, fcPlcffldEdn
);
5808 Set_UInt32( pData
, lcbPlcffldEdn
);
5809 Set_UInt32( pData
, fcPlcfpgdEdn
);
5810 Set_UInt32( pData
, lcbPlcfpgdEdn
);
5811 Set_UInt32( pData
, fcDggInfo
); // in Ver67 leere Reserve
5812 Set_UInt32( pData
, lcbDggInfo
); // in Ver67 leere Reserve
5813 Set_UInt32( pData
, fcSttbfRMark
);
5814 Set_UInt32( pData
, lcbSttbfRMark
);
5815 Set_UInt32( pData
, fcSttbfCaption
);
5816 Set_UInt32( pData
, lcbSttbfCaption
);
5817 Set_UInt32( pData
, fcSttbAutoCaption
);
5818 Set_UInt32( pData
, lcbSttbAutoCaption
);
5819 Set_UInt32( pData
, fcPlcfwkb
);
5820 Set_UInt32( pData
, lcbPlcfwkb
);
5821 Set_UInt32( pData
, fcPlcfspl
); // in Ver67 leere Reserve
5822 Set_UInt32( pData
, lcbPlcfspl
); // in Ver67 leere Reserve
5823 Set_UInt32( pData
, fcPlcftxbxTxt
);
5824 Set_UInt32( pData
, lcbPlcftxbxTxt
);
5825 Set_UInt32( pData
, fcPlcffldTxbx
);
5826 Set_UInt32( pData
, lcbPlcffldTxbx
);
5827 Set_UInt32( pData
, fcPlcfHdrtxbxTxt
);
5828 Set_UInt32( pData
, lcbPlcfHdrtxbxTxt
);
5829 Set_UInt32( pData
, fcPlcffldHdrTxbx
);
5830 Set_UInt32( pData
, lcbPlcffldHdrTxbx
);
5834 pData
+= 0x2da - 0x27a; // Pos + Offset (fcPlcfLst - fcStwUser)
5835 Set_UInt32( pData
, fcSttbFnm
);
5836 Set_UInt32( pData
, lcbSttbFnm
);
5837 Set_UInt32( pData
, fcPlcfLst
);
5838 Set_UInt32( pData
, lcbPlcfLst
);
5839 Set_UInt32( pData
, fcPlfLfo
);
5840 Set_UInt32( pData
, lcbPlfLfo
);
5841 Set_UInt32( pData
, fcPlcftxbxBkd
);
5842 Set_UInt32( pData
, lcbPlcftxbxBkd
);
5843 Set_UInt32( pData
, fcPlcfHdrtxbxBkd
);
5844 Set_UInt32( pData
, lcbPlcfHdrtxbxBkd
);
5846 pData
+= 0x372 - 0x302; // Pos + Offset (fcSttbListNames - fcDocUndo)
5847 Set_UInt32( pData
, fcSttbListNames
);
5848 Set_UInt32( pData
, lcbSttbListNames
);
5850 pData
+= 0x382 - 0x37A;
5851 Set_UInt32( pData
, fcPlcfTch
);
5852 Set_UInt32( pData
, lcbPlcfTch
);
5854 pData
+= 0x3FA - 0x38A;
5855 Set_UInt16( pData
, (sal_uInt16
)0x0002);
5856 Set_UInt16( pData
, (sal_uInt16
)0x00D9);
5858 pData
+= 0x41A - 0x3FE;
5859 Set_UInt32( pData
, fcAtrdExtra
);
5860 Set_UInt32( pData
, lcbAtrdExtra
);
5862 pData
+= 0x4DA - 0x422;
5863 Set_UInt32( pData
, fcHplxsdr
);
5864 Set_UInt32( pData
, 0);
5867 rStrm
.Write( pDataPtr
, fcMin
- nUnencryptedHdr
);
5869 return 0 == rStrm
.GetError();
5872 rtl_TextEncoding
WW8Fib::GetFIBCharset(sal_uInt16 chs
)
5874 OSL_ENSURE(chs
<= 0x100, "overflowed winword charset set");
5875 rtl_TextEncoding eCharSet
=
5877 ? RTL_TEXTENCODING_APPLE_ROMAN
5878 : rtl_getTextEncodingFromWindowsCharset( static_cast<sal_uInt8
>(chs
) );
5882 WW8Style::WW8Style(SvStream
& rStream
, WW8Fib
& rFibPara
)
5883 : rFib(rFibPara
), rSt(rStream
), cstd(0), cbSTDBaseInFile(0),
5884 stiMaxWhenSaved(0), istdMaxFixedWhenSaved(0), nVerBuiltInNamesWhenSaved(0),
5885 ftcAsci(0), ftcFE(0), ftcOther(0), ftcBi(0)
5887 if (!checkSeek(rSt
, rFib
.fcStshf
))
5890 sal_uInt16 cbStshi
= 0; // 2 bytes size of the following STSHI structure
5891 sal_uInt32 nRemaining
= rFib
.lcbStshf
;
5892 const sal_uInt32 nMinValidStshi
= 4;
5894 if (rFib
.GetFIBVersion() <= ww::eWW2
)
5901 if (rFib
.nFib
< 67) // old Version ? (need to find this again to fix)
5902 cbStshi
= nMinValidStshi
;
5905 if (nRemaining
< sizeof(cbStshi
))
5907 // lies die Laenge der in der Datei gespeicherten Struktur
5913 cbStshi
= std::min(static_cast<sal_uInt32
>(cbStshi
), nRemaining
);
5914 if (cbStshi
< nMinValidStshi
)
5917 sal_uInt16 nRead
= cbStshi
;
5922 if( 2 > nRead
) break;
5925 if( 4 > nRead
) break;
5926 rSt
>> cbSTDBaseInFile
;
5928 if( 6 > nRead
) break;
5930 fStdStylenamesWritten
= a16Bit
& 0x0001;
5932 if( 8 > nRead
) break;
5933 rSt
>> stiMaxWhenSaved
;
5935 if( 10 > nRead
) break;
5936 rSt
>> istdMaxFixedWhenSaved
;
5938 if( 12 > nRead
) break;
5939 rSt
>> nVerBuiltInNamesWhenSaved
;
5941 if( 14 > nRead
) break;
5944 if( 16 > nRead
) break;
5947 if ( 18 > nRead
) break;
5952 if ( 20 > nRead
) break;
5955 // ggfs. den Rest ueberlesen
5957 rSt
.SeekRel( nRead
-20 );
5959 while( !this ); // Trick: obiger Block wird genau einmal durchlaufen
5960 // und kann vorzeitig per "break" verlassen werden.
5962 nRemaining
-= cbStshi
;
5964 //There will be stshi.cstd (cbSTD, STD) pairs in the file following the
5965 //STSHI. Note that styles can be empty, i.e. cbSTD == 0
5966 const sal_uInt32 nMinRecordSize
= sizeof(sal_uInt16
);
5967 sal_uInt16 nMaxPossibleRecords
= nRemaining
/nMinRecordSize
;
5969 OSL_ENSURE(cstd
<= nMaxPossibleRecords
,
5970 "allegedly more styles that available data\n");
5971 cstd
= std::min(cstd
, nMaxPossibleRecords
);
5974 // Read1STDFixed() liest ein Style ein. Wenn der Style vollstaendig vorhanden
5975 // ist, d.h. kein leerer Slot, dann wird Speicher alloziert und ein Pointer auf
5976 // die ( evtl. mit Nullen aufgefuellten ) STD geliefert. Ist es ein leerer
5977 // Slot, dann wird ein Nullpointer zurueckgeliefert.
5978 WW8_STD
* WW8Style::Read1STDFixed( short& rSkip
, short* pcbStd
)
5982 sal_uInt16
cbStd(0);
5983 rSt
>> cbStd
; // lies Laenge
5985 sal_uInt16 nRead
= cbSTDBaseInFile
;
5986 if( cbStd
>= cbSTDBaseInFile
)
5988 // Fixed part vollst. vorhanden
5990 // read fixed part of STD
5992 memset( pStd
, 0, sizeof( *pStd
) );
5998 if( 2 > nRead
) break;
6001 pStd
->sti
= a16Bit
& 0x0fff ;
6002 pStd
->fScratch
= 0 != ( a16Bit
& 0x1000 );
6003 pStd
->fInvalHeight
= 0 != ( a16Bit
& 0x2000 );
6004 pStd
->fHasUpe
= 0 != ( a16Bit
& 0x4000 );
6005 pStd
->fMassCopy
= 0 != ( a16Bit
& 0x8000 );
6007 if( 4 > nRead
) break;
6010 pStd
->sgc
= a16Bit
& 0x000f ;
6011 pStd
->istdBase
= ( a16Bit
& 0xfff0 ) >> 4;
6013 if( 6 > nRead
) break;
6016 pStd
->cupx
= a16Bit
& 0x000f ;
6017 pStd
->istdNext
= ( a16Bit
& 0xfff0 ) >> 4;
6019 if( 8 > nRead
) break;
6021 rSt
>> pStd
->bchUpe
;
6023 // ab Ver8 sollten diese beiden Felder dazukommen:
6024 if(10 > nRead
) break;
6027 pStd
->fAutoRedef
= a16Bit
& 0x0001 ;
6028 pStd
->fHidden
= ( a16Bit
& 0x0002 ) >> 1;
6030 // man kann nie wissen: vorsichtshalber ueberlesen
6031 // wir eventuelle Fuellsel, die noch zum BASE-Part gehoeren...
6033 rSt
.SeekRel( nRead
-10 );
6035 while( !this ); // Trick: obiger Block wird genau einmal durchlaufen
6036 // und kann vorzeitig per "break" verlassen werden.
6038 if( (0 != rSt
.GetError()) || !nRead
)
6039 DELETEZ( pStd
); // per NULL den Error melden
6041 rSkip
= cbStd
- cbSTDBaseInFile
;
6044 { // Fixed part zu kurz
6046 rSt
.SeekRel( cbStd
); // ueberlies Reste
6054 WW8_STD
* WW8Style::Read1Style( short& rSkip
, String
* pString
, short* pcbStd
)
6056 // Attention: MacWord-Documents have their Stylenames
6057 // always in ANSI, even if eStructCharSet == CHARSET_MAC !!
6059 WW8_STD
* pStd
= Read1STDFixed( rSkip
, pcbStd
); // lese STD
6061 // String gewuenscht ?
6066 switch( rFib
.nVersion
)
6070 // lies Pascal-String
6071 *pString
= read_uInt8_BeltAndBracesString(rSt
, RTL_TEXTENCODING_MS_1252
);
6072 // leading len and trailing zero --> 2
6073 rSkip
-= 2+ pString
->Len();
6076 // handle Unicode-String with leading length short and
6078 if (TestBeltAndBraces
<sal_Unicode
>(rSt
))
6080 *pString
= read_uInt16_BeltAndBracesString(rSt
);
6081 rSkip
-= (pString
->Len() + 2) * 2;
6087 This is supposed to be impossible, its just supposed
6088 to be 16 bit count followed by the string and ending
6089 in a 0 short. But "Lotus SmartSuite Product: Word Pro"
6090 is creating invalid style names in ww7- format. So we
6091 use the belt and braces of the ms strings to see if
6092 they are not corrupt. If they are then we try them as
6095 *pString
= read_uInt8_BeltAndBracesString(rSt
,RTL_TEXTENCODING_MS_1252
);
6096 // leading len and trailing zero --> 2
6097 rSkip
-= 2+ pString
->Len();
6101 OSL_ENSURE(!this, "Es wurde vergessen, nVersion zu kodieren!");
6106 *pString
= aEmptyStr
; // Kann keinen Namen liefern
6115 struct WW8_FFN_Ver6
: public WW8_FFN_BASE
6118 sal_Char szFfn
[65]; // 0x6 bzw. 0x40 ab Ver8 zero terminated string that
6119 // records name of font.
6120 // Maximal size of szFfn is 65 characters.
6121 // Vorsicht: Dieses Array kann auch kleiner sein!!!
6122 // Possibly followed by a second sz which records the
6123 // name of an alternate font to use if the first named
6124 // font does not exist on this system.
6126 struct WW8_FFN_Ver8
: public WW8_FFN_BASE
6128 // ab Ver8 sind folgende beiden Felder eingeschoben,
6129 // werden von uns ignoriert.
6130 sal_Char panose
[ 10 ]; // 0x6 PANOSE
6131 sal_Char fs
[ 24 ]; // 0x10 FONTSIGNATURE
6133 // ab Ver8 als Unicode
6134 sal_uInt16 szFfn
[65]; // 0x6 bzw. 0x40 ab Ver8 zero terminated string that
6135 // records name of font.
6136 // Maximal size of szFfn is 65 characters.
6137 // Vorsicht: Dieses Array kann auch kleiner sein!!!
6138 // Possibly followed by a second sz which records the
6139 // name of an alternate font to use if the first named
6140 // font does not exist on this system.
6143 // #i43762# check font name for illegal characters
6144 static void lcl_checkFontname( String
& sString
)
6146 // for efficiency, we'd like to use String methods as far as possible.
6148 // 1) convert all invalid chars to \u0001
6149 // 2) then erase all \u0001 chars (if any were found), and
6150 // 3) erase leading/trailing ';', in case a font name was
6151 // completely removed
6153 // convert all invalid chars to \u0001
6154 sal_Unicode
* pBuffer
= sString
.GetBufferAccess();
6155 xub_StrLen nLen
= sString
.Len();
6156 bool bFound
= false;
6157 for( xub_StrLen n
= 0; n
< nLen
; n
++ )
6159 if( pBuffer
[n
] < sal_Unicode( 0x20 ) )
6161 pBuffer
[n
] = sal_Unicode( 1 );
6165 sString
.ReleaseBufferAccess();
6167 // if anything was found, remove \u0001 + leading/trailing ';'
6170 sString
= comphelper::string::remove(sString
, 1);
6171 sString
= comphelper::string::strip(sString
, ';');
6177 sal_uInt16
calcMaxFonts(sal_uInt8
*p
, sal_Int32 nFFn
)
6179 // Figure out the max number of fonts defined here
6180 sal_uInt16 nMax
= 0;
6181 sal_Int32 nRemaining
= nFFn
;
6184 //p[0] is cbFfnM1, the alleged total length of FFN - 1.
6185 //i.e. length after cbFfnM1
6186 sal_uInt16 cbFfnM1
= *p
++;
6189 if (cbFfnM1
> nRemaining
)
6193 nRemaining
-= cbFfnM1
;
6200 WW8Fonts::WW8Fonts( SvStream
& rSt
, WW8Fib
& rFib
)
6201 : pFontA(0), nMax(0)
6203 // Attention: MacWord-Documents have their Fontnames
6204 // always in ANSI, even if eStructCharSet == CHARSET_MAC !!
6205 if( rFib
.lcbSttbfffn
<= 2 )
6207 OSL_ENSURE( !this, "Fonttabelle kaputt! (rFib.lcbSttbfffn < 2)" );
6211 if (!checkSeek(rSt
, rFib
.fcSttbfffn
))
6214 sal_Int32 nFFn
= rFib
.lcbSttbfffn
- 2;
6216 // allocate Font Array
6217 sal_uInt8
* pA
= new sal_uInt8
[nFFn
];
6218 memset(pA
, 0, nFFn
);
6220 ww::WordVersion eVersion
= rFib
.GetFIBVersion();
6222 if( eVersion
>= ww::eWW8
)
6224 // bVer8: read the count of strings in nMax
6228 // Ver8: skip undefined uint16
6229 // Ver67: skip the herein stored total byte of structure
6230 // - we already got that information in rFib.lcbSttbfffn
6233 // read all font information
6234 nFFn
= rSt
.Read(pA
, nFFn
);
6235 sal_uInt16 nCalcMax
= calcMaxFonts(pA
, nFFn
);
6237 if (eVersion
< ww::eWW8
)
6241 //newer versions include purportive count of fonts, so take min of that
6243 nMax
= std::min(nMax
, nCalcMax
);
6248 // allocate Index Array
6249 pFontA
= new WW8_FFN
[ nMax
];
6250 WW8_FFN
* p
= pFontA
;
6252 if( eVersion
<= ww::eWW2
)
6254 WW8_FFN_BASE
* pVer2
= (WW8_FFN_BASE
*)pA
;
6255 for(sal_uInt16 i
=0; i
<nMax
; ++i
, ++p
)
6257 p
->cbFfnM1
= pVer2
->cbFfnM1
;
6263 p
->wWeight
= ( *(((sal_uInt8
*)pVer2
) + 1) );
6264 p
->chs
= ( *(((sal_uInt8
*)pVer2
) + 2) );
6266 #i8726# 7- seems to encode the name in the same encoding as
6267 the font, e.g load the doc in 97 and save to see the unicode
6268 ver of the asian fontnames in that example to confirm.
6270 rtl_TextEncoding eEnc
= WW8Fib::GetFIBCharset(p
->chs
);
6271 if ((eEnc
== RTL_TEXTENCODING_SYMBOL
) || (eEnc
== RTL_TEXTENCODING_DONTKNOW
))
6272 eEnc
= RTL_TEXTENCODING_MS_1252
;
6274 p
->sFontname
= String ( (((const sal_Char
*)pVer2
) + 1 + 2), eEnc
);
6275 pVer2
= (WW8_FFN_BASE
*)( ((sal_uInt8
*)pVer2
) + pVer2
->cbFfnM1
+ 1 );
6278 else if( eVersion
< ww::eWW8
)
6280 WW8_FFN_Ver6
* pVer6
= (WW8_FFN_Ver6
*)pA
;
6282 for(sal_uInt16 i
=0; i
<nMax
; ++i
, ++p
)
6284 p
->cbFfnM1
= pVer6
->cbFfnM1
;
6285 c2
= *(((sal_uInt8
*)pVer6
) + 1);
6288 p
->fTrueType
= (c2
& 0x04) >> 2;
6289 // ein Reserve-Bit ueberspringen
6290 p
->ff
= (c2
& 0x70) >> 4;
6292 p
->wWeight
= SVBT16ToShort( *(SVBT16
*)&pVer6
->wWeight
);
6293 p
->chs
= pVer6
->chs
;
6294 p
->ibszAlt
= pVer6
->ibszAlt
;
6296 #i8726# 7- seems to encode the name in the same encoding as
6297 the font, e.g load the doc in 97 and save to see the unicode
6298 ver of the asian fontnames in that example to confirm.
6300 rtl_TextEncoding eEnc
= WW8Fib::GetFIBCharset(p
->chs
);
6301 if ((eEnc
== RTL_TEXTENCODING_SYMBOL
) || (eEnc
== RTL_TEXTENCODING_DONTKNOW
))
6302 eEnc
= RTL_TEXTENCODING_MS_1252
;
6303 p
->sFontname
= String(pVer6
->szFfn
, eEnc
);
6304 const sal_uInt16 maxStrSize
= sizeof (pVer6
->szFfn
) / sizeof (pVer6
->szFfn
[0]);
6305 if (p
->ibszAlt
&& p
->ibszAlt
< maxStrSize
) //don't start after end of string
6307 p
->sFontname
.Append(';');
6308 p
->sFontname
+= String(pVer6
->szFfn
+p
->ibszAlt
, eEnc
);
6312 //#i18369# if its a symbol font set Symbol as fallback
6314 RTL_TEXTENCODING_SYMBOL
== WW8Fib::GetFIBCharset(p
->chs
)
6315 && !p
->sFontname
.EqualsAscii("Symbol")
6318 p
->sFontname
.AppendAscii(";Symbol");
6321 pVer6
= (WW8_FFN_Ver6
*)( ((sal_uInt8
*)pVer6
) + pVer6
->cbFfnM1
+ 1 );
6326 //count of bytes in minimum FontFamilyInformation payload
6327 const sal_uInt8 cbMinFFNPayload
= 41;
6328 sal_uInt16 nValidFonts
= 0;
6329 sal_Int32 nRemainingFFn
= nFFn
;
6330 sal_uInt8
* pRaw
= pA
;
6331 for (sal_uInt16 i
=0; i
< nMax
&& nRemainingFFn
; ++i
, ++p
)
6333 //pRaw[0] is cbFfnM1, the alleged total length of FFN - 1
6334 //i.e. length after cbFfnM1
6335 sal_uInt8 cbFfnM1
= *pRaw
++;
6338 if (cbFfnM1
> nRemainingFFn
)
6341 if (cbFfnM1
< cbMinFFNPayload
)
6344 p
->cbFfnM1
= cbFfnM1
;
6346 sal_uInt8
*pVer8
= pRaw
;
6348 sal_uInt8 c2
= *pVer8
++;
6352 p
->fTrueType
= (c2
& 0x04) >> 2;
6353 // ein Reserve-Bit ueberspringen
6354 p
->ff
= (c2
& 0x70) >> 4;
6356 p
->wWeight
= SVBT16ToShort(*(SVBT16
*)pVer8
);
6363 p
->ibszAlt
= *pVer8
++;
6366 pVer8
+= 10; //PANOSE
6368 pVer8
+= 24; //FONTSIGNATURE
6371 OSL_ASSERT(cbFfnM1
>= 2);
6373 sal_uInt8 nMaxNullTerminatedPossible
= cbFfnM1
/2 - 1;
6374 sal_Unicode
*pPrimary
= reinterpret_cast<sal_Unicode
*>(pVer8
);
6375 pPrimary
[nMaxNullTerminatedPossible
] = 0;
6376 #ifdef OSL_BIGENDIAN
6377 swapEndian(pPrimary
);
6379 p
->sFontname
= pPrimary
;
6380 if (p
->ibszAlt
&& p
->ibszAlt
< nMaxNullTerminatedPossible
)
6382 p
->sFontname
.Append(';');
6383 sal_Unicode
*pSecondary
= pPrimary
+ p
->ibszAlt
;
6384 #ifdef OSL_BIGENDIAN
6385 swapEndian(pSecondary
);
6387 p
->sFontname
.Append(pSecondary
);
6390 // #i43762# check font name for illegal characters
6391 lcl_checkFontname( p
->sFontname
);
6393 // Zeiger auf Ursprungsarray einen Font nach hinten setzen
6395 nRemainingFFn
-= p
->cbFfnM1
;
6398 OSL_ENSURE(nMax
== nValidFonts
, "Font count differs with availability");
6399 nMax
= std::min(nMax
, nValidFonts
);
6405 const WW8_FFN
* WW8Fonts::GetFont( sal_uInt16 nNum
) const
6407 if( !pFontA
|| nNum
>= nMax
)
6410 return &pFontA
[ nNum
];
6418 // Suche zu einem Header / Footer den Index in der WW-Liste von Headern / Footern
6420 // Pferdefuesse bei WinWord6 und -7:
6421 // 1) Am Anfang des Einlesens muss WWPLCF_HdFt mit Fib und Dop konstruiert werden
6422 // 2) Der Haupttext muss sequentiell ueber alle Sections gelesen werden
6423 // 3) Fuer jedes vorkommende Header / Footer - Attribut des Haupttextes
6424 // ( Darf pro Section maximal eins sein ) muss UpdateIndex() genau einmal
6425 // mit dem Parameter des Attributes gerufen werden. Dieser Aufruf muss *nach*
6426 // dem letzten Aufruf von GetTextPos() passieren.
6427 // 4) GetTextPos() darf mit genau einem der obenstehen WW_... aufgerufen werden
6428 // ( nicht verodern ! )
6429 // -> dann liefert GetTextPos() vielleicht auch ein richtiges Ergebnis
6431 WW8PLCF_HdFt::WW8PLCF_HdFt( SvStream
* pSt
, WW8Fib
& rFib
, WW8Dop
& rDop
)
6432 : aPLCF(*pSt
, rFib
.fcPlcfhdd
, rFib
.lcbPlcfhdd
, 0)
6437 cmc 23/02/2000: This dop.grpfIhdt has a bit set for each special
6438 footnote *and endnote!!* separator,continuation separator, and
6439 continuation notice entry, the documentation does not mention the
6440 endnote separators, the documentation also gets the index numbers
6441 backwards when specifiying which bits to test. The bottom six bits
6442 of this value must be tested and skipped over. Each section's
6443 grpfIhdt is then tested for the existence of the appropriate headers
6444 and footers, at the end of each section the nIdxOffset must be updated
6445 to point to the beginning of the next section's group of headers and
6446 footers in this PLCF, UpdateIndex does that task.
6448 for( sal_uInt8 nI
= 0x1; nI
<= 0x20; nI
<<= 1 )
6449 if( nI
& rDop
.grpfIhdt
) // Bit gesetzt ?
6452 nTextOfs
= rFib
.ccpText
+ rFib
.ccpFtn
; // Groesse des Haupttextes
6453 // und der Fussnoten
6456 bool WW8PLCF_HdFt::GetTextPos(sal_uInt8 grpfIhdt
, sal_uInt8 nWhich
, WW8_CP
& rStart
,
6459 sal_uInt8 nI
= 0x01;
6460 short nIdx
= nIdxOffset
;
6466 nIdx
++; // uninteresting Header / Footer
6467 nI
<<= 1; // text next bit
6469 return false; // not found
6471 // nIdx ist HdFt-Index
6475 aPLCF
.SetIdx( nIdx
); // Lookup suitable CP
6476 aPLCF
.Get( rStart
, nEnd
, pData
);
6477 rLen
= nEnd
- rStart
;
6483 bool WW8PLCF_HdFt::GetTextPosExact(short nIdx
, WW8_CP
& rStart
, long& rLen
)
6488 aPLCF
.SetIdx( nIdx
); // Lookup suitable CP
6489 aPLCF
.Get( rStart
, nEnd
, pData
);
6490 rLen
= nEnd
- rStart
;
6494 void WW8PLCF_HdFt::UpdateIndex( sal_uInt8 grpfIhdt
)
6496 // Caution: Description is not correct
6497 for( sal_uInt8 nI
= 0x01; nI
<= 0x20; nI
<<= 1 )
6506 WW8Dop::WW8Dop(SvStream
& rSt
, sal_Int16 nFib
, sal_Int32 nPos
, sal_uInt32 nSize
) : bUseThaiLineBreakingRules(false)
6508 memset( &nDataStart
, 0, (&nDataEnd
- &nDataStart
) );
6509 fDontUseHTMLAutoSpacing
= true; //default
6510 fAcetateShowAtn
= true; //default
6511 const sal_uInt32 nMaxDopSize
= 0x268;
6512 sal_uInt8
* pDataPtr
= new sal_uInt8
[ nMaxDopSize
];
6513 sal_uInt8
* pData
= pDataPtr
;
6515 sal_uInt32 nRead
= nMaxDopSize
< nSize
? nMaxDopSize
: nSize
;
6517 if (2 > nSize
|| nRead
!= rSt
.Read(pData
, nRead
))
6518 nDopError
= ERR_SWG_READ_ERROR
; // Error melden
6521 if (nMaxDopSize
> nRead
)
6522 memset( pData
+ nRead
, 0, nMaxDopSize
- nRead
);
6524 // dann mal die Daten auswerten
6529 a16Bit
= Get_UShort( pData
); // 0 0x00
6530 fFacingPages
= 0 != ( a16Bit
& 0x0001 ) ;
6531 fWidowControl
= 0 != ( a16Bit
& 0x0002 ) ;
6532 fPMHMainDoc
= 0 != ( a16Bit
& 0x0004 ) ;
6533 grfSuppression
= ( a16Bit
& 0x0018 ) >> 3;
6534 fpc
= ( a16Bit
& 0x0060 ) >> 5;
6535 grpfIhdt
= ( a16Bit
& 0xff00 ) >> 8;
6537 a16Bit
= Get_UShort( pData
); // 2 0x02
6538 rncFtn
= a16Bit
& 0x0003 ;
6539 nFtn
= ( a16Bit
& ~0x0003 ) >> 2 ;
6541 a8Bit
= Get_Byte( pData
); // 4 0x04
6542 fOutlineDirtySave
= 0 != ( a8Bit
& 0x01 );
6544 a8Bit
= Get_Byte( pData
); // 5 0x05
6545 fOnlyMacPics
= 0 != ( a8Bit
& 0x01 );
6546 fOnlyWinPics
= 0 != ( a8Bit
& 0x02 );
6547 fLabelDoc
= 0 != ( a8Bit
& 0x04 );
6548 fHyphCapitals
= 0 != ( a8Bit
& 0x08 );
6549 fAutoHyphen
= 0 != ( a8Bit
& 0x10 );
6550 fFormNoFields
= 0 != ( a8Bit
& 0x20 );
6551 fLinkStyles
= 0 != ( a8Bit
& 0x40 );
6552 fRevMarking
= 0 != ( a8Bit
& 0x80 );
6554 a8Bit
= Get_Byte( pData
); // 6 0x06
6555 fBackup
= 0 != ( a8Bit
& 0x01 );
6556 fExactCWords
= 0 != ( a8Bit
& 0x02 );
6557 fPagHidden
= 0 != ( a8Bit
& 0x04 );
6558 fPagResults
= 0 != ( a8Bit
& 0x08 );
6559 fLockAtn
= 0 != ( a8Bit
& 0x10 );
6560 fMirrorMargins
= 0 != ( a8Bit
& 0x20 );
6561 fReadOnlyRecommended
= 0 != ( a8Bit
& 0x40 );
6562 fDfltTrueType
= 0 != ( a8Bit
& 0x80 );
6564 a8Bit
= Get_Byte( pData
); // 7 0x07
6565 fPagSuppressTopSpacing
= 0 != ( a8Bit
& 0x01 );
6566 fProtEnabled
= 0 != ( a8Bit
& 0x02 );
6567 fDispFormFldSel
= 0 != ( a8Bit
& 0x04 );
6568 fRMView
= 0 != ( a8Bit
& 0x08 );
6569 fRMPrint
= 0 != ( a8Bit
& 0x10 );
6570 fWriteReservation
= 0 != ( a8Bit
& 0x20 );
6571 fLockRev
= 0 != ( a8Bit
& 0x40 );
6572 fEmbedFonts
= 0 != ( a8Bit
& 0x80 );
6575 a8Bit
= Get_Byte( pData
); // 8 0x08
6576 copts_fNoTabForInd
= 0 != ( a8Bit
& 0x01 );
6577 copts_fNoSpaceRaiseLower
= 0 != ( a8Bit
& 0x02 );
6578 copts_fSupressSpbfAfterPgBrk
= 0 != ( a8Bit
& 0x04 );
6579 copts_fWrapTrailSpaces
= 0 != ( a8Bit
& 0x08 );
6580 copts_fMapPrintTextColor
= 0 != ( a8Bit
& 0x10 );
6581 copts_fNoColumnBalance
= 0 != ( a8Bit
& 0x20 );
6582 copts_fConvMailMergeEsc
= 0 != ( a8Bit
& 0x40 );
6583 copts_fSupressTopSpacing
= 0 != ( a8Bit
& 0x80 );
6585 a8Bit
= Get_Byte( pData
); // 9 0x09
6586 copts_fOrigWordTableRules
= 0 != ( a8Bit
& 0x01 );
6587 copts_fTransparentMetafiles
= 0 != ( a8Bit
& 0x02 );
6588 copts_fShowBreaksInFrames
= 0 != ( a8Bit
& 0x04 );
6589 copts_fSwapBordersFacingPgs
= 0 != ( a8Bit
& 0x08 );
6590 copts_fExpShRtn
= 0 != ( a8Bit
& 0x20 ); // #i56856#
6592 dxaTab
= Get_Short( pData
); // 10 0x0a
6593 wSpare
= Get_UShort( pData
); // 12 0x0c
6594 dxaHotZ
= Get_UShort( pData
); // 14 0x0e
6595 cConsecHypLim
= Get_UShort( pData
); // 16 0x10
6596 wSpare2
= Get_UShort( pData
); // 18 0x12
6597 dttmCreated
= Get_Long( pData
); // 20 0x14
6598 dttmRevised
= Get_Long( pData
); // 24 0x18
6599 dttmLastPrint
= Get_Long( pData
); // 28 0x1c
6600 nRevision
= Get_Short( pData
); // 32 0x20
6601 tmEdited
= Get_Long( pData
); // 34 0x22
6602 cWords
= Get_Long( pData
); // 38 0x26
6603 cCh
= Get_Long( pData
); // 42 0x2a
6604 cPg
= Get_Short( pData
); // 46 0x2e
6605 cParas
= Get_Long( pData
); // 48 0x30
6607 a16Bit
= Get_UShort( pData
); // 52 0x34
6608 rncEdn
= a16Bit
& 0x0003 ;
6609 nEdn
= ( a16Bit
& ~0x0003 ) >> 2;
6611 a16Bit
= Get_UShort( pData
); // 54 0x36
6612 epc
= a16Bit
& 0x0003 ;
6613 nfcFtnRef
= ( a16Bit
& 0x003c ) >> 2;
6614 nfcEdnRef
= ( a16Bit
& 0x03c0 ) >> 6;
6615 fPrintFormData
= 0 != ( a16Bit
& 0x0400 );
6616 fSaveFormData
= 0 != ( a16Bit
& 0x0800 );
6617 fShadeFormData
= 0 != ( a16Bit
& 0x1000 );
6618 fWCFtnEdn
= 0 != ( a16Bit
& 0x8000 );
6620 cLines
= Get_Long( pData
); // 56 0x38
6621 cWordsFtnEnd
= Get_Long( pData
); // 60 0x3c
6622 cChFtnEdn
= Get_Long( pData
); // 64 0x40
6623 cPgFtnEdn
= Get_Short( pData
); // 68 0x44
6624 cParasFtnEdn
= Get_Long( pData
); // 70 0x46
6625 cLinesFtnEdn
= Get_Long( pData
); // 74 0x4a
6626 lKeyProtDoc
= Get_Long( pData
); // 78 0x4e
6628 a16Bit
= Get_UShort( pData
); // 82 0x52
6629 wvkSaved
= a16Bit
& 0x0007 ;
6630 wScaleSaved
= ( a16Bit
& 0x0ff8 ) >> 3 ;
6631 zkSaved
= ( a16Bit
& 0x3000 ) >> 12;
6632 fRotateFontW6
= ( a16Bit
& 0x4000 ) >> 14;
6633 iGutterPos
= ( a16Bit
& 0x8000 ) >> 15;
6635 bei nFib >= 103 gehts weiter:
6637 if (nFib
>= 103) // Word 6/32bit, 95, 97, 2000, 2002, 2003, 2007
6639 a32Bit
= Get_ULong( pData
); // 84 0x54
6640 SetCompatabilityOptions(a32Bit
);
6643 //#i22436#, for all WW7- documents
6644 if (nFib
<= 104) // Word 95
6645 fUsePrinterMetrics
= 1;
6648 bei nFib > 105 gehts weiter:
6650 if (nFib
> 105) // Word 97, 2000, 2002, 2003, 2007
6652 adt
= Get_Short( pData
); // 88 0x58
6654 doptypography
.ReadFromMem(pData
); // 90 0x5a
6656 memcpy( &dogrid
, pData
, sizeof( WW8_DOGRID
)); // 400 0x190
6657 pData
+= sizeof( WW8_DOGRID
);
6659 a16Bit
= Get_UShort( pData
); // 410 0x19a
6660 // die untersten 9 Bit sind uninteressant
6661 fHtmlDoc
= ( a16Bit
& 0x0200 ) >> 9 ;
6662 fSnapBorder
= ( a16Bit
& 0x0800 ) >> 11 ;
6663 fIncludeHeader
= ( a16Bit
& 0x1000 ) >> 12 ;
6664 fIncludeFooter
= ( a16Bit
& 0x2000 ) >> 13 ;
6665 fForcePageSizePag
= ( a16Bit
& 0x4000 ) >> 14 ;
6666 fMinFontSizePag
= ( a16Bit
& 0x8000 ) >> 15 ;
6668 a16Bit
= Get_UShort( pData
); // 412 0x19c
6669 fHaveVersions
= 0 != ( a16Bit
& 0x0001 );
6670 fAutoVersion
= 0 != ( a16Bit
& 0x0002 );
6672 pData
+= 12; // 414 0x19e
6674 cChWS
= Get_Long( pData
); // 426 0x1aa
6675 cChWSFtnEdn
= Get_Long( pData
); // 430 0x1ae
6676 grfDocEvents
= Get_Long( pData
); // 434 0x1b2
6678 pData
+= 4+30+8; // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc
6680 cDBC
= Get_Long( pData
); // 480 0x1e0
6681 cDBCFtnEdn
= Get_Long( pData
); // 484 0x1e4
6683 pData
+= 1 * sizeof( sal_Int32
); // 488 0x1e8
6685 nfcFtnRef
= Get_Short( pData
); // 492 0x1ec
6686 nfcEdnRef
= Get_Short( pData
); // 494 0x1ee
6687 hpsZoonFontPag
= Get_Short( pData
); // 496 0x1f0
6688 dywDispPag
= Get_Short( pData
); // 498 0x1f2
6692 //500 -> 508, Appear to be repeated here in 2000+
6693 pData
+= 8; // 500 0x1f4
6694 a32Bit
= Get_Long( pData
); // 508 0x1fc
6695 SetCompatabilityOptions(a32Bit
);
6696 a32Bit
= Get_Long( pData
); // 512 0x200
6699 SetCompatabilityOptions2(a32Bit
);
6704 a16Bit
= Get_UShort( pData
);
6705 fDoNotEmbedSystemFont
= ( a16Bit
& 0x0001 );
6706 fWordCompat
= ( a16Bit
& 0x0002 ) >> 1;
6707 fLiveRecover
= ( a16Bit
& 0x0004 ) >> 2;
6708 fEmbedFactoids
= ( a16Bit
& 0x0008 ) >> 3;
6709 fFactoidXML
= ( a16Bit
& 0x00010 ) >> 4;
6710 fFactoidAllDone
= ( a16Bit
& 0x0020 ) >> 5;
6711 fFolioPrint
= ( a16Bit
& 0x0040 ) >> 6;
6712 fReverseFolio
= ( a16Bit
& 0x0080 ) >> 7;
6713 iTextLineEnding
= ( a16Bit
& 0x0700 ) >> 8;
6714 fHideFcc
= ( a16Bit
& 0x0800 ) >> 11;
6715 fAcetateShowMarkup
= ( a16Bit
& 0x1000 ) >> 12;
6716 fAcetateShowAtn
= ( a16Bit
& 0x2000 ) >> 13;
6717 fAcetateShowInsDel
= ( a16Bit
& 0x4000 ) >> 14;
6718 fAcetateShowProps
= ( a16Bit
& 0x8000 ) >> 15;
6723 a16Bit
= Get_Short(pData
);
6724 fUseBackGroundInAllmodes
= (a16Bit
& 0x0080) >> 7;
6731 WW8Dop::WW8Dop() : bUseThaiLineBreakingRules(false)
6733 // first set everything to a default of 0
6734 memset( &nDataStart
, 0, (&nDataEnd
- &nDataStart
) );
6739 fOutlineDirtySave
= 1;
6747 Writer acts like this all the time at the moment, ideally we need an
6748 option for these two as well to import word docs that are not like
6752 fUsePrinterMetrics
= 1;
6774 cChWSFtnEdn
= /**!!**/ 0;
6777 cDBCFtnEdn
= /**!!**/ 0;
6779 fAcetateShowAtn
= true;
6782 void WW8Dop::SetCompatabilityOptions(sal_uInt32 a32Bit
)
6784 fNoTabForInd
= ( a32Bit
& 0x00000001 ) ;
6785 fNoSpaceRaiseLower
= ( a32Bit
& 0x00000002 ) >> 1 ;
6786 fSupressSpbfAfterPageBreak
= ( a32Bit
& 0x00000004 ) >> 2 ;
6787 fWrapTrailSpaces
= ( a32Bit
& 0x00000008 ) >> 3 ;
6788 fMapPrintTextColor
= ( a32Bit
& 0x00000010 ) >> 4 ;
6789 fNoColumnBalance
= ( a32Bit
& 0x00000020 ) >> 5 ;
6790 fConvMailMergeEsc
= ( a32Bit
& 0x00000040 ) >> 6 ;
6791 fSupressTopSpacing
= ( a32Bit
& 0x00000080 ) >> 7 ;
6792 fOrigWordTableRules
= ( a32Bit
& 0x00000100 ) >> 8 ;
6793 fTransparentMetafiles
= ( a32Bit
& 0x00000200 ) >> 9 ;
6794 fShowBreaksInFrames
= ( a32Bit
& 0x00000400 ) >> 10 ;
6795 fSwapBordersFacingPgs
= ( a32Bit
& 0x00000800 ) >> 11 ;
6796 fCompatabilityOptions_Unknown1_13
= ( a32Bit
& 0x00001000 ) >> 12 ;
6797 fExpShRtn
= ( a32Bit
& 0x00002000 ) >> 13 ; // #i56856#
6798 fCompatabilityOptions_Unknown1_15
= ( a32Bit
& 0x00004000 ) >> 14 ;
6799 fCompatabilityOptions_Unknown1_16
= ( a32Bit
& 0x00008000 ) >> 15 ;
6800 fSuppressTopSpacingMac5
= ( a32Bit
& 0x00010000 ) >> 16 ;
6801 fTruncDxaExpand
= ( a32Bit
& 0x00020000 ) >> 17 ;
6802 fPrintBodyBeforeHdr
= ( a32Bit
& 0x00040000 ) >> 18 ;
6803 fNoLeading
= ( a32Bit
& 0x00080000 ) >> 19 ;
6804 fCompatabilityOptions_Unknown1_21
= ( a32Bit
& 0x00100000 ) >> 20 ;
6805 fMWSmallCaps
= ( a32Bit
& 0x00200000 ) >> 21 ;
6806 fCompatabilityOptions_Unknown1_23
= ( a32Bit
& 0x00400000 ) >> 22 ;
6807 fCompatabilityOptions_Unknown1_24
= ( a32Bit
& 0x00800800 ) >> 23 ;
6808 fCompatabilityOptions_Unknown1_25
= ( a32Bit
& 0x01000000 ) >> 24 ;
6809 fCompatabilityOptions_Unknown1_26
= ( a32Bit
& 0x02000000 ) >> 25 ;
6810 fCompatabilityOptions_Unknown1_27
= ( a32Bit
& 0x04000000 ) >> 26 ;
6811 fCompatabilityOptions_Unknown1_28
= ( a32Bit
& 0x08000000 ) >> 27 ;
6812 fCompatabilityOptions_Unknown1_29
= ( a32Bit
& 0x10000000 ) >> 28 ;
6813 fCompatabilityOptions_Unknown1_30
= ( a32Bit
& 0x20000000 ) >> 29 ;
6814 fCompatabilityOptions_Unknown1_31
= ( a32Bit
& 0x40000000 ) >> 30 ;
6816 fUsePrinterMetrics
= ( a32Bit
& 0x80000000 ) >> 31 ;
6819 sal_uInt32
WW8Dop::GetCompatabilityOptions() const
6821 sal_uInt32 a32Bit
= 0;
6822 if (fNoTabForInd
) a32Bit
|= 0x00000001;
6823 if (fNoSpaceRaiseLower
) a32Bit
|= 0x00000002;
6824 if (fSupressSpbfAfterPageBreak
) a32Bit
|= 0x00000004;
6825 if (fWrapTrailSpaces
) a32Bit
|= 0x00000008;
6826 if (fMapPrintTextColor
) a32Bit
|= 0x00000010;
6827 if (fNoColumnBalance
) a32Bit
|= 0x00000020;
6828 if (fConvMailMergeEsc
) a32Bit
|= 0x00000040;
6829 if (fSupressTopSpacing
) a32Bit
|= 0x00000080;
6830 if (fOrigWordTableRules
) a32Bit
|= 0x00000100;
6831 if (fTransparentMetafiles
) a32Bit
|= 0x00000200;
6832 if (fShowBreaksInFrames
) a32Bit
|= 0x00000400;
6833 if (fSwapBordersFacingPgs
) a32Bit
|= 0x00000800;
6834 if (fCompatabilityOptions_Unknown1_13
) a32Bit
|= 0x00001000;
6835 if (fExpShRtn
) a32Bit
|= 0x00002000; // #i56856#
6836 if (fCompatabilityOptions_Unknown1_15
) a32Bit
|= 0x00004000;
6837 if (fCompatabilityOptions_Unknown1_16
) a32Bit
|= 0x00008000;
6838 if (fSuppressTopSpacingMac5
) a32Bit
|= 0x00010000;
6839 if (fTruncDxaExpand
) a32Bit
|= 0x00020000;
6840 if (fPrintBodyBeforeHdr
) a32Bit
|= 0x00040000;
6841 if (fNoLeading
) a32Bit
|= 0x00080000;
6842 if (fCompatabilityOptions_Unknown1_21
) a32Bit
|= 0x00100000;
6843 if (fMWSmallCaps
) a32Bit
|= 0x00200000;
6844 if (fCompatabilityOptions_Unknown1_23
) a32Bit
|= 0x00400000;
6845 if (fCompatabilityOptions_Unknown1_24
) a32Bit
|= 0x00800000;
6846 if (fCompatabilityOptions_Unknown1_25
) a32Bit
|= 0x01000000;
6847 if (fCompatabilityOptions_Unknown1_26
) a32Bit
|= 0x02000000;
6848 if (fCompatabilityOptions_Unknown1_27
) a32Bit
|= 0x04000000;
6849 if (fCompatabilityOptions_Unknown1_28
) a32Bit
|= 0x08000000;
6850 if (fCompatabilityOptions_Unknown1_29
) a32Bit
|= 0x10000000;
6851 if (fCompatabilityOptions_Unknown1_30
) a32Bit
|= 0x20000000;
6852 if (fCompatabilityOptions_Unknown1_31
) a32Bit
|= 0x40000000;
6853 if (fUsePrinterMetrics
) a32Bit
|= 0x80000000;
6858 void WW8Dop::SetCompatabilityOptions2(sal_uInt32 a32Bit
)
6860 fCompatabilityOptions_Unknown2_1
= ( a32Bit
& 0x00000001 );
6861 fCompatabilityOptions_Unknown2_2
= ( a32Bit
& 0x00000002 ) >> 1 ;
6862 fDontUseHTMLAutoSpacing
= ( a32Bit
& 0x00000004 ) >> 2 ;
6863 fCompatabilityOptions_Unknown2_4
= ( a32Bit
& 0x00000008 ) >> 3 ;
6864 fCompatabilityOptions_Unknown2_5
= ( a32Bit
& 0x00000010 ) >> 4 ;
6865 fCompatabilityOptions_Unknown2_6
= ( a32Bit
& 0x00000020 ) >> 5 ;
6866 fCompatabilityOptions_Unknown2_7
= ( a32Bit
& 0x00000040 ) >> 6 ;
6867 fCompatabilityOptions_Unknown2_8
= ( a32Bit
& 0x00000080 ) >> 7 ;
6868 fCompatabilityOptions_Unknown2_9
= ( a32Bit
& 0x00000100 ) >> 8 ;
6869 fCompatabilityOptions_Unknown2_10
= ( a32Bit
& 0x00000200 ) >> 9 ;
6870 fCompatabilityOptions_Unknown2_11
= ( a32Bit
& 0x00000400 ) >> 10 ;
6871 fCompatabilityOptions_Unknown2_12
= ( a32Bit
& 0x00000800 ) >> 11 ;
6872 fCompatabilityOptions_Unknown2_13
= ( a32Bit
& 0x00001000 ) >> 12 ;
6873 fCompatabilityOptions_Unknown2_14
= ( a32Bit
& 0x00002000 ) >> 13 ;
6874 fCompatabilityOptions_Unknown2_15
= ( a32Bit
& 0x00004000 ) >> 14 ;
6875 fCompatabilityOptions_Unknown2_16
= ( a32Bit
& 0x00008000 ) >> 15 ;
6876 fCompatabilityOptions_Unknown2_17
= ( a32Bit
& 0x00010000 ) >> 16 ;
6877 fCompatabilityOptions_Unknown2_18
= ( a32Bit
& 0x00020000 ) >> 17 ;
6878 fCompatabilityOptions_Unknown2_19
= ( a32Bit
& 0x00040000 ) >> 18 ;
6879 fCompatabilityOptions_Unknown2_20
= ( a32Bit
& 0x00080000 ) >> 19 ;
6880 fCompatabilityOptions_Unknown2_21
= ( a32Bit
& 0x00100000 ) >> 20 ;
6881 fCompatabilityOptions_Unknown2_22
= ( a32Bit
& 0x00200000 ) >> 21 ;
6882 fCompatabilityOptions_Unknown2_23
= ( a32Bit
& 0x00400000 ) >> 22 ;
6883 fCompatabilityOptions_Unknown2_24
= ( a32Bit
& 0x00800800 ) >> 23 ;
6884 fCompatabilityOptions_Unknown2_25
= ( a32Bit
& 0x01000800 ) >> 24 ;
6885 fCompatabilityOptions_Unknown2_26
= ( a32Bit
& 0x02000800 ) >> 25 ;
6886 fCompatabilityOptions_Unknown2_27
= ( a32Bit
& 0x04000800 ) >> 26 ;
6887 fCompatabilityOptions_Unknown2_28
= ( a32Bit
& 0x08000800 ) >> 27 ;
6888 fCompatabilityOptions_Unknown2_29
= ( a32Bit
& 0x10000800 ) >> 28 ;
6889 fCompatabilityOptions_Unknown2_30
= ( a32Bit
& 0x20000800 ) >> 29 ;
6890 fCompatabilityOptions_Unknown2_31
= ( a32Bit
& 0x40000800 ) >> 30 ;
6891 fCompatabilityOptions_Unknown2_32
= ( a32Bit
& 0x80000000 ) >> 31 ;
6894 sal_uInt32
WW8Dop::GetCompatabilityOptions2() const
6896 sal_uInt32 a32Bit
= 0;
6897 if (fCompatabilityOptions_Unknown2_1
) a32Bit
|= 0x00000001;
6898 if (fCompatabilityOptions_Unknown2_2
) a32Bit
|= 0x00000002;
6899 if (fDontUseHTMLAutoSpacing
) a32Bit
|= 0x00000004;
6900 if (fCompatabilityOptions_Unknown2_4
) a32Bit
|= 0x00000008;
6901 if (fCompatabilityOptions_Unknown2_5
) a32Bit
|= 0x00000010;
6902 if (fCompatabilityOptions_Unknown2_6
) a32Bit
|= 0x00000020;
6903 if (fCompatabilityOptions_Unknown2_7
) a32Bit
|= 0x00000040;
6904 if (fCompatabilityOptions_Unknown2_8
) a32Bit
|= 0x00000080;
6905 if (fCompatabilityOptions_Unknown2_9
) a32Bit
|= 0x00000100;
6906 if (fCompatabilityOptions_Unknown2_10
) a32Bit
|= 0x00000200;
6907 if (fCompatabilityOptions_Unknown2_11
) a32Bit
|= 0x00000400;
6908 if (fCompatabilityOptions_Unknown2_12
) a32Bit
|= 0x00000800;
6909 if (fCompatabilityOptions_Unknown2_13
) a32Bit
|= 0x00001000;
6910 //#i42909# set thai "line breaking rules" compatibility option
6911 // pflin, wonder whether bUseThaiLineBreakingRules is correct
6912 // when importing word document.
6913 if (bUseThaiLineBreakingRules
) a32Bit
|= 0x00002000;
6914 else if (fCompatabilityOptions_Unknown2_14
) a32Bit
|= 0x00002000;
6915 if (fCompatabilityOptions_Unknown2_15
) a32Bit
|= 0x00004000;
6916 if (fCompatabilityOptions_Unknown2_16
) a32Bit
|= 0x00008000;
6917 if (fCompatabilityOptions_Unknown2_17
) a32Bit
|= 0x00010000;
6918 if (fCompatabilityOptions_Unknown2_18
) a32Bit
|= 0x00020000;
6919 if (fCompatabilityOptions_Unknown2_19
) a32Bit
|= 0x00040000;
6920 if (fCompatabilityOptions_Unknown2_20
) a32Bit
|= 0x00080000;
6921 if (fCompatabilityOptions_Unknown2_21
) a32Bit
|= 0x00100000;
6922 if (fCompatabilityOptions_Unknown2_22
) a32Bit
|= 0x00200000;
6923 if (fCompatabilityOptions_Unknown2_23
) a32Bit
|= 0x00400000;
6924 if (fCompatabilityOptions_Unknown2_24
) a32Bit
|= 0x00800000;
6925 if (fCompatabilityOptions_Unknown2_25
) a32Bit
|= 0x01000000;
6926 if (fCompatabilityOptions_Unknown2_26
) a32Bit
|= 0x02000000;
6927 if (fCompatabilityOptions_Unknown2_27
) a32Bit
|= 0x04000000;
6928 if (fCompatabilityOptions_Unknown2_28
) a32Bit
|= 0x08000000;
6929 if (fCompatabilityOptions_Unknown2_29
) a32Bit
|= 0x10000000;
6930 if (fCompatabilityOptions_Unknown2_30
) a32Bit
|= 0x20000000;
6931 if (fCompatabilityOptions_Unknown2_31
) a32Bit
|= 0x40000000;
6932 if (fCompatabilityOptions_Unknown2_32
) a32Bit
|= 0x80000000;
6936 bool WW8Dop::Write(SvStream
& rStrm
, WW8Fib
& rFib
) const
6938 const int nMaxDopLen
= 610;
6939 sal_uInt32 nLen
= 8 == rFib
.nVersion
? nMaxDopLen
: 84;
6940 rFib
.fcDop
= rStrm
.Tell();
6943 sal_uInt8 aData
[ nMaxDopLen
];
6944 memset( aData
, 0, nMaxDopLen
);
6945 sal_uInt8
* pData
= aData
;
6947 // dann mal die Daten auswerten
6951 a16Bit
= 0; // 0 0x00
6958 a16Bit
|= ( 0x0018 & (grfSuppression
<< 3));
6959 a16Bit
|= ( 0x0060 & (fpc
<< 5));
6960 a16Bit
|= ( 0xff00 & (grpfIhdt
<< 8));
6961 Set_UInt16( pData
, a16Bit
);
6963 a16Bit
= 0; // 2 0x02
6964 a16Bit
|= ( 0x0003 & rncFtn
);
6965 a16Bit
|= ( ~0x0003 & (nFtn
<< 2));
6966 Set_UInt16( pData
, a16Bit
);
6968 a8Bit
= 0; // 4 0x04
6969 if( fOutlineDirtySave
) a8Bit
|= 0x01;
6970 Set_UInt8( pData
, a8Bit
);
6972 a8Bit
= 0; // 5 0x05
6973 if( fOnlyMacPics
) a8Bit
|= 0x01;
6974 if( fOnlyWinPics
) a8Bit
|= 0x02;
6975 if( fLabelDoc
) a8Bit
|= 0x04;
6976 if( fHyphCapitals
) a8Bit
|= 0x08;
6977 if( fAutoHyphen
) a8Bit
|= 0x10;
6978 if( fFormNoFields
) a8Bit
|= 0x20;
6979 if( fLinkStyles
) a8Bit
|= 0x40;
6980 if( fRevMarking
) a8Bit
|= 0x80;
6981 Set_UInt8( pData
, a8Bit
);
6983 a8Bit
= 0; // 6 0x06
6984 if( fBackup
) a8Bit
|= 0x01;
6985 if( fExactCWords
) a8Bit
|= 0x02;
6986 if( fPagHidden
) a8Bit
|= 0x04;
6987 if( fPagResults
) a8Bit
|= 0x08;
6988 if( fLockAtn
) a8Bit
|= 0x10;
6989 if( fMirrorMargins
) a8Bit
|= 0x20;
6990 if( fReadOnlyRecommended
) a8Bit
|= 0x40;
6991 if( fDfltTrueType
) a8Bit
|= 0x80;
6992 Set_UInt8( pData
, a8Bit
);
6994 a8Bit
= 0; // 7 0x07
6995 if( fPagSuppressTopSpacing
) a8Bit
|= 0x01;
6996 if( fProtEnabled
) a8Bit
|= 0x02;
6997 if( fDispFormFldSel
) a8Bit
|= 0x04;
6998 if( fRMView
) a8Bit
|= 0x08;
6999 if( fRMPrint
) a8Bit
|= 0x10;
7000 if( fWriteReservation
) a8Bit
|= 0x20;
7001 if( fLockRev
) a8Bit
|= 0x40;
7002 if( fEmbedFonts
) a8Bit
|= 0x80;
7003 Set_UInt8( pData
, a8Bit
);
7006 a8Bit
= 0; // 8 0x08
7007 if( copts_fNoTabForInd
) a8Bit
|= 0x01;
7008 if( copts_fNoSpaceRaiseLower
) a8Bit
|= 0x02;
7009 if( copts_fSupressSpbfAfterPgBrk
) a8Bit
|= 0x04;
7010 if( copts_fWrapTrailSpaces
) a8Bit
|= 0x08;
7011 if( copts_fMapPrintTextColor
) a8Bit
|= 0x10;
7012 if( copts_fNoColumnBalance
) a8Bit
|= 0x20;
7013 if( copts_fConvMailMergeEsc
) a8Bit
|= 0x40;
7014 if( copts_fSupressTopSpacing
) a8Bit
|= 0x80;
7015 Set_UInt8( pData
, a8Bit
);
7017 a8Bit
= 0; // 9 0x09
7018 if( copts_fOrigWordTableRules
) a8Bit
|= 0x01;
7019 if( copts_fTransparentMetafiles
) a8Bit
|= 0x02;
7020 if( copts_fShowBreaksInFrames
) a8Bit
|= 0x04;
7021 if( copts_fSwapBordersFacingPgs
) a8Bit
|= 0x08;
7022 if( copts_fExpShRtn
) a8Bit
|= 0x20; // #i56856#
7023 Set_UInt8( pData
, a8Bit
);
7025 Set_UInt16( pData
, dxaTab
); // 10 0x0a
7026 Set_UInt16( pData
, wSpare
); // 12 0x0c
7027 Set_UInt16( pData
, dxaHotZ
); // 14 0x0e
7028 Set_UInt16( pData
, cConsecHypLim
); // 16 0x10
7029 Set_UInt16( pData
, wSpare2
); // 18 0x12
7030 Set_UInt32( pData
, dttmCreated
); // 20 0x14
7031 Set_UInt32( pData
, dttmRevised
); // 24 0x18
7032 Set_UInt32( pData
, dttmLastPrint
); // 28 0x1c
7033 Set_UInt16( pData
, nRevision
); // 32 0x20
7034 Set_UInt32( pData
, tmEdited
); // 34 0x22
7035 Set_UInt32( pData
, cWords
); // 38 0x26
7036 Set_UInt32( pData
, cCh
); // 42 0x2a
7037 Set_UInt16( pData
, cPg
); // 46 0x2e
7038 Set_UInt32( pData
, cParas
); // 48 0x30
7040 a16Bit
= 0; // 52 0x34
7041 a16Bit
|= ( 0x0003 & rncEdn
);
7042 a16Bit
|= (~0x0003 & ( nEdn
<< 2));
7043 Set_UInt16( pData
, a16Bit
);
7045 a16Bit
= 0; // 54 0x36
7046 a16Bit
|= (0x0003 & epc
);
7047 a16Bit
|= (0x003c & (nfcFtnRef
<< 2));
7048 a16Bit
|= (0x03c0 & (nfcEdnRef
<< 6));
7049 if( fPrintFormData
) a16Bit
|= 0x0400;
7050 if( fSaveFormData
) a16Bit
|= 0x0800;
7051 if( fShadeFormData
) a16Bit
|= 0x1000;
7052 if( fWCFtnEdn
) a16Bit
|= 0x8000;
7053 Set_UInt16( pData
, a16Bit
);
7055 Set_UInt32( pData
, cLines
); // 56 0x38
7056 Set_UInt32( pData
, cWordsFtnEnd
); // 60 0x3c
7057 Set_UInt32( pData
, cChFtnEdn
); // 64 0x40
7058 Set_UInt16( pData
, cPgFtnEdn
); // 68 0x44
7059 Set_UInt32( pData
, cParasFtnEdn
); // 70 0x46
7060 Set_UInt32( pData
, cLinesFtnEdn
); // 74 0x4a
7061 Set_UInt32( pData
, lKeyProtDoc
); // 78 0x4e
7063 a16Bit
= 0; // 82 0x52
7066 a16Bit
|= (0x0ff8 & (wScaleSaved
<< 3));
7067 a16Bit
|= (0x3000 & (zkSaved
<< 12));
7068 Set_UInt16( pData
, a16Bit
);
7070 if( 8 == rFib
.nVersion
)
7072 Set_UInt32(pData
, GetCompatabilityOptions()); // 84 0x54
7074 Set_UInt16( pData
, adt
); // 88 0x58
7076 doptypography
.WriteToMem(pData
); // 400 0x190
7078 memcpy( pData
, &dogrid
, sizeof( WW8_DOGRID
));
7079 pData
+= sizeof( WW8_DOGRID
);
7081 a16Bit
= 0x12; // lvl auf 9 setzen // 410 0x19a
7082 if( fHtmlDoc
) a16Bit
|= 0x0200;
7083 if( fSnapBorder
) a16Bit
|= 0x0800;
7084 if( fIncludeHeader
) a16Bit
|= 0x1000;
7085 if( fIncludeFooter
) a16Bit
|= 0x2000;
7086 if( fForcePageSizePag
) a16Bit
|= 0x4000;
7087 if( fMinFontSizePag
) a16Bit
|= 0x8000;
7088 Set_UInt16( pData
, a16Bit
);
7090 a16Bit
= 0; // 412 0x19c
7091 if( fHaveVersions
) a16Bit
|= 0x0001;
7092 if( fAutoVersion
) a16Bit
|= 0x0002;
7093 Set_UInt16( pData
, a16Bit
);
7095 pData
+= 12; // 414 0x19e
7097 Set_UInt32( pData
, cChWS
); // 426 0x1aa
7098 Set_UInt32( pData
, cChWSFtnEdn
); // 430 0x1ae
7099 Set_UInt32( pData
, grfDocEvents
); // 434 0x1b2
7101 pData
+= 4+30+8; // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc
7103 Set_UInt32( pData
, cDBC
); // 480 0x1e0
7104 Set_UInt32( pData
, cDBCFtnEdn
); // 484 0x1e4
7106 pData
+= 1 * sizeof( sal_Int32
); // 488 0x1e8
7108 Set_UInt16( pData
, nfcFtnRef
); // 492 0x1ec
7109 Set_UInt16( pData
, nfcEdnRef
); // 494 0x1ee
7110 Set_UInt16( pData
, hpsZoonFontPag
); // 496 0x1f0
7111 Set_UInt16( pData
, dywDispPag
); // 498 0x1f2
7113 //500 -> 508, Appear to be repeated here in 2000+
7115 Set_UInt32(pData
, GetCompatabilityOptions());
7116 Set_UInt32(pData
, GetCompatabilityOptions2());
7120 if (fAcetateShowMarkup
)
7122 //Word XP at least requires fAcetateShowMarkup to honour fAcetateShowAtn
7123 if (fAcetateShowAtn
)
7128 Set_UInt16(pData
, a16Bit
);
7132 Set_UInt16(pData
, a16Bit
);
7134 rStrm
.Write( aData
, nLen
);
7135 return 0 == rStrm
.GetError();
7138 void WW8DopTypography::ReadFromMem(sal_uInt8
*&pData
)
7140 sal_uInt16 a16Bit
= Get_UShort(pData
);
7141 fKerningPunct
= (a16Bit
& 0x0001);
7142 iJustification
= (a16Bit
& 0x0006) >> 1;
7143 iLevelOfKinsoku
= (a16Bit
& 0x0018) >> 3;
7144 f2on1
= (a16Bit
& 0x0020) >> 5;
7145 reserved1
= (a16Bit
& 0x03C0) >> 6;
7146 reserved2
= (a16Bit
& 0xFC00) >> 10;
7148 cchFollowingPunct
= Get_Short(pData
);
7149 cchLeadingPunct
= Get_Short(pData
);
7152 for (i
=0; i
< nMaxFollowing
; ++i
)
7153 rgxchFPunct
[i
] = Get_Short(pData
);
7154 for (i
=0; i
< nMaxLeading
; ++i
)
7155 rgxchLPunct
[i
] = Get_Short(pData
);
7157 if (cchFollowingPunct
>= 0 && cchFollowingPunct
< nMaxFollowing
)
7158 rgxchFPunct
[cchFollowingPunct
]=0;
7160 rgxchFPunct
[nMaxFollowing
- 1]=0;
7162 if (cchLeadingPunct
>= 0 && cchLeadingPunct
< nMaxLeading
)
7163 rgxchLPunct
[cchLeadingPunct
]=0;
7165 rgxchLPunct
[nMaxLeading
- 1]=0;
7169 void WW8DopTypography::WriteToMem(sal_uInt8
*&pData
) const
7171 sal_uInt16 a16Bit
= fKerningPunct
;
7172 a16Bit
|= (iJustification
<< 1) & 0x0006;
7173 a16Bit
|= (iLevelOfKinsoku
<< 3) & 0x0018;
7174 a16Bit
|= (f2on1
<< 5) & 0x002;
7175 a16Bit
|= (reserved1
<< 6) & 0x03C0;
7176 a16Bit
|= (reserved2
<< 10) & 0xFC00;
7177 Set_UInt16(pData
,a16Bit
);
7179 Set_UInt16(pData
,cchFollowingPunct
);
7180 Set_UInt16(pData
,cchLeadingPunct
);
7183 for (i
=0; i
< nMaxFollowing
; ++i
)
7184 Set_UInt16(pData
,rgxchFPunct
[i
]);
7185 for (i
=0; i
< nMaxLeading
; ++i
)
7186 Set_UInt16(pData
,rgxchLPunct
[i
]);
7189 sal_uInt16
WW8DopTypography::GetConvertedLang() const
7192 //I have assumed peoples republic/taiwan == simplified/traditional
7194 //This isn't a documented issue, so we might have it all wrong,
7195 //i.e. i.e. whats with the powers of two ?
7198 One example of 3 for reserved1 which was really Japanese, perhaps last bit
7199 is for some other use ?, or redundant. If more examples trigger the assert
7200 we might be able to figure it out.
7202 switch(reserved1
& 0xE)
7205 nLang
= LANGUAGE_JAPANESE
;
7207 case 4: //Chinese (Peoples Republic)
7208 nLang
= LANGUAGE_CHINESE_SIMPLIFIED
;
7211 nLang
= LANGUAGE_KOREAN
;
7213 case 8: //Chinese (Taiwan)
7214 nLang
= LANGUAGE_CHINESE_TRADITIONAL
;
7217 OSL_ENSURE(!this, "Unknown MS Asian Typography language, report");
7218 nLang
= LANGUAGE_CHINESE
;
7221 //And here we have the possibility that it says 2, but its really
7222 //a bug and only japanese level 2 has been selected after a custom
7223 //version was chosen on last save!
7224 nLang
= LANGUAGE_JAPANESE
;
7233 sal_uInt16
wwSprmParser::GetSprmTailLen(sal_uInt16 nId
, const sal_uInt8
* pSprm
)
7236 SprmInfo aSprm
= GetSprmInfo(nId
);
7237 sal_uInt16 nL
= 0; // number of Bytes to read
7244 if( pSprm
[1 + mnDelta
] != 255 )
7245 nL
= static_cast< sal_uInt16
>(pSprm
[1 + mnDelta
] + aSprm
.nLen
);
7248 sal_uInt8 nDel
= pSprm
[2 + mnDelta
];
7249 sal_uInt8 nIns
= pSprm
[3 + mnDelta
+ 4 * nDel
];
7251 nL
= 2 + 4 * nDel
+ 3 * nIns
;
7255 nL
= SVBT16ToShort( &pSprm
[1 + mnDelta
] );
7258 switch (aSprm
.nVari
)
7261 nL
= aSprm
.nLen
; // Excl. Token
7264 // Variable 1-Byte Length?
7265 // Excl. Token + Var-Lengthbyte
7266 nL
= static_cast< sal_uInt16
>(pSprm
[1 + mnDelta
] + aSprm
.nLen
);
7269 // Variable 2-Byte Length?
7270 // Excl. Token + Var-Lengthbyte
7271 nL
= static_cast< sal_uInt16
>(SVBT16ToShort( &pSprm
[1 + mnDelta
] ) + aSprm
.nLen
- 1);
7274 OSL_ENSURE(!this, "Unknown sprm varient");
7282 // one or two bytes at the beginning at the sprm id
7283 sal_uInt16
wwSprmParser::GetSprmId(const sal_uInt8
* pSp
) const
7285 ASSERT_RET_ON_FAIL(pSp
, "Why GetSprmId with pSp of 0", 0);
7289 if (ww::IsSevenMinus(meVersion
))
7297 nId
= SVBT16ToShort(pSp
);
7305 // with tokens and length byte
7306 sal_uInt16
wwSprmParser::GetSprmSize(sal_uInt16 nId
, const sal_uInt8
* pSprm
) const
7308 return GetSprmTailLen(nId
, pSprm
) + 1 + mnDelta
+ SprmDataOfs(nId
);
7311 sal_uInt8
wwSprmParser::SprmDataOfs(sal_uInt16 nId
) const
7313 return GetSprmInfo(nId
).nVari
;
7316 sal_uInt16
wwSprmParser::DistanceToData(sal_uInt16 nId
) const
7318 return 1 + mnDelta
+ SprmDataOfs(nId
);
7321 sal_uInt8
* wwSprmParser::findSprmData(sal_uInt16 nId
, sal_uInt8
* pSprms
,
7322 sal_uInt16 nLen
) const
7324 while (nLen
>= MinSprmLen())
7326 sal_uInt16 nAktId
= GetSprmId(pSprms
);
7327 // gib Zeiger auf Daten
7328 sal_uInt16 nSize
= GetSprmSize(nAktId
, pSprms
);
7330 bool bValid
= nSize
<= nLen
;
7332 SAL_WARN_IF(!bValid
, "sw.ww8",
7333 "sprm 0x" << std::hex
<< nAktId
<< std::dec
<< " longer than remaining bytes, " <<
7334 nSize
<< " vs " << nLen
<< "doc or parser is wrong");
7336 if (nAktId
== nId
&& bValid
) // Sprm found
7337 return pSprms
+ DistanceToData(nId
);
7339 //Clip to available size if wrong
7340 nSize
= std::min(nSize
, nLen
);
7349 bkc(2), fTitlePage(0), fAutoPgn(0), nfcPgn(0), fUnlocked(0), cnsPgn(0),
7350 fPgnRestart(0), fEndNote(1), lnc(0), grpfIhdt(0), nLnnMod(0), dxaLnn(0),
7351 dxaPgn(720), dyaPgn(720), fLBetween(0), vjc(0), dmBinFirst(0),
7352 dmBinOther(0), dmPaperReq(0), fPropRMark(0), ibstPropRMark(0),
7353 dttmPropRMark(0), dxtCharSpace(0), dyaLinePitch(0), clm(0), reserved1(0),
7354 dmOrientPage(0), iHeadingPgn(0), pgnStart(1), lnnMin(0), wTextFlow(0),
7355 reserved2(0), pgbApplyTo(0), pgbPageDepth(0), pgbOffsetFrom(0),
7356 xaPage(lLetterWidth
), yaPage(lLetterHeight
), xaPageNUp(lLetterWidth
), yaPageNUp(lLetterHeight
),
7357 dxaLeft(1800), dxaRight(1800), dyaTop(1440), dyaBottom(1440), dzaGutter(0),
7358 dyaHdrTop(720), dyaHdrBottom(720), ccolM1(0), fEvenlySpaced(1),
7359 reserved3(0), fBiDi(0), fFacingCol(0), fRTLGutter(0), fRTLAlignment(0),
7360 dxaColumns(720), dxaColumnWidth(0), dmOrientFirst(0), fLayout(0),
7363 memset(rgdxaColumnWidthSpacing
, 0, sizeof(rgdxaColumnWidthSpacing
));
7366 bool checkSeek(SvStream
&rSt
, sal_uInt32 nOffset
)
7368 return (rSt
.Seek(nOffset
) == static_cast<sal_Size
>(nOffset
));
7371 bool checkRead(SvStream
&rSt
, void *pDest
, sal_uInt32 nLength
)
7373 return (rSt
.Read(pDest
, nLength
) == static_cast<sal_Size
>(nLength
));
7376 #ifdef OSL_BIGENDIAN
7377 void swapEndian(sal_Unicode
*pString
)
7379 for (sal_Unicode
*pWork
= pString
; *pWork
; ++pWork
)
7380 *pWork
= OSL_SWAPWORD(*pWork
);
7384 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */