LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - ww8scan.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 3212 3687 87.1 %
Date: 2015-06-13 12:38:46 Functions: 234 257 91.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11