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