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

Generated by: LCOV version 1.10