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

Generated by: LCOV version 1.10