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-17 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         804 :     template<typename C> bool TestBeltAndBraces(SvStream& rStrm)
      82             :     {
      83         804 :         bool bRet = false;
      84         804 :         sal_uInt32 nOldPos = rStrm.Tell();
      85         804 :         C nBelt(0);
      86         804 :         rStrm >> nBelt;
      87         804 :         nBelt *= sizeof(C);
      88         804 :         if (rStrm.good() && (rStrm.remainingSize() >= (nBelt + sizeof(C))))
      89             :         {
      90         804 :             rStrm.SeekRel(nBelt);
      91         804 :             if (rStrm.good())
      92             :             {
      93         804 :                 C cBraces(0);
      94         804 :                 rStrm >> cBraces;
      95         804 :                 if (rStrm.good() && cBraces == 0)
      96         804 :                     bRet = true;
      97             :             }
      98             :         }
      99         804 :         rStrm.Seek(nOldPos);
     100         804 :         return bRet;
     101             :     }
     102             : }
     103             : 
     104     1334026 : inline bool operator==(const SprmInfo &rFirst, const SprmInfo &rSecond)
     105             : {
     106     1334026 :     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        1914 : 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        1914 :     static wwSprmSearcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
     779        1914 :     return &aSprmSrch;
     780             : };
     781             : 
     782        1914 : wwSprmParser::wwSprmParser(ww::WordVersion eVersion) : meVersion(eVersion)
     783             : {
     784             :    OSL_ENSURE((meVersion >= ww::eWW2 && meVersion <= ww::eWW8),
     785             :         "Impossible value for version");
     786             : 
     787        1914 :     mnDelta = (ww::IsSevenMinus(meVersion)) ? 0 : 1;
     788             : 
     789        1914 :     if (meVersion <= ww::eWW2)
     790           0 :         mpKnownSprms = GetWW2SprmSearcher();
     791        1914 :     else if (meVersion < ww::eWW8)
     792           0 :         mpKnownSprms = GetWW6SprmSearcher();
     793             :     else
     794        1914 :         mpKnownSprms = GetWW8SprmSearcher();
     795        1914 : }
     796             : 
     797     1421906 : SprmInfo wwSprmParser::GetSprmInfo(sal_uInt16 nId) const
     798             : {
     799             :     // Find sprm
     800     1421906 :     SprmInfo aSrch={0,0,0};
     801     1421906 :     aSrch.nId = nId;
     802     1421906 :     const SprmInfo* pFound = mpKnownSprms->search(aSrch);
     803     1421906 :     if (pFound == 0)
     804             :     {
     805             :         OSL_ENSURE(ww::IsEightPlus(meVersion),
     806             :            "Unknown ww7- sprm, dangerous, report to development");
     807             : 
     808       87880 :         aSrch.nId = 0;
     809       87880 :         aSrch.nLen = 0;
     810             :         //All the unknown ww7 sprms appear to be variable (which makes sense)
     811       87880 :         aSrch.nVari = L_VAR;
     812             : 
     813       87880 :         if (ww::IsEightPlus(meVersion)) //We can recover perfectly in this case
     814             :         {
     815       87880 :             aSrch.nVari = L_FIX;
     816       87880 :             switch (nId >> 13)
     817             :             {
     818             :                 case 0:
     819             :                 case 1:
     820        2774 :                     aSrch.nLen = 1;
     821        2774 :                     break;
     822             :                 case 2:
     823       13948 :                     aSrch.nLen = 2;
     824       13948 :                     break;
     825             :                 case 3:
     826       18134 :                     aSrch.nLen = 4;
     827       18134 :                     break;
     828             :                 case 4:
     829             :                 case 5:
     830        1618 :                     aSrch.nLen = 2;
     831        1618 :                     break;
     832             :                 case 6:
     833       36538 :                     aSrch.nLen = 0;
     834       36538 :                     aSrch.nVari =  L_VAR;
     835       36538 :                     break;
     836             :                 case 7:
     837             :                 default:
     838       14868 :                     aSrch.nLen = 3;
     839       14868 :                     break;
     840             :             }
     841             :         }
     842             : 
     843       87880 :         pFound = &aSrch;
     844             :     }
     845     1421906 :     return *pFound;
     846             : }
     847             : 
     848             : //-end
     849             : 
     850         444 : inline sal_uInt8 Get_Byte( sal_uInt8 *& p )
     851             : {
     852         444 :     sal_uInt8 n = SVBT8ToByte( *(SVBT8*)p );
     853         444 :     p += 1;
     854         444 :     return n;
     855             : }
     856             : 
     857       13042 : inline sal_uInt16 Get_UShort( sal_uInt8 *& p )
     858             : {
     859       13042 :     sal_uInt16 n = SVBT16ToShort( *(SVBT16*)p );
     860       13042 :     p += 2;
     861       13042 :     return n;
     862             : }
     863             : 
     864       12102 : inline short Get_Short( sal_uInt8 *& p )
     865             : {
     866       12102 :     return Get_UShort(p);
     867             : }
     868             : 
     869       16268 : inline sal_uLong Get_ULong( sal_uInt8 *& p )
     870             : {
     871       16268 :     sal_uLong n = SVBT32ToUInt32( *(SVBT32*)p );
     872       16268 :     p += 4;
     873       16268 :     return n;
     874             : }
     875             : 
     876       16194 : inline long Get_Long( sal_uInt8 *& p )
     877             : {
     878       16194 :     return Get_ULong(p);
     879             : }
     880             : 
     881       57166 : WW8SprmIter::WW8SprmIter(const sal_uInt8* pSprms_, long nLen_,
     882             :     const wwSprmParser &rParser)
     883       57166 :     :  mrSprmParser(rParser), pSprms( pSprms_), nRemLen( nLen_)
     884             : {
     885       57166 :     UpdateMyMembers();
     886       57166 : }
     887             : 
     888         338 : void WW8SprmIter::SetSprms(const sal_uInt8* pSprms_, long nLen_)
     889             : {
     890         338 :     pSprms = pSprms_;
     891         338 :     nRemLen = nLen_;
     892         338 :     UpdateMyMembers();
     893         338 : }
     894             : 
     895      312754 : void WW8SprmIter::advance()
     896             : {
     897      312754 :     if (nRemLen > 0 )
     898             :     {
     899      312754 :         sal_uInt16 nSize = nAktSize;
     900      312754 :         if (nSize > nRemLen)
     901           0 :             nSize = nRemLen;
     902      312754 :         pSprms += nSize;
     903      312754 :         nRemLen -= nSize;
     904      312754 :         UpdateMyMembers();
     905             :     }
     906      312754 : }
     907             : 
     908      370258 : void WW8SprmIter::UpdateMyMembers()
     909             : {
     910      370258 :     bool bValid = (pSprms && nRemLen >= mrSprmParser.MinSprmLen());
     911             : 
     912      370258 :     if (bValid)
     913             :     {
     914      327818 :         nAktId = mrSprmParser.GetSprmId(pSprms);
     915      327818 :         nAktSize = mrSprmParser.GetSprmSize(nAktId, pSprms);
     916      327818 :         pAktParams = pSprms + mrSprmParser.DistanceToData(nAktId);
     917      327818 :         bValid = nAktSize <= nRemLen;
     918             :         SAL_WARN_IF(!bValid, "sw.ww8", "sprm longer than remaining bytes, doc or parser is wrong");
     919             :     }
     920             : 
     921      370258 :     if (!bValid)
     922             :     {
     923       42488 :         nAktId = 0;
     924       42488 :         pAktParams = 0;
     925       42488 :         nAktSize = 0;
     926       42488 :         nRemLen = 0;
     927             :     }
     928      370258 : }
     929             : 
     930       52866 : const sal_uInt8* WW8SprmIter::FindSprm(sal_uInt16 nId)
     931             : {
     932      394530 :     while (GetSprms())
     933             :     {
     934      303814 :         if (GetAktId() == nId)
     935       15016 :             return GetAktParams();              // SPRM found!
     936      288798 :         advance();
     937             :     }
     938             : 
     939       37850 :     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         216 : WW8PLCFx_PCDAttrs::WW8PLCFx_PCDAttrs(ww::WordVersion eVersion,
     950             :     WW8PLCFx_PCD* pPLCFx_PCD, const WW8ScannerBase* pBase)
     951         216 :     : WW8PLCFx(eVersion, true), pPcdI(pPLCFx_PCD->GetPLCFIter()),
     952             :     pPcd(pPLCFx_PCD), pGrpprls(pBase->pPieceGrpprls),
     953         432 :     nGrpprls(pBase->nPieceGrpprls)
     954             : {
     955         216 : }
     956             : 
     957         122 : sal_uLong WW8PLCFx_PCDAttrs::GetIdx() const
     958             : {
     959         122 :     return 0;
     960             : }
     961             : 
     962         122 : void WW8PLCFx_PCDAttrs::SetIdx( sal_uLong )
     963             : {
     964         122 : }
     965             : 
     966         244 : bool WW8PLCFx_PCDAttrs::SeekPos(WW8_CP )
     967             : {
     968         244 :     return true;
     969             : }
     970             : 
     971        7242 : void WW8PLCFx_PCDAttrs::advance()
     972             : {
     973        7242 : }
     974             : 
     975           0 : WW8_CP WW8PLCFx_PCDAttrs::Where()
     976             : {
     977           0 :     return ( pPcd ) ? pPcd->Where() : WW8_CP_MAX;
     978             : }
     979             : 
     980       49184 : void WW8PLCFx_PCDAttrs::GetSprms(WW8PLCFxDesc* p)
     981             : {
     982             :     void* pData;
     983             : 
     984       49184 :     p->bRealLineEnd = false;
     985       49184 :     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       49184 :     sal_uInt16 nPrm = SVBT16ToShort( ( (WW8_PCD*)pData )->prm );
     995       49184 :     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       49184 :         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       49184 :             p->pMemPos = 0;
    1033       49184 :             p->nSprmsLen = 0;
    1034       49184 :             sal_uInt8 nSprmListIdx = (sal_uInt8)((nPrm & 0xfe) >> 1);
    1035       49184 :             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         216 : WW8PLCFx_PCD::WW8PLCFx_PCD(ww::WordVersion eVersion, WW8PLCFpcd* pPLCFpcd,
    1138             :     WW8_CP nStartCp, bool bVer67P)
    1139         216 :     : WW8PLCFx(eVersion, false), nClipStart(-1)
    1140             : {
    1141             :     // eigenen Iterator konstruieren
    1142         216 :     pPcdI = new WW8PLCFpcd_Iter(*pPLCFpcd, nStartCp);
    1143         216 :     bVer67= bVer67P;
    1144         216 : }
    1145             : 
    1146         648 : WW8PLCFx_PCD::~WW8PLCFx_PCD()
    1147             : {
    1148             :     // pPcd-Dtor which in called from WW8ScannerBase
    1149         216 :     delete pPcdI;
    1150         432 : }
    1151             : 
    1152           0 : sal_uLong WW8PLCFx_PCD::GetIMax() const
    1153             : {
    1154           0 :     return pPcdI ? pPcdI->GetIMax() : 0;
    1155             : }
    1156             : 
    1157        1898 : sal_uLong WW8PLCFx_PCD::GetIdx() const
    1158             : {
    1159        1898 :     return pPcdI ? pPcdI->GetIdx() : 0;
    1160             : }
    1161             : 
    1162        1898 : void WW8PLCFx_PCD::SetIdx( sal_uLong nIdx )
    1163             : {
    1164        1898 :     if (pPcdI)
    1165        1898 :         pPcdI->SetIdx( nIdx );
    1166        1898 : }
    1167             : 
    1168       21040 : bool WW8PLCFx_PCD::SeekPos(WW8_CP nCpPos)
    1169             : {
    1170       21040 :     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        7508 : long WW8PLCFx_PCD::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
    1179             : {
    1180             :     void* pData;
    1181        7508 :     rLen = 0;
    1182             : 
    1183        7508 :     if ( !pPcdI || !pPcdI->Get(rStart, rEnd, pData) )
    1184             :     {
    1185           0 :         rStart = rEnd = WW8_CP_MAX;
    1186           0 :         return -1;
    1187             :     }
    1188        7508 :     return pPcdI->GetIdx();
    1189             : }
    1190             : 
    1191           8 : void WW8PLCFx_PCD::advance()
    1192             : {
    1193             :     OSL_ENSURE(pPcdI , "pPcdI fehlt");
    1194           8 :     if (pPcdI)
    1195           8 :         pPcdI->advance();
    1196           8 : }
    1197             : 
    1198       20776 : WW8_FC WW8PLCFx_PCD::AktPieceStartCp2Fc( WW8_CP nCp )
    1199             : {
    1200             :     WW8_CP nCpStart, nCpEnd;
    1201             :     void* pData;
    1202             : 
    1203       20776 :     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       20776 :     if( nCp < nCpStart )
    1213           0 :         nCp = nCpStart;
    1214       20776 :     if( nCp >= nCpEnd )
    1215           0 :         nCp = nCpEnd - 1;
    1216             : 
    1217       20776 :     bool bIsUnicode = false;
    1218       20776 :     WW8_FC nFC = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
    1219       20776 :     if( !bVer67 )
    1220       20776 :         nFC = WW8PLCFx_PCD::TransformPieceAddress( nFC, bIsUnicode );
    1221             : 
    1222       20776 :     return nFC + (nCp - nCpStart) * (bIsUnicode ? 2 : 1);
    1223             : }
    1224             : 
    1225             : 
    1226         344 : void WW8PLCFx_PCD::AktPieceFc2Cp( WW8_CP& rStartPos, WW8_CP& rEndPos,
    1227             :     const WW8ScannerBase *pSBase )
    1228             : {
    1229             :     //No point going anywhere with this
    1230         344 :     if ((rStartPos == WW8_CP_MAX) && (rEndPos == WW8_CP_MAX))
    1231         344 :         return;
    1232             : 
    1233         344 :     rStartPos = pSBase->WW8Fc2Cp( rStartPos );
    1234         344 :     rEndPos = pSBase->WW8Fc2Cp( rEndPos );
    1235             : }
    1236             : 
    1237        8782 : WW8_CP WW8PLCFx_PCD::AktPieceStartFc2Cp( WW8_FC nStartPos )
    1238             : {
    1239             :     WW8_CP nCpStart, nCpEnd;
    1240             :     void* pData;
    1241        8782 :     if ( !pPcdI->Get( nCpStart, nCpEnd, pData ) )
    1242             :     {
    1243             :         OSL_ENSURE( !this, "AktPieceStartFc2Cp() - Fehler" );
    1244           0 :         return WW8_CP_MAX;
    1245             :     }
    1246        8782 :     bool bIsUnicode = false;
    1247        8782 :     sal_Int32 nFcStart  = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
    1248        8782 :     if( !bVer67 )
    1249        8782 :         nFcStart = WW8PLCFx_PCD::TransformPieceAddress( nFcStart, bIsUnicode );
    1250             : 
    1251        8782 :     sal_Int32 nUnicodeFactor = bIsUnicode ? 2 : 1;
    1252             : 
    1253        8782 :     if( nStartPos < nFcStart )
    1254          94 :         nStartPos = nFcStart;
    1255             : 
    1256        8782 :     if( nStartPos >= nFcStart + (nCpEnd - nCpStart)     * nUnicodeFactor )
    1257           0 :         nStartPos  = nFcStart + (nCpEnd - nCpStart - 1) * nUnicodeFactor;
    1258             : 
    1259        8782 :     return nCpStart + (nStartPos - nFcStart) / nUnicodeFactor;
    1260             : }
    1261             : 
    1262             : //-----------------------------------------
    1263             : //      Hilfsroutinen fuer alle
    1264             : //-----------------------------------------
    1265             : 
    1266        4346 : 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        4346 :     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        4346 :         nIdx = aBits1[1];
    1297        4346 :         nCol = aBits2[0];   // aBor.ico
    1298        4346 :         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        4346 :         nMSTotalWidth  = aBits1[ 0 ] * 20 / 8;
    1302             : 
    1303             :         //Figure out the real size of the border according to word
    1304        4346 :         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        4346 :                 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        4346 :     if (pIdx)
    1354        3686 :         *pIdx = nIdx;
    1355        4346 :     if (pSpace)
    1356        3686 :         *pSpace = nSpace*20;
    1357        4346 :     if (pCol)
    1358        3686 :         *pCol = nCol;
    1359        4346 :     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        1816 : WW8_CP WW8ScannerBase::WW8Fc2Cp( WW8_FC nFcPos ) const
    1369             : {
    1370        1816 :     WW8_CP nFallBackCpEnd = WW8_CP_MAX;
    1371        1816 :     if( nFcPos == WW8_FC_MAX )
    1372           0 :         return nFallBackCpEnd;
    1373             : 
    1374             :     bool bIsUnicode;
    1375        1816 :     if (pWw8Fib->nVersion >= 8)
    1376        1816 :         bIsUnicode = false;
    1377             :     else
    1378           0 :         bIsUnicode = pWw8Fib->fExtChar ? true : false;
    1379             : 
    1380        1816 :     if( pPieceIter )    // Complex File ?
    1381             :     {
    1382         688 :         sal_uLong nOldPos = pPieceIter->GetIdx();
    1383             : 
    1384        3252 :         for (pPieceIter->SetIdx(0);
    1385        1876 :             pPieceIter->GetIdx() < pPieceIter->GetIMax(); pPieceIter->advance())
    1386             :         {
    1387             :             WW8_CP nCpStart, nCpEnd;
    1388             :             void* pData;
    1389        2564 :             if( !pPieceIter->Get( nCpStart, nCpEnd, pData ) )
    1390             :             {   // ausserhalb PLCFfpcd ?
    1391             :                 OSL_ENSURE( !this, "PLCFpcd-WW8Fc2Cp() ging schief" );
    1392             :                 break;
    1393             :             }
    1394        2564 :             sal_Int32 nFcStart  = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
    1395        2564 :             if (pWw8Fib->nVersion >= 8)
    1396             :             {
    1397             :                 nFcStart = WW8PLCFx_PCD::TransformPieceAddress( nFcStart,
    1398        2564 :                                                                 bIsUnicode );
    1399             :             }
    1400             :             else
    1401             :             {
    1402           0 :                 bIsUnicode = pWw8Fib->fExtChar ? true : false;
    1403             :             }
    1404        2564 :             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        2564 :             if (nFcPos >= nFcStart)
    1411             :             {
    1412             :                 // found
    1413             :                 WW8_CP nTempCp =
    1414        2564 :                     nCpStart + ((nFcPos - nFcStart) / (bIsUnicode ? 2 : 1));
    1415        2564 :                 if (nFcPos < nFcStart + nLen)
    1416             :                 {
    1417         688 :                     pPieceIter->SetIdx( nOldPos );
    1418         688 :                     return nTempCp;
    1419             :                 }
    1420        1876 :                 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        1128 :     if (!bIsUnicode)
    1440        1128 :         nFallBackCpEnd = (nFcPos - pWw8Fib->fcMin);
    1441             :     else
    1442           0 :         nFallBackCpEnd = (nFcPos - pWw8Fib->fcMin + 1) / 2;
    1443             : 
    1444        1128 :     return nFallBackCpEnd;
    1445             : }
    1446             : 
    1447      139830 : WW8_FC WW8ScannerBase::WW8Cp2Fc(WW8_CP nCpPos, bool* pIsUnicode,
    1448             :     WW8_CP* pNextPieceCp, bool* pTestFlag) const
    1449             : {
    1450      139830 :     if( pTestFlag )
    1451         148 :         *pTestFlag = true;
    1452      139830 :     if( WW8_CP_MAX == nCpPos )
    1453           0 :         return WW8_CP_MAX;
    1454             : 
    1455             :     bool bIsUnicode;
    1456      139830 :     if( !pIsUnicode )
    1457         712 :         pIsUnicode = &bIsUnicode;
    1458             : 
    1459      139830 :     if (pWw8Fib->nVersion >= 8)
    1460      139830 :         *pIsUnicode = false;
    1461             :     else
    1462           0 :         *pIsUnicode = pWw8Fib->fExtChar ? true : false;
    1463             : 
    1464      139830 :     if( pPieceIter )
    1465             :     {
    1466             :         // Complex File
    1467      133350 :         if( pNextPieceCp )
    1468         144 :             *pNextPieceCp = WW8_CP_MAX;
    1469             : 
    1470      133350 :         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      133350 :         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      133350 :         if( pNextPieceCp )
    1491         144 :             *pNextPieceCp = nCpEnd;
    1492             : 
    1493      133350 :         WW8_FC nRet = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
    1494      133350 :         if (pWw8Fib->nVersion >= 8)
    1495      133350 :             nRet = WW8PLCFx_PCD::TransformPieceAddress( nRet, *pIsUnicode );
    1496             :         else
    1497           0 :             *pIsUnicode = pWw8Fib->fExtChar ? true : false;
    1498             : 
    1499      133350 :         nRet += (nCpPos - nCpStart) * (*pIsUnicode ? 2 : 1);
    1500             : 
    1501      133350 :         return nRet;
    1502             :     }
    1503             : 
    1504             :     // No complex file
    1505        6480 :     return pWw8Fib->fcMin + nCpPos * (*pIsUnicode ? 2 : 1);
    1506             : }
    1507             : 
    1508             : //-----------------------------------------
    1509             : //      class WW8ScannerBase
    1510             : //-----------------------------------------
    1511             : 
    1512          74 : WW8PLCFpcd* WW8ScannerBase::OpenPieceTable( SvStream* pStr, const WW8Fib* pWwF )
    1513             : {
    1514          74 :     if ( ((8 > pWw8Fib->nVersion) && !pWwF->fComplex) || !pWwF->lcbClx )
    1515           0 :         return NULL;
    1516             : 
    1517          74 :     WW8_FC nClxPos = pWwF->fcClx;
    1518          74 :     sal_Int32 nClxLen = pWwF->lcbClx;
    1519          74 :     sal_Int32 nLeft = nClxLen;
    1520          74 :     sal_Int16 nGrpprl = 0;
    1521             : 
    1522          74 :     if (!checkSeek(*pStr, nClxPos))
    1523           0 :         return NULL;
    1524             : 
    1525           2 :     while( 1 ) // Zaehle Zahl der Grpprls
    1526             :     {
    1527          76 :         sal_uInt8 clxt(2);
    1528          76 :         *pStr >> clxt;
    1529          76 :         nLeft--;
    1530          76 :         if( 2 == clxt )                         // PLCFfpcd ?
    1531             :             break;                              // PLCFfpcd gefunden
    1532           4 :         if( 1 == clxt )                         // clxtGrpprl ?
    1533           0 :             nGrpprl++;
    1534           4 :         sal_uInt16 nLen(0);
    1535           4 :         *pStr >> nLen;
    1536           4 :         nLeft -= 2 + nLen;
    1537           4 :         if( nLeft < 0 )
    1538           2 :             return NULL;                        // schiefgegangen
    1539           2 :         pStr->SeekRel( nLen );                  // ueberlies grpprl
    1540             :     }
    1541             : 
    1542          72 :     if (!checkSeek(*pStr, nClxPos))
    1543           0 :         return NULL;
    1544             : 
    1545          72 :     nLeft = nClxLen;
    1546          72 :     pPieceGrpprls = new sal_uInt8*[nGrpprl + 1];
    1547          72 :     memset( pPieceGrpprls, 0, ( nGrpprl + 1 ) * sizeof(sal_uInt8 *) );
    1548          72 :     nPieceGrpprls = nGrpprl;
    1549          72 :     sal_Int16 nAktGrpprl = 0;                       // lies Grpprls ein
    1550           0 :     while( 1 )
    1551             :     {
    1552          72 :         sal_uInt8 clxt(2);
    1553          72 :         *pStr >> clxt;
    1554          72 :         nLeft--;
    1555          72 :         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          72 :     sal_Int32 nPLCFfLen(0);
    1578          72 :     if (pWwF->GetFIBVersion() <= ww::eWW2)
    1579             :     {
    1580           0 :         sal_Int16 nWordTwoLen(0);
    1581           0 :         *pStr >> nWordTwoLen;
    1582           0 :         nPLCFfLen = nWordTwoLen;
    1583             :     }
    1584             :     else
    1585          72 :         *pStr >> nPLCFfLen;
    1586             :     OSL_ENSURE( 65536 > nPLCFfLen, "PLCFfpcd ueber 64 k" );
    1587          72 :     return new WW8PLCFpcd( pStr, pStr->Tell(), nPLCFfLen, 8 );
    1588             : }
    1589             : 
    1590          74 : void WW8ScannerBase::DeletePieceTable()
    1591             : {
    1592          74 :     if( pPieceGrpprls )
    1593             :     {
    1594          72 :         for( sal_uInt8** p = pPieceGrpprls; *p; p++ )
    1595           0 :             delete[] (*p);
    1596          72 :         delete[] pPieceGrpprls;
    1597          72 :         pPieceGrpprls = 0;
    1598             :     }
    1599          74 : }
    1600             : 
    1601          74 : 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          74 :     pSubdocs(0), pExtendedAtrds(0), pPieceGrpprls(0)
    1606             : {
    1607          74 :     pPiecePLCF = OpenPieceTable( pTblSt, pWw8Fib );             // Complex
    1608          74 :     if( pPiecePLCF )
    1609             :     {
    1610          72 :         pPieceIter = new WW8PLCFpcd_Iter( *pPiecePLCF );
    1611             :         pPLCFx_PCD = new WW8PLCFx_PCD(pWwFib->GetFIBVersion(), pPiecePLCF, 0,
    1612          72 :             IsSevenMinus(pWw8Fib->GetFIBVersion()));
    1613             :         pPLCFx_PCDAttrs = new WW8PLCFx_PCDAttrs(pWwFib->GetFIBVersion(),
    1614          72 :             pPLCFx_PCD, this);
    1615             :     }
    1616             :     else
    1617             :     {
    1618           2 :         pPieceIter = 0;
    1619           2 :         pPLCFx_PCD = 0;
    1620           2 :         pPLCFx_PCDAttrs = 0;
    1621             :     }
    1622             : 
    1623             :     // pChpPLCF and pPapPLCF may NOT be created before pPLCFx_PCD !!
    1624          74 :     pChpPLCF = new WW8PLCFx_Cp_FKP( pSt, pTblSt, pDataSt, *this, CHP ); // CHPX
    1625          74 :     pPapPLCF = new WW8PLCFx_Cp_FKP( pSt, pTblSt, pDataSt, *this, PAP ); // PAPX
    1626             : 
    1627          74 :     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          74 :         pWwFib->lcbPlcffndTxt, 2 );
    1633             :     // Endnotes
    1634             :     pEdnPLCF = new WW8PLCFx_SubDoc( pTblSt, pWwFib->GetFIBVersion(), 0,
    1635             :         pWwFib->fcPlcfendRef, pWwFib->lcbPlcfendRef, pWwFib->fcPlcfendTxt,
    1636          74 :         pWwFib->lcbPlcfendTxt, 2 );
    1637             :     // Anmerkungen
    1638             :     pAndPLCF = new WW8PLCFx_SubDoc( pTblSt, pWwFib->GetFIBVersion(), 0,
    1639             :         pWwFib->fcPlcfandRef, pWwFib->lcbPlcfandRef, pWwFib->fcPlcfandTxt,
    1640          74 :         pWwFib->lcbPlcfandTxt, IsSevenMinus(pWwFib->GetFIBVersion()) ? 20 : 30);
    1641             : 
    1642             :     // Fields Main Text
    1643          74 :     pFldPLCF    = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_MAINTEXT);
    1644             :     // Fields Header / Footer
    1645          74 :     pFldHdFtPLCF= new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_HDFT);
    1646             :     // Fields Footnote
    1647          74 :     pFldFtnPLCF = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_FTN);
    1648             :     // Fields Endnote
    1649          74 :     pFldEdnPLCF = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_EDN);
    1650             :     // Fields Anmerkungen
    1651          74 :     pFldAndPLCF = new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_AND);
    1652             :     // Fields in Textboxes in Main Text
    1653          74 :     pFldTxbxPLCF= new WW8PLCFx_FLD(pTblSt, *pWwFib, MAN_TXBX);
    1654             :     // Fields in Textboxes in Header / Footer
    1655          74 :     pFldTxbxHdFtPLCF = new WW8PLCFx_FLD(pTblSt,*pWwFib,MAN_TXBX_HDFT);
    1656             : 
    1657             :     // Note: 6 stands for "6 OR 7",  7 stands for "ONLY 7"
    1658          74 :     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          74 :             if( pWwFib->fcPlcfspaMom && pWwFib->lcbPlcfspaMom )
    1675             :             {
    1676             :                 pMainFdoa = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfspaMom,
    1677          28 :                     pWwFib->lcbPlcfspaMom, 26 );
    1678             :             }
    1679          74 :             if( pWwFib->fcPlcfspaHdr && pWwFib->lcbPlcfspaHdr )
    1680             :             {
    1681             :                 pHdFtFdoa = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfspaHdr,
    1682           6 :                     pWwFib->lcbPlcfspaHdr, 26 );
    1683             :             }
    1684             :             // PLCF fuer TextBox-Break-Deskriptoren im Maintext
    1685          74 :             if( pWwFib->fcPlcftxbxBkd && pWwFib->lcbPlcftxbxBkd )
    1686             :             {
    1687             :                 pMainTxbxBkd = new WW8PLCFspecial( pTblSt,
    1688          20 :                     pWwFib->fcPlcftxbxBkd, pWwFib->lcbPlcftxbxBkd, 0);
    1689             :             }
    1690             :             // PLCF fuer TextBox-Break-Deskriptoren im Header-/Footer-Bereich
    1691          74 :             if( pWwFib->fcPlcfHdrtxbxBkd && pWwFib->lcbPlcfHdrtxbxBkd )
    1692             :             {
    1693             :                 pHdFtTxbxBkd = new WW8PLCFspecial( pTblSt,
    1694           2 :                     pWwFib->fcPlcfHdrtxbxBkd, pWwFib->lcbPlcfHdrtxbxBkd, 0);
    1695             :             }
    1696             :             // Sub table cp positions
    1697          74 :             if (pWwFib->fcPlcfTch && pWwFib->lcbPlcfTch)
    1698             :             {
    1699             :                 pMagicTables = new WW8PLCFspecial( pTblSt,
    1700          50 :                     pWwFib->fcPlcfTch, pWwFib->lcbPlcfTch, 4);
    1701             :             }
    1702             :             // Sub document cp positions
    1703          74 :             if (pWwFib->fcPlcfwkb && pWwFib->lcbPlcfwkb)
    1704             :             {
    1705             :                 pSubdocs = new WW8PLCFspecial( pTblSt,
    1706           2 :                     pWwFib->fcPlcfwkb, pWwFib->lcbPlcfwkb, 12);
    1707             :             }
    1708             :             // Extended ATRD
    1709          74 :             if (pWwFib->fcAtrdExtra && pWwFib->lcbAtrdExtra)
    1710             :             {
    1711           2 :                 sal_Size nOldPos = pTblSt->Tell();
    1712           2 :                 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           2 :                     pWwFib->lcbAtrdExtra = 0;
    1719           2 :                 pTblSt->Seek(nOldPos);
    1720             :             }
    1721             : 
    1722          74 :             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          74 :     sal_uInt32 nLenTxBxS = (8 > pWw8Fib->nVersion) ? 0 : 22;
    1730          74 :     if( pWwFib->fcPlcftxbxTxt && pWwFib->lcbPlcftxbxTxt )
    1731             :     {
    1732             :         pMainTxbx = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcftxbxTxt,
    1733          20 :             pWwFib->lcbPlcftxbxTxt, nLenTxBxS );
    1734             :     }
    1735             : 
    1736             :     // PLCF fuer TextBox-Stories im Header-/Footer-Bereich
    1737          74 :     if( pWwFib->fcPlcfHdrtxbxTxt && pWwFib->lcbPlcfHdrtxbxTxt )
    1738             :     {
    1739             :         pHdFtTxbx = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfHdrtxbxTxt,
    1740           2 :             pWwFib->lcbPlcfHdrtxbxTxt, nLenTxBxS );
    1741             :     }
    1742             : 
    1743          74 :     pBook = new WW8PLCFx_Book(pTblSt, *pWwFib);
    1744          74 : }
    1745             : 
    1746          74 : WW8ScannerBase::~WW8ScannerBase()
    1747             : {
    1748          74 :     DeletePieceTable();
    1749          74 :     delete pPLCFx_PCDAttrs;
    1750          74 :     delete pPLCFx_PCD;
    1751          74 :     delete pPieceIter;
    1752          74 :     delete pPiecePLCF;
    1753          74 :     delete pBook;
    1754          74 :     delete pFldEdnPLCF;
    1755          74 :     delete pFldFtnPLCF;
    1756          74 :     delete pFldAndPLCF;
    1757          74 :     delete pFldHdFtPLCF;
    1758          74 :     delete pFldPLCF;
    1759          74 :     delete pFldTxbxPLCF;
    1760          74 :     delete pFldTxbxHdFtPLCF;
    1761          74 :     delete pEdnPLCF;
    1762          74 :     delete pFtnPLCF;
    1763          74 :     delete pAndPLCF;
    1764          74 :     delete pSepPLCF;
    1765          74 :     delete pPapPLCF;
    1766          74 :     delete pChpPLCF;
    1767             :     // vergessene Schaeflein
    1768          74 :     delete pMainFdoa;
    1769          74 :     delete pHdFtFdoa;
    1770          74 :     delete pMainTxbx;
    1771          74 :     delete pMainTxbxBkd;
    1772          74 :     delete pHdFtTxbx;
    1773          74 :     delete pHdFtTxbxBkd;
    1774          74 :     delete pMagicTables;
    1775          74 :     delete pSubdocs;
    1776          74 :     delete [] pExtendedAtrds;
    1777          74 : }
    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          30 : static bool WW8GetFieldPara(WW8PLCFspecial& rPLCF, WW8FieldDesc& rF)
    1830             : {
    1831             :     void* pData;
    1832          30 :     sal_uLong nOldIdx = rPLCF.GetIdx();
    1833             : 
    1834          30 :     rF.nLen = rF.nId = rF.nOpt = rF.bCodeNest = rF.bResNest = 0;
    1835             : 
    1836          30 :     if( !rPLCF.Get( rF.nSCode, pData ) )             // Ende des PLCFspecial ?
    1837           0 :         goto Err;
    1838             : 
    1839          30 :     rPLCF.advance();
    1840             : 
    1841          30 :     if((((sal_uInt8*)pData)[0] & 0x1f ) != 0x13 )        // Kein Anfang ?
    1842           0 :         goto Err;
    1843             : 
    1844          30 :     rF.nId = ((sal_uInt8*)pData)[1];
    1845             : 
    1846          30 :     if( !rPLCF.Get( rF.nLCode, pData ) )
    1847           0 :         goto Err;
    1848             : 
    1849          30 :     rF.nSRes = rF.nLCode;                           // Default
    1850          30 :     rF.nSCode++;                                    // ohne Marken
    1851          30 :     rF.nLCode -= rF.nSCode;                         // Pos zu Laenge
    1852             : 
    1853          60 :     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          30 :     if ((((sal_uInt8*)pData)[0] & 0x1f ) == 0x14 )       // Field Separator ?
    1863             :     {
    1864          30 :         rPLCF.advance();
    1865             : 
    1866          30 :         if( !rPLCF.Get( rF.nLRes, pData ) )
    1867           0 :             goto Err;
    1868             : 
    1869          60 :         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          30 :         rF.nLen = rF.nLRes - rF.nSCode + 2; // nLRes ist noch die Endposition
    1878          30 :         rF.nLRes -= rF.nSRes;                       // nun: nLRes = Laenge
    1879          30 :         rF.nSRes++;                                 // Endpos encl. Marken
    1880          30 :         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          30 :     rPLCF.advance();
    1888          30 :     if((((sal_uInt8*)pData)[0] & 0x1f ) == 0x15 )
    1889             :     {
    1890             :         // Field Ende ?
    1891             :         // INDEX-Fld hat Bit7 gesetzt!?!
    1892          30 :         rF.nOpt = ((sal_uInt8*)pData)[1];                // Ja -> Flags uebernehmen
    1893             :     }else{
    1894           0 :         rF.nId = 0;                                 // Nein -> Feld ungueltig
    1895             :     }
    1896             : 
    1897          30 :     rPLCF.SetIdx( nOldIdx );
    1898          30 :     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         804 : String read_uInt16_BeltAndBracesString(SvStream& rStrm)
    1912             : {
    1913         804 :     String aRet = read_uInt16_PascalString(rStrm);
    1914         804 :     rStrm.SeekRel(sizeof(sal_Unicode)); // skip null-byte at end
    1915         804 :     return aRet;
    1916             : }
    1917             : 
    1918         148 : 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         148 :     rStr.Erase();
    1923             : 
    1924         148 :     long nTotalRead = 0;
    1925         148 :     WW8_CP nBehindTextCp = nAktStartCp + nTotalLen;
    1926         148 :     WW8_CP nNextPieceCp  = nBehindTextCp; // Initialisierung wichtig fuer Ver6
    1927         148 :     do
    1928             :     {
    1929             :         bool bIsUnicode, bPosOk;
    1930         148 :         WW8_FC fcAct = WW8Cp2Fc(nAktStartCp,&bIsUnicode,&nNextPieceCp,&bPosOk);
    1931             : 
    1932             :         // vermutlich uebers Dateiende hinaus gezielt, macht nix!
    1933         148 :         if( !bPosOk )
    1934             :             break;
    1935             : 
    1936         148 :         rStrm.Seek( fcAct );
    1937             : 
    1938             :         long nLen = ( (nNextPieceCp < nBehindTextCp) ? nNextPieceCp
    1939         148 :             : nBehindTextCp ) - nAktStartCp;
    1940             : 
    1941         148 :         if( 0 >= nLen )
    1942             :             break;
    1943             : 
    1944         148 :         if( nLen > USHRT_MAX - 1 )
    1945           0 :             nLen = USHRT_MAX - 1;
    1946             : 
    1947         148 :         if( bIsUnicode )
    1948          34 :             rStr.Append(String(read_uInt16s_ToOUString(rStrm, nLen)));
    1949             :         else
    1950         114 :             rStr.Append(String(read_uInt8s_ToOUString(rStrm, nLen, eEnc)));
    1951         148 :         nTotalRead  += nLen;
    1952         148 :         nAktStartCp += nLen;
    1953         148 :         if ( nTotalRead != rStr.Len() )
    1954             :             break;
    1955             :     }
    1956             :     while( nTotalRead < nTotalLen );
    1957             : 
    1958         148 :     return rStr.Len();
    1959             : }
    1960             : 
    1961             : //-----------------------------------------
    1962             : //              WW8PLCFspecial
    1963             : //-----------------------------------------
    1964             : 
    1965         164 : WW8PLCFspecial::WW8PLCFspecial(SvStream* pSt, sal_uInt32 nFilePos,
    1966             :     sal_uInt32 nPLCF, sal_uInt32 nStruct)
    1967         164 :     : nIdx(0), nStru(nStruct)
    1968             : {
    1969         164 :     const sal_uInt32 nValidMin=4;
    1970             : 
    1971         164 :     sal_Size nOldPos = pSt->Tell();
    1972             : 
    1973         164 :     bool bValid = checkSeek(*pSt, nFilePos);
    1974         164 :     sal_Size nRemainingSize = pSt->remainingSize();
    1975         164 :     if( !(nRemainingSize >= nValidMin && nPLCF >= nValidMin ))
    1976           0 :         bValid = false;
    1977         164 :     nPLCF = bValid ? std::min(nRemainingSize, static_cast<sal_Size>(nPLCF)) : nValidMin;
    1978             : 
    1979             :     // Pointer auf Pos- u. Struct-Array
    1980         164 :     pPLCF_PosArray = new sal_Int32[ ( nPLCF + 3 ) / 4 ];
    1981         164 :     pPLCF_PosArray[0] = 0;
    1982             : 
    1983         164 :     nPLCF = bValid ? pSt->Read(pPLCF_PosArray, nPLCF) : nValidMin;
    1984             : 
    1985         164 :     nPLCF = std::max(nPLCF, nValidMin);
    1986             : 
    1987         164 :     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         164 :     if( nStruct ) // Pointer auf Inhalts-Array
    1994         138 :         pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
    1995             :     else
    1996          26 :         pPLCF_Contents = 0;                         // kein Inhalt
    1997             : 
    1998         164 :     pSt->Seek(nOldPos);
    1999         164 : }
    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         224 : bool WW8PLCFspecial::SeekPos(long nP)
    2006             : {
    2007         224 :     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         224 :     if( (1 > nIdx) || (nP < pPLCF_PosArray[ nIdx-1 ]) )
    2015         118 :         nIdx = 1;
    2016             : 
    2017         224 :     long nI   = nIdx ? nIdx : 1;
    2018         224 :     long nEnd = nIMax;
    2019             : 
    2020         224 :     for(int n = (1==nIdx ? 1 : 2); n; --n )
    2021             :     {
    2022        1758 :         for( ; nI <=nEnd; ++nI)
    2023             :         {                                   // Suchen mit um 1 erhoehtem Index
    2024        1758 :             if( nP < pPLCF_PosArray[nI] )
    2025             :             {                               // Position gefunden
    2026         224 :                 nIdx = nI - 1;              // nI - 1 ist der richtige Index
    2027         224 :                 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         410 : bool WW8PLCFspecial::SeekPosExact(long nP)
    2042             : {
    2043         410 :     if( nP < pPLCF_PosArray[0] )
    2044             :     {
    2045           2 :         nIdx = 0;
    2046           2 :         return false;       // Not found: nP unterhalb kleinstem Eintrag
    2047             :     }
    2048             :     // Search from beginning?
    2049         408 :     if( nP <=pPLCF_PosArray[nIdx] )
    2050         142 :         nIdx = 0;
    2051             : 
    2052         408 :     long nI   = nIdx ? nIdx-1 : 0;
    2053         408 :     long nEnd = nIMax;
    2054             : 
    2055         590 :     for(int n = (0==nIdx ? 1 : 2); n; --n )
    2056             :     {
    2057        2986 :         for( ; nI < nEnd; ++nI)
    2058             :         {
    2059        2804 :             if( nP <=pPLCF_PosArray[nI] )
    2060             :             {                           // Position gefunden
    2061         262 :                 nIdx = nI;              // nI     ist der richtige Index
    2062         262 :                 return true;            // ... und fertig
    2063             :             }
    2064             :         }
    2065         182 :         nI   = 0;
    2066         182 :         nEnd = nIdx;
    2067             :     }
    2068         146 :     nIdx = nIMax;               // Not found, groesser als alle Eintraege
    2069         146 :     return false;
    2070             : }
    2071             : 
    2072        1396 : bool WW8PLCFspecial::Get(WW8_CP& rPos, void*& rpValue) const
    2073             : {
    2074        1396 :     return GetData( nIdx, rPos, rpValue );
    2075             : }
    2076             : 
    2077        1396 : bool WW8PLCFspecial::GetData(long nInIdx, WW8_CP& rPos, void*& rpValue) const
    2078             : {
    2079        1396 :     if ( nInIdx >= nIMax )
    2080             :     {
    2081         116 :         rPos = WW8_CP_MAX;
    2082         116 :         return false;
    2083             :     }
    2084        1280 :     rPos = pPLCF_PosArray[nInIdx];
    2085        1280 :     rpValue = pPLCF_Contents ? (void*)&pPLCF_Contents[nInIdx * nStru] : 0;
    2086        1280 :     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         114 : WW8PLCF::WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
    2096         114 :     WW8_CP nStartPos) : pPLCF_PosArray(0), nIdx(0), nStru(nStruct)
    2097             : {
    2098             :     OSL_ENSURE( nPLCF, "WW8PLCF: nPLCF ist Null!" );
    2099             : 
    2100         114 :     nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
    2101             : 
    2102         114 :     ReadPLCF(rSt, nFilePos, nPLCF);
    2103             : 
    2104         114 :     if( nStartPos >= 0 )
    2105          78 :         SeekPos( nStartPos );
    2106         114 : }
    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         148 : 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         148 :     nStru(nStruct)
    2116             : {
    2117         148 :     nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
    2118             : 
    2119         148 :     if( nIMax >= ncpN )
    2120         144 :         ReadPLCF(rSt, nFilePos, nPLCF);
    2121             :     else
    2122           4 :         GeneratePLCF(rSt, nPN, ncpN);
    2123             : 
    2124         148 :     if( nStartPos >= 0 )
    2125         148 :         SeekPos( nStartPos );
    2126         148 : }
    2127             : 
    2128         258 : void WW8PLCF::ReadPLCF(SvStream& rSt, WW8_FC nFilePos, sal_uInt32 nPLCF)
    2129             : {
    2130         258 :     sal_Size nOldPos = rSt.Tell();
    2131         258 :     bool bValid = checkSeek(rSt, nFilePos) && (rSt.remainingSize() >= nPLCF);
    2132             : 
    2133         258 :     if (bValid)
    2134             :     {
    2135             :         // Pointer auf Pos-Array
    2136         258 :         pPLCF_PosArray = new WW8_CP[ ( nPLCF + 3 ) / 4 ];
    2137         258 :         bValid = checkRead(rSt, pPLCF_PosArray, nPLCF);
    2138             :     }
    2139             : 
    2140         258 :     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         258 :         pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
    2149             :     }
    2150             : 
    2151             :     OSL_ENSURE(bValid, "Document has corrupt PLCF, ignoring it");
    2152             : 
    2153         258 :     if (!bValid)
    2154           0 :         MakeFailedPLCF();
    2155             : 
    2156         258 :     rSt.Seek(nOldPos);
    2157         258 : }
    2158             : 
    2159           4 : void WW8PLCF::MakeFailedPLCF()
    2160             : {
    2161           4 :     nIMax = 0;
    2162           4 :     delete[] pPLCF_PosArray;
    2163           4 :     pPLCF_PosArray = new sal_Int32[2];
    2164           4 :     pPLCF_PosArray[0] = pPLCF_PosArray[1] = WW8_CP_MAX;
    2165           4 :     pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
    2166           4 : }
    2167             : 
    2168           4 : 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           4 :     bool failure = false;
    2173           4 :     nIMax = ncpN;
    2174             : 
    2175           4 :     if ((nIMax < 1) || (nIMax > (WW8_CP_MAX - 4)/6) || ((nPN + ncpN) > USHRT_MAX))
    2176           4 :         failure = true;
    2177             : 
    2178           4 :     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           4 :     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           4 :     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           4 :     if (failure)
    2239           4 :         MakeFailedPLCF();
    2240           4 : }
    2241             : 
    2242       21818 : bool WW8PLCF::SeekPos(WW8_CP nPos)
    2243             : {
    2244       21818 :     WW8_CP nP = nPos;
    2245             : 
    2246       21818 :     if( nP < pPLCF_PosArray[0] )
    2247             :     {
    2248          10 :         nIdx = 0;
    2249             :         // Nicht gefunden: nPos unterhalb kleinstem Eintrag
    2250          10 :         return false;
    2251             :     }
    2252             : 
    2253             :     // Search from beginning?
    2254       21808 :     if( (1 > nIdx) || (nP < pPLCF_PosArray[ nIdx-1 ]) )
    2255        4116 :         nIdx = 1;
    2256             : 
    2257       21808 :     sal_Int32 nI   = nIdx ? nIdx : 1;
    2258       21808 :     sal_Int32 nEnd = nIMax;
    2259             : 
    2260       21808 :     for(int n = (1==nIdx ? 1 : 2); n; --n )
    2261             :     {
    2262       59446 :         for( ; nI <=nEnd; ++nI)             // Suchen mit um 1 erhoehtem Index
    2263             :         {
    2264       59446 :             if( nP < pPLCF_PosArray[nI] )   // Position gefunden
    2265             :             {
    2266       21808 :                 nIdx = nI - 1;              // nI - 1 ist der richtige Index
    2267       21808 :                 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       26940 : bool WW8PLCF::Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const
    2279             : {
    2280       26940 :     if ( nIdx >= nIMax )
    2281             :     {
    2282          38 :         rStart = rEnd = WW8_CP_MAX;
    2283          38 :         return false;
    2284             :     }
    2285       26902 :     rStart = pPLCF_PosArray[ nIdx ];
    2286       26902 :     rEnd   = pPLCF_PosArray[ nIdx + 1 ];
    2287       26902 :     rpValue = (void*)&pPLCF_Contents[nIdx * nStru];
    2288       26902 :     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          72 : WW8PLCFpcd::WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos,
    2304             :     sal_uInt32 nPLCF, sal_uInt32 nStruct)
    2305          72 :     : nStru( nStruct )
    2306             : {
    2307          72 :     const sal_uInt32 nValidMin=4;
    2308             : 
    2309          72 :     sal_Size nOldPos = pSt->Tell();
    2310             : 
    2311          72 :     bool bValid = checkSeek(*pSt, nFilePos);
    2312          72 :     sal_Size nRemainingSize = pSt->remainingSize();
    2313          72 :     if( !(nRemainingSize >= nValidMin && nPLCF >= nValidMin ))
    2314           0 :         bValid = false;
    2315          72 :     nPLCF = bValid ? std::min(nRemainingSize, static_cast<sal_Size>(nPLCF)) : nValidMin;
    2316             : 
    2317          72 :     pPLCF_PosArray = new sal_Int32[ ( nPLCF + 3 ) / 4 ];    // Pointer auf Pos-Array
    2318          72 :     pPLCF_PosArray[0] = 0;
    2319             : 
    2320          72 :     nPLCF = bValid ? pSt->Read(pPLCF_PosArray, nPLCF) : nValidMin;
    2321          72 :     nPLCF = std::max(nPLCF, nValidMin);
    2322             : 
    2323          72 :     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          72 :     pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
    2331             : 
    2332          72 :     pSt->Seek( nOldPos );
    2333          72 : }
    2334             : 
    2335             : // Bei nStartPos < 0 wird das erste Element des PLCFs genommen
    2336         288 : WW8PLCFpcd_Iter::WW8PLCFpcd_Iter( WW8PLCFpcd& rPLCFpcd, long nStartPos )
    2337         288 :     :rPLCF( rPLCFpcd ), nIdx( 0 )
    2338             : {
    2339         288 :     if( nStartPos >= 0 )
    2340         216 :         SeekPos( nStartPos );
    2341         288 : }
    2342             : 
    2343      195762 : bool WW8PLCFpcd_Iter::SeekPos(long nPos)
    2344             : {
    2345      195762 :     long nP = nPos;
    2346             : 
    2347      195762 :     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      195762 :     if( (1 > nIdx) || (nP < rPLCF.pPLCF_PosArray[ nIdx-1 ]) )
    2354       82574 :         nIdx = 1;
    2355             : 
    2356      195762 :     long nI   = nIdx ? nIdx : 1;
    2357      195762 :     long nEnd = rPLCF.nIMax;
    2358             : 
    2359      195906 :     for(int n = (1==nIdx ? 1 : 2); n; --n )
    2360             :     {
    2361      309340 :         for( ; nI <=nEnd; ++nI)
    2362             :         {                               // Suchen mit um 1 erhoehtem Index
    2363      309196 :             if( nP < rPLCF.pPLCF_PosArray[nI] )
    2364             :             {                           // Position gefunden
    2365      195622 :                 nIdx = nI - 1;          // nI - 1 ist der richtige Index
    2366      195622 :                 return true;            // ... und fertig
    2367             :             }
    2368             :         }
    2369         144 :         nI   = 1;
    2370         144 :         nEnd = nIdx-1;
    2371             :     }
    2372         140 :     nIdx = rPLCF.nIMax;         // Nicht gefunden, groesser als alle Eintraege
    2373         140 :     return false;
    2374             : }
    2375             : 
    2376      242542 : bool WW8PLCFpcd_Iter::Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const
    2377             : {
    2378      242542 :     if( nIdx >= rPLCF.nIMax )
    2379             :     {
    2380           0 :         rStart = rEnd = WW8_CP_MAX;
    2381           0 :         return false;
    2382             :     }
    2383      242542 :     rStart = rPLCF.pPLCF_PosArray[nIdx];
    2384      242542 :     rEnd = rPLCF.pPLCF_PosArray[nIdx + 1];
    2385      242542 :     rpValue = (void*)&rPLCF.pPLCF_Contents[nIdx * rPLCF.nStru];
    2386      242542 :     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       42122 : bool WW8PLCFx_Fc_FKP::WW8Fkp::Entry::operator<
    2399             :     (const WW8PLCFx_Fc_FKP::WW8Fkp::Entry& rSecond) const
    2400             : {
    2401       42122 :     return (mnFC < rSecond.mnFC);
    2402             : }
    2403             : 
    2404        8244 : bool IsReplaceAllSprm(sal_uInt16 nSpId)
    2405             : {
    2406        8244 :     return (0x6645 == nSpId || 0x6646 == nSpId);
    2407             : }
    2408             : 
    2409        8244 : bool IsExpandableSprm(sal_uInt16 nSpId)
    2410             : {
    2411        8244 :     return 0x646B == nSpId;
    2412             : }
    2413             : 
    2414        9930 : void WW8PLCFx_Fc_FKP::WW8Fkp::FillEntry(WW8PLCFx_Fc_FKP::WW8Fkp::Entry &rEntry,
    2415             :     sal_Size nDataOffset, sal_uInt16 nLen)
    2416             : {
    2417        9930 :     bool bValidPos = (nDataOffset < sizeof(maRawData));
    2418             : 
    2419             :     OSL_ENSURE(bValidPos, "sprm sequence offset is out of range, ignoring");
    2420             : 
    2421        9930 :     if (!bValidPos)
    2422             :     {
    2423           0 :         rEntry.mnLen = 0;
    2424        9930 :         return;
    2425             :     }
    2426             : 
    2427        9930 :     sal_uInt16 nAvailableData = sizeof(maRawData)-nDataOffset;
    2428             :     OSL_ENSURE(nLen <= nAvailableData, "srpm sequence len is out of range, clipping");
    2429        9930 :     rEntry.mnLen = std::min(nLen, nAvailableData);
    2430        9930 :     rEntry.mpData = maRawData + nDataOffset;
    2431             : }
    2432             : 
    2433        1268 : 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        1268 :     maSprmParser(eVersion)
    2438             : {
    2439        1268 :     memset(maRawData, 0, 512);
    2440             : 
    2441        1268 :     sal_Size nOldPos = pSt->Tell();
    2442             : 
    2443        1268 :     bool bCouldSeek = checkSeek(*pSt, nFilePos);
    2444        1268 :     bool bCouldRead = bCouldSeek ? checkRead(*pSt, maRawData, 512) : false;
    2445             : 
    2446        1268 :     mnIMax = bCouldRead ? maRawData[511] : 0;
    2447             : 
    2448        1268 :     sal_uInt8 *pStart = maRawData;
    2449             :     // Offset-Location in maRawData
    2450        1268 :     const size_t nRawDataStart = (mnIMax + 1) * 4;
    2451             : 
    2452       14730 :     for (mnIdx = 0; mnIdx < mnIMax; ++mnIdx)
    2453             :     {
    2454       13462 :         const size_t nRawDataOffset = nRawDataStart + mnIdx * nItemSize;
    2455             : 
    2456             :         //clip to available data, corrupt fkp
    2457       13462 :         if (nRawDataOffset >= 511)
    2458             :         {
    2459           0 :             mnIMax = mnIdx;
    2460             :             break;
    2461             :         }
    2462             : 
    2463       13462 :         unsigned int nOfs = maRawData[nRawDataOffset] * 2;
    2464             : 
    2465             :         //clip to available data, corrupt fkp
    2466       13462 :         if (nOfs >= 511)
    2467             :         {
    2468           0 :             mnIMax = mnIdx;
    2469             :             break;
    2470             :         }
    2471             : 
    2472       13462 :         Entry aEntry(Get_Long(pStart));
    2473             : 
    2474       13462 :         if (nOfs)
    2475             :         {
    2476       13024 :             switch (ePLCF)
    2477             :             {
    2478             :                 case CHP:
    2479             :                 {
    2480        4780 :                     aEntry.mnLen = maRawData[nOfs];
    2481             : 
    2482             :                     //len byte
    2483        4780 :                     sal_Size nDataOffset = nOfs + 1;
    2484             : 
    2485        4780 :                     FillEntry(aEntry, nDataOffset, aEntry.mnLen);
    2486             : 
    2487        4780 :                     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        4780 :                     break;
    2500             :                 }
    2501             :                 case PAP:
    2502             :                     {
    2503        8244 :                         sal_uInt8 nDelta = 0;
    2504             : 
    2505        8244 :                         aEntry.mnLen = maRawData[nOfs];
    2506        8244 :                         if (IsEightPlus(eVersion) && !aEntry.mnLen)
    2507             :                         {
    2508        6578 :                             aEntry.mnLen = maRawData[nOfs+1];
    2509        6578 :                             nDelta++;
    2510             :                         }
    2511        8244 :                         aEntry.mnLen *= 2;
    2512             : 
    2513             :                         //stylecode, std/istd
    2514        8244 :                         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        8244 :                             if (aEntry.mnLen >= 2)
    2533             :                             {
    2534             :                                 //len byte + optional extra len byte
    2535        8244 :                                 sal_Size nDataOffset = nOfs + 1 + nDelta;
    2536             :                                 aEntry.mnIStd = nDataOffset <= sizeof(maRawData)-sizeof(aEntry.mnIStd) ?
    2537        8244 :                                     SVBT16ToShort(maRawData+nDataOffset) : 0;
    2538        8244 :                                 aEntry.mnLen-=2; //istd
    2539        8244 :                                 if (aEntry.mnLen)
    2540             :                                 {
    2541             :                                     //additional istd
    2542        5150 :                                     nDataOffset += sizeof(aEntry.mnIStd);
    2543             : 
    2544        5150 :                                     FillEntry(aEntry, nDataOffset, aEntry.mnLen);
    2545             :                                 }
    2546             :                             }
    2547             :                             else
    2548           0 :                                 aEntry.mnLen=0; //Too short, ignore
    2549             :                         }
    2550             : 
    2551        8244 :                         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        8244 :                         bool bExpand = IsExpandableSprm(nSpId);
    2559        8244 :                         if (IsReplaceAllSprm(nSpId) || bExpand)
    2560             :                         {
    2561         770 :                             sal_uInt32 nCurr = pDataSt->Tell();
    2562         770 :                             sal_uInt32 nPos = SVBT32ToUInt32(aEntry.mpData + 2);
    2563         770 :                             if (checkSeek(*pDataSt, nPos))
    2564             :                             {
    2565         770 :                                 sal_uInt16 nOrigLen = bExpand ? aEntry.mnLen : 0;
    2566         770 :                                 sal_uInt8 *pOrigData = bExpand ? aEntry.mpData : 0;
    2567             : 
    2568         770 :                                 *pDataSt >> aEntry.mnLen;
    2569             :                                 aEntry.mpData =
    2570         770 :                                     new sal_uInt8[aEntry.mnLen + nOrigLen];
    2571         770 :                                 aEntry.mbMustDelete = true;
    2572             :                                 aEntry.mnLen =
    2573         770 :                                     pDataSt->Read(aEntry.mpData, aEntry.mnLen);
    2574             : 
    2575         770 :                                 pDataSt->Seek( nCurr );
    2576             : 
    2577         770 :                                 if (pOrigData)
    2578             :                                 {
    2579         754 :                                     memcpy(aEntry.mpData + aEntry.mnLen,
    2580        1508 :                                         pOrigData, nOrigLen);
    2581         754 :                                     aEntry.mnLen = aEntry.mnLen + nOrigLen;
    2582             :                                 }
    2583             :                             }
    2584             :                         }
    2585             :                     }
    2586        8244 :                     break;
    2587             :                 default:
    2588             :                     OSL_FAIL("sweet god, what have you done!");
    2589           0 :                     break;
    2590             :             }
    2591             :         }
    2592             : 
    2593       13462 :         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       13462 :     }
    2609             : 
    2610             :     //one more FC than grrpl entries
    2611        1268 :     maEntries.push_back(Entry(Get_Long(pStart)));
    2612             : 
    2613             :     //we expect them sorted, but it appears possible for them to arive unsorted
    2614        1268 :     std::sort(maEntries.begin(), maEntries.end());
    2615             : 
    2616        1268 :     mnIdx = 0;
    2617             : 
    2618        1268 :     if (nStartFc >= 0)
    2619        1260 :         SeekPos(nStartFc);
    2620             : 
    2621        1268 :     pSt->Seek(nOldPos);
    2622        1268 : }
    2623             : 
    2624       46108 : WW8PLCFx_Fc_FKP::WW8Fkp::Entry::Entry(const Entry &rEntry)
    2625             :     : mnFC(rEntry.mnFC), mnLen(rEntry.mnLen), mnIStd(rEntry.mnIStd),
    2626       46108 :     mbMustDelete(rEntry.mbMustDelete)
    2627             : {
    2628       46108 :     if (mbMustDelete)
    2629             :     {
    2630        2362 :         mpData = new sal_uInt8[mnLen];
    2631        2362 :         memcpy(mpData, rEntry.mpData, mnLen);
    2632             :     }
    2633             :     else
    2634       43746 :         mpData = rEntry.mpData;
    2635       46108 : }
    2636             : 
    2637             : WW8PLCFx_Fc_FKP::WW8Fkp::Entry&
    2638       23318 :     WW8PLCFx_Fc_FKP::WW8Fkp::Entry::operator=(const Entry &rEntry)
    2639             : {
    2640       23318 :     if (this == &rEntry)
    2641           0 :         return *this;
    2642             : 
    2643       23318 :     if (mbMustDelete)
    2644         122 :         delete[] mpData;
    2645             : 
    2646       23318 :     mnFC = rEntry.mnFC;
    2647       23318 :     mnLen = rEntry.mnLen;
    2648       23318 :     mnIStd = rEntry.mnIStd;
    2649       23318 :     mbMustDelete = rEntry.mbMustDelete;
    2650             : 
    2651       23318 :     if (mbMustDelete)
    2652             :     {
    2653         122 :         mpData = new sal_uInt8[mnLen];
    2654         122 :         memcpy(mpData, rEntry.mpData, mnLen);
    2655             :     }
    2656             :     else
    2657       23196 :         mpData = rEntry.mpData;
    2658       23318 :     return *this;
    2659             : }
    2660             : 
    2661       60838 : WW8PLCFx_Fc_FKP::WW8Fkp::Entry::~Entry()
    2662             : {
    2663       60838 :     if (mbMustDelete)
    2664        3132 :         delete[] mpData;
    2665       60838 : }
    2666             : 
    2667        4294 : void WW8PLCFx_Fc_FKP::WW8Fkp::Reset(WW8_FC nFc)
    2668             : {
    2669        4294 :     SetIdx(0);
    2670        4294 :     if (nFc >= 0)
    2671        3402 :         SeekPos(nFc);
    2672        4294 : }
    2673             : 
    2674       21722 : bool WW8PLCFx_Fc_FKP::WW8Fkp::SeekPos(WW8_FC nFc)
    2675             : {
    2676       21722 :     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       21722 :     if ((1 > mnIdx) || (nFc < maEntries[mnIdx-1].mnFC))
    2684        7206 :         mnIdx = 1;
    2685             : 
    2686       21722 :     sal_uInt8 nI   = mnIdx ? mnIdx : 1;
    2687       21722 :     sal_uInt8 nEnd = mnIMax;
    2688             : 
    2689       22290 :     for(sal_uInt8 n = (1==mnIdx ? 1 : 2); n; --n )
    2690             :     {
    2691       69282 :         for( ; nI <=nEnd; ++nI)
    2692             :         {                               // Suchen mit um 1 erhoehtem Index
    2693       68714 :             if (nFc < maEntries[nI].mnFC)
    2694             :             {                           // Position gefunden
    2695       21254 :                 mnIdx = nI - 1;          // nI - 1 ist der richtige Index
    2696       21254 :                 return true;            // ... und fertig
    2697             :             }
    2698             :         }
    2699         568 :         nI = 1;
    2700         568 :         nEnd = mnIdx-1;
    2701             :     }
    2702         468 :     mnIdx = mnIMax;               // Nicht gefunden, groesser als alle Eintraege
    2703         468 :     return false;
    2704             : }
    2705             : 
    2706       21286 : sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::Get(WW8_FC& rStart, WW8_FC& rEnd, sal_Int32& rLen)
    2707             :     const
    2708             : {
    2709       21286 :     rLen = 0;
    2710             : 
    2711       21286 :     if (mnIdx >= mnIMax)
    2712             :     {
    2713         196 :         rStart = WW8_FC_MAX;
    2714         196 :         return 0;
    2715             :     }
    2716             : 
    2717       21090 :     rStart = maEntries[mnIdx].mnFC;
    2718       21090 :     rEnd   = maEntries[mnIdx + 1].mnFC;
    2719             : 
    2720       21090 :     sal_uInt8* pSprms = GetLenAndIStdAndSprms( rLen );
    2721       21090 :     return pSprms;
    2722             : }
    2723             : 
    2724        5832 : bool WW8PLCFx_Fc_FKP::WW8Fkp::SetIdx(sal_uInt8 nI)
    2725             : {
    2726        5832 :     if (nI < mnIMax)
    2727             :     {
    2728        5602 :         mnIdx = nI;
    2729        5602 :         return true;
    2730             :     }
    2731         230 :     return false;
    2732             : }
    2733             : 
    2734       71090 : sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::GetLenAndIStdAndSprms(sal_Int32& rLen) const
    2735             : {
    2736       71090 :     rLen = maEntries[mnIdx].mnLen;
    2737       71090 :     return maEntries[mnIdx].mpData;
    2738             : }
    2739             : 
    2740       50060 : const sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm( sal_uInt16 nId )
    2741             : {
    2742       50060 :     if (mnIdx >= mnIMax)
    2743          60 :         return 0;
    2744             : 
    2745             :     sal_Int32 nLen;
    2746       50000 :     sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen );
    2747             : 
    2748       50000 :     WW8SprmIter aIter(pSprms, nLen, maSprmParser);
    2749       50000 :     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         854 : sal_uLong WW8PLCFx::GetIdx2() const
    2793             : {
    2794         854 :     return 0;
    2795             : }
    2796             : 
    2797         854 : void WW8PLCFx::SetIdx2(sal_uLong )
    2798             : {
    2799         854 : }
    2800             : 
    2801             : class SamePos :
    2802             :     public std::unary_function<const WW8PLCFx_Fc_FKP::WW8Fkp *, bool>
    2803             : {
    2804             : private:
    2805             :     long mnPo;
    2806             : public:
    2807        5156 :     SamePos(long nPo) : mnPo(nPo) {}
    2808       19350 :     bool operator()(const WW8PLCFx_Fc_FKP::WW8Fkp *pFkp)
    2809       19350 :         {return mnPo == pFkp->GetFilePos();}
    2810             : };
    2811             : 
    2812             : //-----------------------------------------
    2813        5562 : 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        5562 :     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        5562 :             pFkpSizeTab = WW8FkpSizeTabVer8;
    2843        5562 :             break;
    2844             :         default:
    2845             :             // Programm-Fehler!
    2846             :             OSL_ENSURE( !this, "Es wurde vergessen, nVersion zu kodieren!" );
    2847           0 :             return false;
    2848             :     }
    2849             : 
    2850        5562 :     if (!pPLCF->Get( nPLCFStart, nPLCFEnd, pPage ))
    2851             :     {
    2852           0 :         pFkp = 0;
    2853           0 :         return false;                           // PLCF fertig abgearbeitet
    2854             :     }
    2855        5562 :     pPLCF->advance();
    2856        5562 :     long nPo = SVBT16ToShort( (sal_uInt8 *)pPage );
    2857        5562 :     nPo <<= 9;                                  // shift als LONG
    2858             : 
    2859        5562 :     long nAktFkpFilePos = pFkp ? pFkp->GetFilePos() : -1;
    2860        5562 :     if (nAktFkpFilePos == nPo)
    2861         406 :         pFkp->Reset(GetStartFc());
    2862             :     else
    2863             :     {
    2864             :         myiter aIter =
    2865        5156 :             std::find_if(maFkpCache.begin(), maFkpCache.end(), SamePos(nPo));
    2866        5156 :         if (aIter != maFkpCache.end())
    2867             :         {
    2868        3888 :             pFkp = *aIter;
    2869        3888 :             pFkp->Reset(GetStartFc());
    2870             :         }
    2871        3804 :         else if (0 != (pFkp = new WW8Fkp(GetFIBVersion(), pFKPStrm, pDataStrm, nPo,
    2872        2536 :             pFkpSizeTab[ ePLCF ], ePLCF, GetStartFc())))
    2873             :         {
    2874        1268 :             maFkpCache.push_back(pFkp);
    2875             : 
    2876        1268 :             if (maFkpCache.size() > eMaxCache)
    2877             :             {
    2878         988 :                 delete maFkpCache.front();
    2879         988 :                 maFkpCache.pop_front();
    2880             :             }
    2881             :         }
    2882             :     }
    2883             : 
    2884        5562 :     SetStartFc( -1 );                                   // Nur das erste Mal
    2885        5562 :     return true;
    2886             : }
    2887             : 
    2888         148 : 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         148 :     pFkp(0), ePLCF(ePl), pPCDAttrs(0)
    2892             : {
    2893         148 :     SetStartFc(nStartFcL);
    2894         148 :     long nLenStruct = (8 > rFib.nVersion) ? 2 : 4;
    2895         148 :     if (ePl == CHP)
    2896             :     {
    2897             :         pPLCF = new WW8PLCF(*pTblSt, rFib.fcPlcfbteChpx, rFib.lcbPlcfbteChpx,
    2898          74 :             nLenStruct, GetStartFc(), rFib.pnChpFirst, rFib.cpnBteChp);
    2899             :     }
    2900             :     else
    2901             :     {
    2902             :         pPLCF = new WW8PLCF(*pTblSt, rFib.fcPlcfbtePapx, rFib.lcbPlcfbtePapx,
    2903          74 :             nLenStruct, GetStartFc(), rFib.pnPapFirst, rFib.cpnBtePap);
    2904             :     }
    2905         148 : }
    2906             : 
    2907         296 : WW8PLCFx_Fc_FKP::~WW8PLCFx_Fc_FKP()
    2908             : {
    2909         148 :     myiter aEnd = maFkpCache.end();
    2910         428 :     for (myiter aIter = maFkpCache.begin(); aIter != aEnd; ++aIter)
    2911         280 :         delete *aIter;
    2912         148 :     delete pPLCF;
    2913         148 :     delete pPCDAttrs;
    2914         148 : }
    2915             : 
    2916        1776 : sal_uLong WW8PLCFx_Fc_FKP::GetIdx() const
    2917             : {
    2918        1776 :     sal_uLong u = pPLCF->GetIdx() << 8;
    2919        1776 :     if (pFkp)
    2920        1776 :         u |= pFkp->GetIdx();
    2921        1776 :     return u;
    2922             : }
    2923             : 
    2924        1776 : void WW8PLCFx_Fc_FKP::SetIdx( sal_uLong nIdx )
    2925             : {
    2926        1776 :     if( !( nIdx & 0xffffff00L ) )
    2927             :     {
    2928         238 :         pPLCF->SetIdx( nIdx >> 8 );
    2929         238 :         pFkp = 0;
    2930             :     }
    2931             :     else
    2932             :     {                                   //Es gab einen Fkp
    2933             :         //Lese PLCF um 1 Pos zurueck, um die Adresse des Fkp wiederzubekommen
    2934        1538 :         pPLCF->SetIdx( ( nIdx >> 8 ) - 1 );
    2935        1538 :         if (NewFkp())                       // und lese Fkp wieder ein
    2936             :         {
    2937        1538 :             sal_uInt8 nFkpIdx = static_cast<sal_uInt8>(nIdx & 0xff);
    2938        1538 :             pFkp->SetIdx(nFkpIdx);          // Dann stelle Fkp-Pos wieder ein
    2939             :         }
    2940             :     }
    2941        1776 : }
    2942             : 
    2943       21340 : bool WW8PLCFx_Fc_FKP::SeekPos(WW8_FC nFcPos)
    2944             : {
    2945             :     // StartPos for next Where()
    2946       21340 :     SetStartFc( nFcPos );
    2947             : 
    2948             :     // find StartPos for next pPLCF->Get()
    2949       21340 :     bool bRet = pPLCF->SeekPos(nFcPos);
    2950             : 
    2951             :     // make FKP invalid?
    2952             :     WW8_CP nPLCFStart, nPLCFEnd;
    2953             :     void* pPage;
    2954       21340 :     if( pFkp && pPLCF->Get( nPLCFStart, nPLCFEnd, pPage ) )
    2955             :     {
    2956       20702 :         long nPo = SVBT16ToShort( (sal_uInt8 *)pPage );
    2957       20702 :         nPo <<= 9;                                          // shift als LONG
    2958       20702 :         if (nPo != pFkp->GetFilePos())
    2959        3642 :             pFkp = 0;
    2960             :         else
    2961       17060 :             pFkp->SeekPos( nFcPos );
    2962             :     }
    2963       21340 :     return bRet;
    2964             : }
    2965             : 
    2966        8782 : WW8_FC WW8PLCFx_Fc_FKP::Where()
    2967             : {
    2968        8782 :     if( !pFkp )
    2969             :     {
    2970           0 :         if( !NewFkp() )
    2971           0 :             return WW8_FC_MAX;
    2972             :     }
    2973        8782 :     WW8_FC nP = pFkp->Where();
    2974        8782 :     if( nP != WW8_FC_MAX )
    2975        8782 :         return nP;
    2976             : 
    2977           0 :     pFkp = 0;                   // FKP beendet -> hole neuen
    2978           0 :     return Where();                     // am einfachsten rekursiv
    2979             : }
    2980             : 
    2981       21286 : sal_uInt8* WW8PLCFx_Fc_FKP::GetSprmsAndPos(WW8_FC& rStart, WW8_FC& rEnd, sal_Int32& rLen)
    2982             : {
    2983       21286 :     rLen = 0;                               // Default
    2984       21286 :     rStart = rEnd = WW8_FC_MAX;
    2985             : 
    2986       21286 :     if( !pFkp )     // Fkp not there ?
    2987             :     {
    2988        4024 :         if( !NewFkp() )
    2989           0 :             return 0;
    2990             :     }
    2991             : 
    2992       21286 :     sal_uInt8* pPos = pFkp->Get( rStart, rEnd, rLen );
    2993       21286 :     if( rStart == WW8_FC_MAX )    //Not found
    2994         196 :         return 0;
    2995       21090 :     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       10068 : sal_uInt16 WW8PLCFx_Fc_FKP::GetIstd() const
    3012             : {
    3013       10068 :     return pFkp ? pFkp->GetIstd() : 0xFFFF;
    3014             : }
    3015             : 
    3016       36336 : void WW8PLCFx_Fc_FKP::GetPCDSprms( WW8PLCFxDesc& rDesc )
    3017             : {
    3018       36336 :     rDesc.pMemPos   = 0;
    3019       36336 :     rDesc.nSprmsLen = 0;
    3020       36336 :     if( pPCDAttrs )
    3021             :     {
    3022       34190 :         if( !pFkp )
    3023             :         {
    3024             :             OSL_FAIL(
    3025             :                 "+Problem: GetPCDSprms: NewFkp necessay (not possible!)" );
    3026           0 :             if( !NewFkp() )
    3027       36336 :                 return;
    3028             :         }
    3029       34190 :         pPCDAttrs->GetSprms(&rDesc);
    3030             :     }
    3031             : }
    3032             : 
    3033       50060 : 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       50060 :     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       50060 :     const sal_uInt8* pRes = pFkp->HasSprm( nId );
    3046             : 
    3047       50060 :     if( !pRes )
    3048             :     {
    3049       35998 :         WW8PLCFxDesc aDesc;
    3050       35998 :         GetPCDSprms( aDesc );
    3051             : 
    3052       35998 :         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       50060 :     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         148 : 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         148 :     bComplex( (7 < rBase.pWw8Fib->nVersion) || (0 != rBase.pWw8Fib->fComplex) )
    3102             : {
    3103         148 :     ResetAttrStartEnd();
    3104             : 
    3105         144 :     pPcd = rSBase.pPiecePLCF ? new WW8PLCFx_PCD(GetFIBVersion(),
    3106         292 :         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         148 :     if (pPcd)
    3115             :     {
    3116             :         pPCDAttrs = rSBase.pPLCFx_PCDAttrs ? new WW8PLCFx_PCDAttrs(
    3117         144 :             rSBase.pWw8Fib->GetFIBVersion(), pPcd, &rSBase) : 0;
    3118             :     }
    3119             : 
    3120         148 :     pPieceIter = rSBase.pPieceIter;
    3121         148 : }
    3122             : 
    3123         444 : WW8PLCFx_Cp_FKP::~WW8PLCFx_Cp_FKP()
    3124             : {
    3125         148 :     delete pPcd;
    3126         296 : }
    3127             : 
    3128         684 : void WW8PLCFx_Cp_FKP::ResetAttrStartEnd()
    3129             : {
    3130         684 :     nAttrStart = -1;
    3131         684 :     nAttrEnd   = -1;
    3132         684 :     bLineEnd   = false;
    3133         684 : }
    3134             : 
    3135           0 : sal_uLong WW8PLCFx_Cp_FKP::GetPCDIMax() const
    3136             : {
    3137           0 :     return pPcd ? pPcd->GetIMax() : 0;
    3138             : }
    3139             : 
    3140        1776 : sal_uLong WW8PLCFx_Cp_FKP::GetPCDIdx() const
    3141             : {
    3142        1776 :     return pPcd ? pPcd->GetIdx() : 0;
    3143             : }
    3144             : 
    3145        1776 : void WW8PLCFx_Cp_FKP::SetPCDIdx( sal_uLong nIdx )
    3146             : {
    3147        1776 :     if( pPcd )
    3148        1776 :         pPcd->SetIdx( nIdx );
    3149        1776 : }
    3150             : 
    3151       21410 : bool WW8PLCFx_Cp_FKP::SeekPos(WW8_CP nCpPos)
    3152             : {
    3153       21410 :     if( pPcd )  // Complex
    3154             :     {
    3155       20846 :         if( !pPcd->SeekPos( nCpPos ) )  // Piece setzen
    3156          70 :             return false;
    3157       20776 :         if (pPCDAttrs && !pPCDAttrs->GetIter()->SeekPos(nCpPos))
    3158           0 :             return false;
    3159       20776 :         return WW8PLCFx_Fc_FKP::SeekPos(pPcd->AktPieceStartCp2Fc(nCpPos));
    3160             :     }
    3161             :                                     // KEINE Piece-Table !!!
    3162         564 :     return WW8PLCFx_Fc_FKP::SeekPos( rSBase.WW8Cp2Fc(nCpPos) );
    3163             : }
    3164             : 
    3165        8782 : WW8_CP WW8PLCFx_Cp_FKP::Where()
    3166             : {
    3167        8782 :     WW8_FC nFc = WW8PLCFx_Fc_FKP::Where();
    3168        8782 :     if( pPcd )
    3169        8782 :         return pPcd->AktPieceStartFc2Cp( nFc ); // Piece ermitteln
    3170           0 :     return rSBase.WW8Fc2Cp( nFc );      // KEINE Piece-Table !!!
    3171             : }
    3172             : 
    3173       21288 : void WW8PLCFx_Cp_FKP::GetSprms(WW8PLCFxDesc* p)
    3174             : {
    3175       21288 :     WW8_CP nOrigCp = p->nStartPos;
    3176             : 
    3177       21288 :     if (!GetDirty())        //Normal case
    3178             :     {
    3179             :         p->pMemPos = WW8PLCFx_Fc_FKP::GetSprmsAndPos(p->nStartPos, p->nEndPos,
    3180       21218 :             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          70 :         if( !pPieceIter )
    3196           0 :             return;
    3197          70 :         sal_uLong nOldPos = pPieceIter->GetIdx();
    3198          70 :         bool bOk = pPieceIter->SeekPos(nOrigCp);
    3199          70 :         pPieceIter->SetIdx( nOldPos );
    3200          70 :         if (!bOk)
    3201          70 :             return;
    3202             :     }
    3203             : 
    3204       21218 :     if( pPcd )  // Piece-Table vorhanden !!!
    3205             :     {
    3206             :         // Init ( noch kein ++ gerufen )
    3207       20654 :         if( (nAttrStart >  nAttrEnd) || (nAttrStart == -1) )
    3208             :         {
    3209       20654 :             p->bRealLineEnd = (ePLCF == PAP);
    3210             : 
    3211       20654 :             if ( ((ePLCF == PAP ) || (ePLCF == CHP)) && (nOrigCp != WW8_CP_MAX) )
    3212             :             {
    3213       20310 :                 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       20310 :                 sal_uLong nOldPos = pPieceIter->GetIdx();
    3225       20310 :                 p->nStartPos = nOrigCp;
    3226       20310 :                 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       20310 :                 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       20310 :                 void* pData=NULL;
    3248       20310 :                 pPieceIter->Get(nCpStart, nCpEnd, pData);
    3249             : 
    3250       20310 :                 WW8_FC nLimitFC = SVBT32ToUInt32( ((WW8_PCD*)pData)->fc );
    3251       20310 :                 WW8_FC nBeginLimitFC = nLimitFC;
    3252       20310 :                 if (IsEightPlus(GetFIBVersion()))
    3253             :                 {
    3254             :                     nBeginLimitFC =
    3255             :                         WW8PLCFx_PCD::TransformPieceAddress(nLimitFC,
    3256       20310 :                         bIsUnicode);
    3257             :                 }
    3258             : 
    3259             :                 nLimitFC = nBeginLimitFC +
    3260       20310 :                     (nCpEnd - nCpStart) * (bIsUnicode ? 2 : 1);
    3261             : 
    3262       20310 :                 if (nOldEndPos <= nLimitFC)
    3263             :                 {
    3264             :                     p->nEndPos = nCpEnd -
    3265       20042 :                         (nLimitFC-nOldEndPos) / (bIsUnicode ? 2 : 1);
    3266             :                 }
    3267             :                 else
    3268             :                 {
    3269         268 :                     if (ePLCF == CHP)
    3270           4 :                         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         264 :                         pPieceIter->advance();
    3292             : 
    3293         528 :                         for (;pPieceIter->GetIdx() < pPieceIter->GetIMax();
    3294           0 :                             pPieceIter->advance())
    3295             :                         {
    3296          68 :                             if( !pPieceIter->Get( nCpStart, nCpEnd, pData ) )
    3297             :                             {
    3298             :                                 OSL_ENSURE( !this, "piece iter broken!" );
    3299             :                                 break;
    3300             :                             }
    3301          68 :                             bIsUnicode = false;
    3302          68 :                             sal_Int32 nFcStart=SVBT32ToUInt32(((WW8_PCD*)pData)->fc);
    3303             : 
    3304          68 :                             if (IsEightPlus(GetFIBVersion()))
    3305             :                             {
    3306             :                                 nFcStart =
    3307             :                                     WW8PLCFx_PCD::TransformPieceAddress(
    3308          68 :                                     nFcStart,bIsUnicode );
    3309             :                             }
    3310             : 
    3311             :                             nLimitFC = nFcStart + (nCpEnd - nCpStart) *
    3312          68 :                                 (bIsUnicode ? 2 : 1);
    3313             : 
    3314             :                             //if it doesn't exist, skip it
    3315          68 :                             if (!SeekPos(nCpStart))
    3316           0 :                                 continue;
    3317             : 
    3318             :                             WW8_FC nOne,nSmallest;
    3319             :                             p->pMemPos = WW8PLCFx_Fc_FKP::GetSprmsAndPos(nOne,
    3320          68 :                                 nSmallest, p->nSprmsLen);
    3321             : 
    3322          68 :                             if (nSmallest <= nLimitFC)
    3323             :                             {
    3324             :                                 WW8_CP nEndPos = nCpEnd -
    3325          68 :                                     (nLimitFC-nSmallest) / (bIsUnicode ? 2 : 1);
    3326             : 
    3327             :                                 OSL_ENSURE(nEndPos >= p->nStartPos, "EndPos before StartPos");
    3328             : 
    3329          68 :                                 if (nEndPos >= p->nStartPos)
    3330          68 :                                     p->nEndPos = nEndPos;
    3331             : 
    3332             :                                 break;
    3333             :                             }
    3334             :                         }
    3335             :                     }
    3336             :                 }
    3337       20310 :                 pPieceIter->SetIdx( nOldPos );
    3338             :             }
    3339             :             else
    3340         344 :                 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         564 :         p->nStartPos = rSBase.WW8Fc2Cp( p->nStartPos );
    3352         564 :         p->nEndPos   = rSBase.WW8Fc2Cp( p->nEndPos );
    3353         564 :         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          74 : WW8PLCFx_SEPX::WW8PLCFx_SEPX(SvStream* pSt, SvStream* pTblSt,
    3382             :     const WW8Fib& rFib, WW8_CP nStartCp)
    3383             :     : WW8PLCFx(rFib.GetFIBVersion(), true), maSprmParser(rFib.GetFIBVersion()),
    3384          74 :     pStrm(pSt), nArrMax(256), nSprmSiz(0)
    3385             : {
    3386             :     pPLCF =   rFib.lcbPlcfsed
    3387             :             ? new WW8PLCF(*pTblSt, rFib.fcPlcfsed, rFib.lcbPlcfsed,
    3388         148 :               GetFIBVersion() <= ww::eWW2 ? 6 : 12, nStartCp)
    3389         222 :             : 0;
    3390             : 
    3391          74 :     pSprms = new sal_uInt8[nArrMax];     // maximum length
    3392          74 : }
    3393             : 
    3394         222 : WW8PLCFx_SEPX::~WW8PLCFx_SEPX()
    3395             : {
    3396          74 :     delete pPLCF;
    3397          74 :     delete[] pSprms;
    3398         148 : }
    3399             : 
    3400         122 : sal_uLong WW8PLCFx_SEPX::GetIdx() const
    3401             : {
    3402         122 :     return pPLCF ? pPLCF->GetIdx() : 0;
    3403             : }
    3404             : 
    3405         122 : void WW8PLCFx_SEPX::SetIdx( sal_uLong nIdx )
    3406             : {
    3407         122 :     if( pPLCF ) pPLCF->SetIdx( nIdx );
    3408         122 : }
    3409             : 
    3410         244 : bool WW8PLCFx_SEPX::SeekPos(WW8_CP nCpPos)
    3411             : {
    3412         244 :     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         442 : void WW8PLCFx_SEPX::GetSprms(WW8PLCFxDesc* p)
    3421             : {
    3422         884 :     if( !pPLCF ) return;
    3423             : 
    3424             :     void* pData;
    3425             : 
    3426         442 :     p->bRealLineEnd = false;
    3427         442 :     if (!pPLCF->Get( p->nStartPos, p->nEndPos, pData ))
    3428             :     {
    3429          36 :         p->nStartPos = p->nEndPos = WW8_CP_MAX;       // PLCF fertig abgearbeitet
    3430          36 :         p->pMemPos = 0;
    3431          36 :         p->nSprmsLen = 0;
    3432             :     }
    3433             :     else
    3434             :     {
    3435         406 :         sal_uInt32 nPo =  SVBT32ToUInt32( (sal_uInt8*)pData+2 );
    3436         406 :         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         406 :             pStrm->Seek( nPo );
    3445             : 
    3446             :             // read len
    3447         406 :             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         406 :                 *pStrm >> nSprmSiz;
    3455             : 
    3456         406 :             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         406 :             nSprmSiz = pStrm->Read(pSprms, nSprmSiz); // read Sprms
    3463             : 
    3464         406 :             p->nSprmsLen = nSprmSiz;
    3465         406 :             p->pMemPos = pSprms;                    // return Position
    3466             :         }
    3467             :     }
    3468             : }
    3469             : 
    3470          46 : void WW8PLCFx_SEPX::advance()
    3471             : {
    3472          46 :     if (pPLCF)
    3473          46 :         pPLCF->advance();
    3474          46 : }
    3475             : 
    3476        2866 : const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId ) const
    3477             : {
    3478        2866 :     return HasSprm( nId, pSprms, nSprmSiz);
    3479             : }
    3480             : 
    3481        2866 : const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, const sal_uInt8*  pOtherSprms,
    3482             :     long nOtherSprmSiz ) const
    3483             : {
    3484        2866 :     const sal_uInt8 *pRet = 0;
    3485        2866 :     if (pPLCF)
    3486             :     {
    3487        2866 :         WW8SprmIter aIter(pOtherSprms, nOtherSprmSiz, maSprmParser);
    3488        2866 :         pRet = aIter.FindSprm(nId);
    3489             :     }
    3490        2866 :     return pRet;
    3491             : }
    3492             : 
    3493          84 : 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          84 :     if( !pPLCF )
    3497           0 :         return 0;
    3498             : 
    3499          84 :     bool bFound = false;
    3500          84 :     p1 = 0;
    3501          84 :     p2 = 0;
    3502          84 :     p3 = 0;
    3503          84 :     p4 = 0;
    3504             : 
    3505          84 :     sal_uInt8* pSp = pSprms;
    3506          84 :     sal_uInt16 i=0;
    3507        1174 :     while (i + maSprmParser.MinSprmLen() <= nSprmSiz)
    3508             :     {
    3509             :         // Sprm gefunden?
    3510        1006 :         sal_uInt16 nAktId = maSprmParser.GetSprmId(pSp);
    3511        1006 :         bool bOk = true;
    3512        1006 :         if( nAktId  == nId1 )
    3513           0 :             p1 = pSp + maSprmParser.DistanceToData(nId1);
    3514        1006 :         else if( nAktId  == nId2 )
    3515           0 :             p2 = pSp + maSprmParser.DistanceToData(nId2);
    3516        1006 :         else if( nAktId  == nId3 )
    3517           0 :             p3 = pSp + maSprmParser.DistanceToData(nId3);
    3518        1006 :         else if( nAktId  == nId4 )
    3519           0 :             p4 = pSp + maSprmParser.DistanceToData(nId4);
    3520             :         else
    3521        1006 :             bOk = false;
    3522        1006 :         bFound |= bOk;
    3523             :         // erhoehe Zeiger, so dass er auf naechsten Sprm zeigt
    3524        1006 :         sal_uInt16 x = maSprmParser.GetSprmSize(nAktId, pSp);
    3525        1006 :         i = i + x;
    3526        1006 :         pSp += x;
    3527             :     }
    3528          84 :     return bFound;
    3529             : }
    3530             : 
    3531          12 : const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const
    3532             : {
    3533          12 :     if( !pPLCF )
    3534           0 :         return 0;
    3535             : 
    3536          12 :     sal_uInt8* pSp = pSprms;
    3537             : 
    3538          12 :     sal_uInt16 i=0;
    3539         210 :     while (i + maSprmParser.MinSprmLen() <= nSprmSiz)
    3540             :     {
    3541             :         // Sprm gefunden?
    3542         198 :         sal_uInt16 nAktId = maSprmParser.GetSprmId(pSp);
    3543         198 :         if (nAktId == nId)
    3544             :         {
    3545          16 :             sal_uInt8 *pRet = pSp + maSprmParser.DistanceToData(nId);
    3546          16 :             if (*pRet == n2nd)
    3547          12 :                 return pRet;
    3548             :         }
    3549             :         // erhoehe Zeiger, so dass er auf naechsten Sprm zeigt
    3550         186 :         sal_uInt16 x = maSprmParser.GetSprmSize(nAktId, pSp);
    3551         186 :         i = i + x;
    3552         186 :         pSp += x;
    3553             :     }
    3554             : 
    3555           0 :     return 0;   // Sprm nicht gefunden
    3556             : }
    3557             : 
    3558             : //-----------------------------------------
    3559         222 : 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         222 :     : WW8PLCFx(eVersion, true), pRef(0), pTxt(0)
    3563             : {
    3564         222 :     if( nLenRef && nLenTxt )
    3565             :     {
    3566           2 :         pRef = new WW8PLCF(*pSt, nFcRef, nLenRef, nStruct, nStartCp);
    3567           2 :         pTxt = new WW8PLCF(*pSt, nFcTxt, nLenTxt, 0, nStartCp);
    3568             :     }
    3569         222 : }
    3570             : 
    3571         666 : WW8PLCFx_SubDoc::~WW8PLCFx_SubDoc()
    3572             : {
    3573         222 :     delete pRef;
    3574         222 :     delete pTxt;
    3575         444 : }
    3576             : 
    3577         366 : sal_uLong WW8PLCFx_SubDoc::GetIdx() const
    3578             : {
    3579             :     // Wahrscheinlich pTxt... nicht noetig
    3580         366 :     if( pRef )
    3581           4 :         return ( pRef->GetIdx() << 16 | pTxt->GetIdx() );
    3582         362 :     return 0;
    3583             : }
    3584             : 
    3585         366 : void WW8PLCFx_SubDoc::SetIdx( sal_uLong nIdx )
    3586             : {
    3587         366 :     if( pRef )
    3588             :     {
    3589           4 :         pRef->SetIdx( nIdx >> 16 );
    3590             :         // Wahrscheinlich pTxt... nicht noetig
    3591           4 :         pTxt->SetIdx( nIdx & 0xFFFF );
    3592             :     }
    3593         366 : }
    3594             : 
    3595         732 : bool WW8PLCFx_SubDoc::SeekPos( WW8_CP nCpPos )
    3596             : {
    3597         732 :     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         956 : void WW8PLCFx_SubDoc::GetSprms(WW8PLCFxDesc* p)
    3606             : {
    3607         956 :     p->nStartPos = p->nEndPos = WW8_CP_MAX;
    3608         956 :     p->pMemPos = 0;
    3609         956 :     p->nSprmsLen = 0;
    3610         956 :     p->bRealLineEnd = false;
    3611             : 
    3612         956 :     if (!pRef)
    3613             :         return;
    3614             : 
    3615          12 :     sal_uLong nNr = pRef->GetIdx();
    3616             : 
    3617             :     void *pData;
    3618             :     WW8_CP nFoo;
    3619          12 :     if (!pRef->Get(p->nStartPos, nFoo, pData))
    3620             :     {
    3621           2 :         p->nEndPos = p->nStartPos = WW8_CP_MAX;
    3622             :         return;
    3623             :     }
    3624             : 
    3625          10 :     p->nEndPos = p->nStartPos + 1;
    3626             : 
    3627          10 :     if (!pTxt)
    3628             :         return;
    3629             : 
    3630          10 :     pTxt->SetIdx(nNr);
    3631             : 
    3632          10 :     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          10 :     p->nSprmsLen -= p->nCp2OrIdx;
    3640             : }
    3641             : 
    3642           2 : void WW8PLCFx_SubDoc::advance()
    3643             : {
    3644           2 :     if (pRef && pTxt)
    3645             :     {
    3646           2 :         pRef->advance();
    3647           2 :         pTxt->advance();
    3648             :     }
    3649           2 : }
    3650             : 
    3651             : //-----------------------------------------
    3652             : //          Felder
    3653             : //-----------------------------------------
    3654             : 
    3655         518 : WW8PLCFx_FLD::WW8PLCFx_FLD( SvStream* pSt, const WW8Fib& rMyFib, short nType)
    3656         518 :     : WW8PLCFx(rMyFib.GetFIBVersion(), true), pPLCF(0), rFib(rMyFib)
    3657             : {
    3658             :     long nFc, nLen;
    3659             : 
    3660         518 :     switch( nType )
    3661             :     {
    3662             :     case MAN_HDFT:
    3663          74 :         nFc = rFib.fcPlcffldHdr;
    3664          74 :         nLen = rFib.lcbPlcffldHdr;
    3665          74 :         break;
    3666             :     case MAN_FTN:
    3667          74 :         nFc = rFib.fcPlcffldFtn;
    3668          74 :         nLen = rFib.lcbPlcffldFtn;
    3669          74 :         break;
    3670             :     case MAN_EDN:
    3671          74 :         nFc = rFib.fcPlcffldEdn;
    3672          74 :         nLen = rFib.lcbPlcffldEdn;
    3673          74 :         break;
    3674             :     case MAN_AND:
    3675          74 :         nFc = rFib.fcPlcffldAtn;
    3676          74 :         nLen = rFib.lcbPlcffldAtn;
    3677          74 :         break;
    3678             :     case MAN_TXBX:
    3679          74 :         nFc = rFib.fcPlcffldTxbx;
    3680          74 :         nLen = rFib.lcbPlcffldTxbx;
    3681          74 :         break;
    3682             :     case MAN_TXBX_HDFT:
    3683          74 :         nFc = rFib.fcPlcffldHdrTxbx;
    3684          74 :         nLen = rFib.lcbPlcffldHdrTxbx;
    3685          74 :         break;
    3686             :     default:
    3687          74 :         nFc = rFib.fcPlcffldMom;
    3688          74 :         nLen = rFib.lcbPlcffldMom;
    3689          74 :         break;
    3690             :     }
    3691             : 
    3692         518 :     if( nLen )
    3693          26 :         pPLCF = new WW8PLCFspecial( pSt, nFc, nLen, 2 );
    3694         518 : }
    3695             : 
    3696        1554 : WW8PLCFx_FLD::~WW8PLCFx_FLD()
    3697             : {
    3698         518 :     delete pPLCF;
    3699        1036 : }
    3700             : 
    3701         122 : sal_uLong WW8PLCFx_FLD::GetIdx() const
    3702             : {
    3703         122 :     return pPLCF ? pPLCF->GetIdx() : 0;
    3704             : }
    3705             : 
    3706         122 : void WW8PLCFx_FLD::SetIdx( sal_uLong nIdx )
    3707             : {
    3708         122 :     if( pPLCF )
    3709          18 :         pPLCF->SetIdx( nIdx );
    3710         122 : }
    3711             : 
    3712         438 : bool WW8PLCFx_FLD::SeekPos(WW8_CP nCpPos)
    3713             : {
    3714         438 :     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          72 : bool WW8PLCFx_FLD::StartPosIsFieldStart()
    3723             : {
    3724             :     void* pData;
    3725             :     sal_Int32 nTest;
    3726         216 :     if (
    3727         144 :          (!pPLCF || !pPLCF->Get(nTest, pData) ||
    3728          72 :          ((((sal_uInt8*)pData)[0] & 0x1f) != 0x13))
    3729             :        )
    3730          42 :         return false;
    3731          30 :     return true;
    3732             : }
    3733             : 
    3734          70 : bool WW8PLCFx_FLD::EndPosIsFieldEnd()
    3735             : {
    3736          70 :     bool bRet = false;
    3737             : 
    3738          70 :     if (pPLCF)
    3739             :     {
    3740          70 :         long n = pPLCF->GetIdx();
    3741             : 
    3742          70 :         pPLCF->advance();
    3743             : 
    3744             :         void* pData;
    3745             :         sal_Int32 nTest;
    3746          70 :         if ( pPLCF->Get(nTest, pData) && ((((sal_uInt8*)pData)[0] & 0x1f) == 0x15) )
    3747          30 :             bRet = true;
    3748             : 
    3749          70 :         pPLCF->SetIdx(n);
    3750             :     }
    3751             : 
    3752          70 :     return bRet;
    3753             : }
    3754             : 
    3755         582 : void WW8PLCFx_FLD::GetSprms(WW8PLCFxDesc* p)
    3756             : {
    3757         582 :     p->nStartPos = p->nEndPos = WW8_CP_MAX;
    3758         582 :     p->pMemPos = 0;
    3759         582 :     p->nSprmsLen = 0;
    3760         582 :     p->bRealLineEnd = false;
    3761             : 
    3762         582 :     if (!pPLCF)
    3763             :     {
    3764         358 :         p->nStartPos = WW8_CP_MAX;                    // Es gibt keine Felder
    3765             :         return;
    3766             :     }
    3767             : 
    3768         224 :     long n = pPLCF->GetIdx();
    3769             : 
    3770             :     sal_Int32 nP;
    3771             :     void *pData;
    3772         224 :     if (!pPLCF->Get(nP, pData))             // Ende des PLCFspecial ?
    3773             :     {
    3774          98 :         p->nStartPos = WW8_CP_MAX;            // PLCF fertig abgearbeitet
    3775             :         return;
    3776             :     }
    3777             : 
    3778         126 :     p->nStartPos = nP;
    3779             : 
    3780         126 :     pPLCF->advance();
    3781         126 :     if (!pPLCF->Get(nP, pData))             // Ende des PLCFspecial ?
    3782             :     {
    3783          18 :         p->nStartPos = WW8_CP_MAX;            // PLCF fertig abgearbeitet
    3784             :         return;
    3785             :     }
    3786             : 
    3787         108 :     p->nEndPos = nP;
    3788             : 
    3789         108 :     pPLCF->SetIdx(n);
    3790             : 
    3791         108 :     p->nCp2OrIdx = pPLCF->GetIdx();
    3792             : }
    3793             : 
    3794          70 : void WW8PLCFx_FLD::advance()
    3795             : {
    3796          70 :     pPLCF->advance();
    3797          70 : }
    3798             : 
    3799          30 : bool WW8PLCFx_FLD::GetPara(long nIdx, WW8FieldDesc& rF)
    3800             : {
    3801             :     OSL_ENSURE( pPLCF, "Aufruf ohne Feld PLCFspecial" );
    3802          30 :     if( !pPLCF )
    3803           0 :         return false;
    3804             : 
    3805          30 :     long n = pPLCF->GetIdx();
    3806          30 :     pPLCF->SetIdx(nIdx);
    3807             : 
    3808          30 :     bool bOk = WW8GetFieldPara(*pPLCF, rF);
    3809             : 
    3810          30 :     pPLCF->SetIdx(n);
    3811          30 :     return bOk;
    3812             : }
    3813             : 
    3814             : //-----------------------------------------
    3815             : //      class WW8PLCF_Book
    3816             : //-----------------------------------------
    3817             : 
    3818             : /*  to be optimized like this:    */
    3819         204 : 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         204 :     if (nLen==0)     // Handle Empty STTBF
    3824         352 :         return;
    3825             : 
    3826          56 :     sal_Size nOldPos = rStrm.Tell();
    3827          56 :     if (checkSeek(rStrm, nStart))
    3828             :     {
    3829          56 :         sal_uInt16 nLen2(0);
    3830          56 :         rStrm >> nLen2; // bVer67: total length of structure
    3831             :                         // bVer8 : count of strings
    3832             : 
    3833          56 :         if( bVer8 )
    3834             :         {
    3835          56 :             sal_uInt16 nStrings(0);
    3836          56 :             bool bUnicode = (0xFFFF == nLen2);
    3837          56 :             if (bUnicode)
    3838          54 :                 rStrm >> nStrings;
    3839             :             else
    3840           2 :                 nStrings = nLen2;
    3841             : 
    3842          56 :             rStrm >> nExtraLen;
    3843             : 
    3844       33398 :             for (sal_uInt16 i=0; i < nStrings; ++i)
    3845             :             {
    3846       33342 :                 if (bUnicode)
    3847          62 :                     rArray.push_back(read_uInt16_PascalString(rStrm));
    3848             :                 else
    3849             :                 {
    3850       33280 :                     rtl::OString aTmp = read_lenPrefixed_uInt8s_ToOString<sal_uInt8>(rStrm);
    3851       33280 :                     rArray.push_back(rtl::OStringToOUString(aTmp, eCS));
    3852             :                 }
    3853             : 
    3854             :                 // Skip the extra data
    3855       33342 :                 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          56 :             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          56 :     rStrm.Seek(nOldPos);
    3937             : }
    3938             : 
    3939          74 : WW8PLCFx_Book::WW8PLCFx_Book(SvStream* pTblSt, const WW8Fib& rFib)
    3940          74 :     : WW8PLCFx(rFib.GetFIBVersion(), false), pStatus(0), nIsEnd(0), nBookmarkId(1)
    3941             : {
    3942          86 :     if( !rFib.fcPlcfbkf || !rFib.lcbPlcfbkf || !rFib.fcPlcfbkl ||
    3943          12 :         !rFib.lcbPlcfbkl || !rFib.fcSttbfbkmk || !rFib.lcbSttbfbkmk )
    3944             :     {
    3945          70 :         pBook[0] = pBook[1] = 0;
    3946          70 :         nIMax = 0;
    3947             :     }
    3948             :     else
    3949             :     {
    3950           4 :         pBook[0] = new WW8PLCFspecial(pTblSt,rFib.fcPlcfbkf,rFib.lcbPlcfbkf,4);
    3951             : 
    3952           4 :         pBook[1] = new WW8PLCFspecial(pTblSt,rFib.fcPlcfbkl,rFib.lcbPlcfbkl,0);
    3953             : 
    3954           4 :         rtl_TextEncoding eStructChrSet = WW8Fib::GetFIBCharset(rFib.chseTables);
    3955             : 
    3956             :         WW8ReadSTTBF( (7 < rFib.nVersion), *pTblSt, rFib.fcSttbfbkmk,
    3957           4 :             rFib.lcbSttbfbkmk, 0, eStructChrSet, aBookNames );
    3958             : 
    3959           4 :         nIMax = aBookNames.size();
    3960             : 
    3961           4 :         if( pBook[0]->GetIMax() < nIMax )   // Count of Bookmarks
    3962           0 :             nIMax = pBook[0]->GetIMax();
    3963           4 :         if( pBook[1]->GetIMax() < nIMax )
    3964           0 :             nIMax = pBook[1]->GetIMax();
    3965           4 :         pStatus = new eBookStatus[ nIMax ];
    3966           4 :         memset( pStatus, 0, nIMax * sizeof( eBookStatus ) );
    3967             :     }
    3968          74 : }
    3969             : 
    3970         222 : WW8PLCFx_Book::~WW8PLCFx_Book()
    3971             : {
    3972          74 :     delete[] pStatus;
    3973          74 :     delete pBook[1];
    3974          74 :     delete pBook[0];
    3975         148 : }
    3976             : 
    3977         122 : sal_uLong WW8PLCFx_Book::GetIdx() const
    3978             : {
    3979         122 :     return nIMax ? pBook[0]->GetIdx() : 0;
    3980             : }
    3981             : 
    3982         122 : void WW8PLCFx_Book::SetIdx( sal_uLong nI )
    3983             : {
    3984         122 :     if( nIMax )
    3985          22 :         pBook[0]->SetIdx( nI );
    3986         122 : }
    3987             : 
    3988         122 : sal_uLong WW8PLCFx_Book::GetIdx2() const
    3989             : {
    3990         122 :     return nIMax ? ( pBook[1]->GetIdx() | ( ( nIsEnd ) ? 0x80000000 : 0 ) ) : 0;
    3991             : }
    3992             : 
    3993         122 : void WW8PLCFx_Book::SetIdx2( sal_uLong nI )
    3994             : {
    3995         122 :     if( nIMax )
    3996             :     {
    3997          22 :         pBook[1]->SetIdx( nI & 0x7fffffff );
    3998          22 :         nIsEnd = (sal_uInt16)( ( nI >> 31 ) & 1 );  // 0 oder 1
    3999             :     }
    4000         122 : }
    4001             : 
    4002         194 : bool WW8PLCFx_Book::SeekPos(WW8_CP nCpPos)
    4003             : {
    4004         194 :     if( !pBook[0] )
    4005         170 :         return false;
    4006             : 
    4007          24 :     bool bOk = pBook[0]->SeekPosExact( nCpPos );
    4008          24 :     bOk &= pBook[1]->SeekPosExact( nCpPos );
    4009          24 :     nIsEnd = 0;
    4010             : 
    4011          24 :     return bOk;
    4012             : }
    4013             : 
    4014           0 : WW8_CP WW8PLCFx_Book::Where()
    4015             : {
    4016           0 :     return pBook[nIsEnd]->Where();
    4017             : }
    4018             : 
    4019         292 : long WW8PLCFx_Book::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen )
    4020             : {
    4021             :     void* pData;
    4022         292 :     rEnd = WW8_CP_MAX;
    4023         292 :     rLen = 0;
    4024             : 
    4025         292 :     if (!pBook[0] || !pBook[1] || !nIMax || (pBook[nIsEnd]->GetIdx()) >= nIMax)
    4026             :     {
    4027         268 :         rStart = rEnd = WW8_CP_MAX;
    4028         268 :         return -1;
    4029             :     }
    4030             : 
    4031          24 :     pBook[nIsEnd]->Get( rStart, pData );    // Pos. abfragen
    4032             : 
    4033          24 :     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          24 : void WW8PLCFx_Book::advance()
    4048             : {
    4049          24 :     if( pBook[0] && pBook[1] && nIMax )
    4050             :     {
    4051          24 :         (*pBook[nIsEnd]).advance();
    4052             : 
    4053          24 :         sal_uLong l0 = pBook[0]->Where();
    4054          24 :         sal_uLong l1 = pBook[1]->Where();
    4055          24 :         if( l0 < l1 )
    4056           2 :             nIsEnd = 0;
    4057          22 :         else if( l1 < l0 )
    4058          10 :             nIsEnd = 1;
    4059             :         else
    4060          12 :             nIsEnd = ( nIsEnd ) ? 0 : 1;
    4061             :     }
    4062          24 : }
    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          24 : eBookStatus WW8PLCFx_Book::GetStatus() const
    4091             : {
    4092          24 :     if( !pStatus )
    4093           0 :         return BOOK_NORMAL;
    4094          24 :     long nEndIdx = GetHandle();
    4095          24 :     return ( nEndIdx < nIMax ) ? pStatus[nEndIdx] : BOOK_NORMAL;
    4096             : }
    4097             : 
    4098          48 : long WW8PLCFx_Book::GetHandle() const
    4099             : {
    4100          48 :     if( !pBook[0] || !pBook[1] )
    4101           0 :         return LONG_MAX;
    4102             : 
    4103          48 :     if( nIsEnd )
    4104          24 :         return pBook[1]->GetIdx();
    4105             :     else
    4106             :     {
    4107          24 :         if (const void* p = pBook[0]->GetData(pBook[0]->GetIdx()))
    4108          24 :             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          12 : const String* WW8PLCFx_Book::GetName() const
    4191             : {
    4192          12 :     const String *pRet = 0;
    4193          12 :     if (!nIsEnd && (pBook[0]->GetIdx() < nIMax))
    4194          12 :         pRet = &(aBookNames[pBook[0]->GetIdx()]);
    4195          12 :     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       25710 : 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       25710 :     rDesc.nOrigEndPos = rDesc.nEndPos;
    4212       25710 :     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       25710 :     if (GetDoingDrawTextBox())
    4222       26206 :         return;
    4223             : 
    4224       25214 :     if ( (&rDesc == pPap) && rDesc.bRealLineEnd )
    4225             :     {
    4226       10812 :         if ( pPap->nEndPos != WW8_CP_MAX )    // Para adjust
    4227             :         {
    4228        5366 :             nLineEnd = pPap->nEndPos;// nLineEnd zeigt *hinter* das <CR>
    4229        5366 :             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        5366 :             if (pChp->nEndPos == nLineEnd)
    4234         818 :                 pChp->nEndPos--;
    4235             : 
    4236             :             // gibt es bereits ein Sep-Ende, das auf das jetzige Absatzende
    4237             :             // zeigt ?  ... dann auch um 1 Zeichen verkuerzen
    4238        5366 :             if( pSep->nEndPos == nLineEnd )
    4239          32 :                 pSep->nEndPos--;
    4240             :         }
    4241             :     }
    4242       19808 :     else if ( (&rDesc == pChp) || (&rDesc == pSep) )
    4243             :     {
    4244             :         // Char Adjust oder Sep Adjust Wenn Ende Char-Attr == Absatzende ...
    4245        4752 :         if( (rDesc.nEndPos == nLineEnd) && (rDesc.nEndPos > rDesc.nStartPos) )
    4246        1076 :             rDesc.nEndPos--;            // ... dann um 1 Zeichen verkuerzen
    4247             :     }
    4248             : }
    4249             : 
    4250       38526 : void WW8PLCFxDesc::ReduceByOffset()
    4251             : {
    4252             :    OSL_ENSURE((WW8_CP_MAX == nStartPos) || (nStartPos <= nEndPos),
    4253             :             "Attr-Anfang und -Ende ueber Kreuz" );
    4254             : 
    4255       38526 :     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       36802 :         if (nCpOfs > nStartPos)
    4264         862 :             nStartPos = 0;
    4265             :         else
    4266       35940 :             nStartPos -= nCpOfs;
    4267             :     }
    4268       38526 :     if( nEndPos != WW8_CP_MAX )
    4269             :     {
    4270             :         OSL_ENSURE(nCpOfs <= nEndPos,
    4271             :             "oh oh, so much for the subdocument piece theory");
    4272       36514 :         nEndPos   -= nCpOfs;
    4273             :     }
    4274       38526 : }
    4275             : 
    4276       25710 : void WW8PLCFMan::GetNewSprms( WW8PLCFxDesc& rDesc )
    4277             : {
    4278       25710 :     rDesc.pPLCFx->GetSprms(&rDesc);
    4279       25710 :     rDesc.ReduceByOffset();
    4280             : 
    4281       25710 :     rDesc.bFirstSprm = true;
    4282       25710 :     AdjustEnds( rDesc );
    4283       25710 :     rDesc.nOrigSprmsLen = rDesc.nSprmsLen;
    4284       25710 : }
    4285             : 
    4286        7800 : void WW8PLCFMan::GetNewNoSprms( WW8PLCFxDesc& rDesc )
    4287             : {
    4288             :     rDesc.nCp2OrIdx = rDesc.pPLCFx->GetNoSprms(rDesc.nStartPos, rDesc.nEndPos,
    4289        7800 :         rDesc.nSprmsLen);
    4290             : 
    4291             :    OSL_ENSURE((WW8_CP_MAX == rDesc.nStartPos) || (rDesc.nStartPos <= rDesc.nEndPos),
    4292             :             "Attr-Anfang und -Ende ueber Kreuz" );
    4293             : 
    4294        7800 :     rDesc.ReduceByOffset();
    4295             : 
    4296        7800 :     rDesc.bFirstSprm = true;
    4297        7800 :     rDesc.nOrigSprmsLen = rDesc.nSprmsLen;
    4298        7800 : }
    4299             : 
    4300      124608 : sal_uInt16 WW8PLCFMan::GetId(const WW8PLCFxDesc* p) const
    4301             : {
    4302      124608 :     sal_uInt16 nId = 0;        // Id = 0 for empty attributes
    4303             : 
    4304      124608 :     if (p == pFld)
    4305         144 :         nId = eFLD;
    4306      124464 :     else if (p == pFtn)
    4307           4 :         nId = eFTN;
    4308      124460 :     else if (p == pEdn)
    4309           0 :         nId = eEDN;
    4310      124460 :     else if (p == pAnd)
    4311           0 :         nId = eAND;
    4312      124460 :     else if (p->nSprmsLen >= maSprmParser.MinSprmLen())
    4313      103848 :         nId = maSprmParser.GetSprmId(p->pMemPos);
    4314             : 
    4315      124608 :     return nId;
    4316             : }
    4317             : 
    4318         268 : WW8PLCFMan::WW8PLCFMan(WW8ScannerBase* pBase, ManTypes nType, long nStartCp,
    4319             :     bool bDoingDrawTextBox)
    4320             :     : maSprmParser(pBase->pWw8Fib->GetFIBVersion()),
    4321         268 :     mbDoingDrawTextBox(bDoingDrawTextBox)
    4322             : {
    4323         268 :     pWwFib = pBase->pWw8Fib;
    4324             : 
    4325         268 :     nLastWhereIdxCp = 0;
    4326         268 :     memset( aD, 0, sizeof( aD ) );
    4327         268 :     nLineEnd = WW8_CP_MAX;
    4328         268 :     nManType = nType;
    4329             :     sal_uInt16 i;
    4330             : 
    4331         268 :     if( MAN_MAINTEXT == nType )
    4332             :     {
    4333             :         // Suchreihenfolge der Attribute
    4334          74 :         nPLCF = MAN_ANZ_PLCF;
    4335          74 :         pFld = &aD[0];
    4336          74 :         pBkm = &aD[1];
    4337          74 :         pEdn = &aD[2];
    4338          74 :         pFtn = &aD[3];
    4339          74 :         pAnd = &aD[4];
    4340             : 
    4341          74 :         pPcd = ( pBase->pPLCFx_PCD ) ? &aD[5] : 0;
    4342             :         //pPcdA index == pPcd index + 1
    4343          74 :         pPcdA = ( pBase->pPLCFx_PCDAttrs ) ? &aD[6] : 0;
    4344             : 
    4345          74 :         pChp = &aD[7];
    4346          74 :         pPap = &aD[8];
    4347          74 :         pSep = &aD[9];
    4348             : 
    4349          74 :         pSep->pPLCFx = pBase->pSepPLCF;
    4350          74 :         pFtn->pPLCFx = pBase->pFtnPLCF;
    4351          74 :         pEdn->pPLCFx = pBase->pEdnPLCF;
    4352          74 :         pBkm->pPLCFx = pBase->pBook;
    4353          74 :         pAnd->pPLCFx = pBase->pAndPLCF;
    4354             : 
    4355             :     }
    4356             :     else
    4357             :     {
    4358             :         // Suchreihenfolge der Attribute
    4359         194 :         nPLCF = 7;
    4360         194 :         pFld = &aD[0];
    4361         194 :         pBkm = ( pBase->pBook ) ? &aD[1] : 0;
    4362             : 
    4363         194 :         pPcd = ( pBase->pPLCFx_PCD ) ? &aD[2] : 0;
    4364             :         //pPcdA index == pPcd index + 1
    4365         194 :         pPcdA= ( pBase->pPLCFx_PCDAttrs ) ? &aD[3] : 0;
    4366             : 
    4367         194 :         pChp = &aD[4];
    4368         194 :         pPap = &aD[5];
    4369         194 :         pSep = &aD[6]; // Dummy
    4370             : 
    4371         194 :         pAnd = pFtn = pEdn = 0;     // unbenutzt bei SpezText
    4372             :     }
    4373             : 
    4374         268 :     pChp->pPLCFx = pBase->pChpPLCF;
    4375         268 :     pPap->pPLCFx = pBase->pPapPLCF;
    4376         268 :     if( pPcd )
    4377         266 :         pPcd->pPLCFx = pBase->pPLCFx_PCD;
    4378         268 :     if( pPcdA )
    4379         266 :         pPcdA->pPLCFx= pBase->pPLCFx_PCDAttrs;
    4380         268 :     if( pBkm )
    4381         268 :         pBkm->pPLCFx = pBase->pBook;
    4382             : 
    4383         268 :     pMagicTables = pBase->pMagicTables;
    4384         268 :     pSubdocs = pBase->pSubdocs;
    4385         268 :     pExtendedAtrds = pBase->pExtendedAtrds;
    4386             : 
    4387         268 :     switch( nType )                 // Feld-Initialisierung
    4388             :     {
    4389             :         case MAN_HDFT:
    4390          76 :             pFld->pPLCFx = pBase->pFldHdFtPLCF;
    4391          76 :             pFdoa = pBase->pHdFtFdoa;
    4392          76 :             pTxbx = pBase->pHdFtTxbx;
    4393          76 :             pTxbxBkd = pBase->pHdFtTxbxBkd;
    4394          76 :             break;
    4395             :         case MAN_FTN:
    4396           2 :             pFld->pPLCFx = pBase->pFldFtnPLCF;
    4397           2 :             pFdoa = pTxbx = pTxbxBkd = 0;
    4398           2 :             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         116 :             pFld->pPLCFx = pBase->pFldTxbxPLCF;
    4409         116 :             pTxbx = pBase->pMainTxbx;
    4410         116 :             pTxbxBkd = pBase->pMainTxbxBkd;
    4411         116 :             pFdoa = 0;
    4412         116 :             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          74 :             pFld->pPLCFx = pBase->pFldPLCF;
    4421          74 :             pFdoa = pBase->pMainFdoa;
    4422          74 :             pTxbx = pBase->pMainTxbx;
    4423          74 :             pTxbxBkd = pBase->pMainTxbxBkd;
    4424          74 :             break;
    4425             :     }
    4426             : 
    4427         268 :     nCpO = pWwFib->GetBaseCp(nType);
    4428             : 
    4429         268 :     if( nStartCp || nCpO )
    4430         194 :         SeekPos( nStartCp );    // PLCFe auf Text-StartPos einstellen
    4431             : 
    4432             :     // initialisieren der Member-Vars Low-Level
    4433         268 :     GetChpPLCF()->ResetAttrStartEnd();
    4434         268 :     GetPapPLCF()->ResetAttrStartEnd();
    4435        2366 :     for( i=0; i < nPLCF; i++)
    4436             :     {
    4437        2098 :         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        2098 :             p == pPcdA ) ? nCpO : 0;
    4448             : 
    4449        2098 :         p->nCp2OrIdx = 0;
    4450        2098 :         p->bFirstSprm = false;
    4451        2098 :         p->pIdStk = 0;
    4452             : 
    4453        2098 :         if ((p == pChp) || (p == pPap))
    4454         536 :             p->nStartPos = p->nEndPos = nStartCp;
    4455             :         else
    4456        1562 :             p->nStartPos = p->nEndPos = WW8_CP_MAX;
    4457             :     }
    4458             : 
    4459             :     // initialisieren der Member-Vars High-Level
    4460        2366 :     for( i=0; i<nPLCF; i++){
    4461        2098 :         WW8PLCFxDesc* p = &aD[i];
    4462             : 
    4463        2098 :         if( !p->pPLCFx )
    4464             :         {
    4465         198 :             p->nStartPos = p->nEndPos = WW8_CP_MAX;
    4466         198 :             continue;
    4467             :         }
    4468             : 
    4469        1900 :         if( p->pPLCFx->IsSprm() )
    4470             :         {
    4471             :             // Vorsicht: nEndPos muss bereits
    4472        1366 :             p->pIdStk = new std::stack<sal_uInt16>;
    4473        1366 :             if ((p == pChp) || (p == pPap))
    4474             :             {
    4475         536 :                 WW8_CP nTemp = p->nEndPos+p->nCpOfs;
    4476         536 :                 p->pMemPos = 0;
    4477         536 :                 p->nSprmsLen = 0;
    4478         536 :                 p->nStartPos = nTemp;
    4479         536 :                 if (!(*p->pPLCFx).SeekPos(p->nStartPos))
    4480           4 :                     p->nEndPos = p->nStartPos = WW8_CP_MAX;
    4481             :                 else
    4482         532 :                     GetNewSprms( *p );
    4483             :             }
    4484             :             else
    4485         830 :                 GetNewSprms( *p );      // bei allen PLCFen initialisiert sein
    4486             :         }
    4487         534 :         else if( p->pPLCFx )
    4488         534 :             GetNewNoSprms( *p );
    4489             :     }
    4490         268 : }
    4491             : 
    4492         268 : WW8PLCFMan::~WW8PLCFMan()
    4493             : {
    4494        2366 :     for( sal_uInt16 i=0; i<nPLCF; i++)
    4495        2098 :         delete aD[i].pIdStk;
    4496         268 : }
    4497             : 
    4498             : // 0. welche Attr.-Klasse,
    4499             : // 1. ob ein Attr.-Start ist,
    4500             : // 2. CP, wo ist naechste Attr.-Aenderung
    4501      366970 : sal_uInt16 WW8PLCFMan::WhereIdx(bool* pbStart, long* pPos) const
    4502             : {
    4503             :     OSL_ENSURE(nPLCF,"What the hell");
    4504      366970 :     long nNext = LONG_MAX;  // SuchReihenfolge:
    4505      366970 :     sal_uInt16 nNextIdx = nPLCF;// first ending found ( CHP, PAP, ( SEP ) ),
    4506      366970 :     bool bStart = true;     // dann Anfaenge finden ( ( SEP ), PAP, CHP )
    4507             :     sal_uInt16 i;
    4508             :     const WW8PLCFxDesc* pD;
    4509     4005182 :     for (i=0; i < nPLCF; i++)
    4510             :     {
    4511     3638212 :         pD = &aD[i];
    4512     3638212 :         if (pD != pPcdA)
    4513             :         {
    4514     3279310 :             if( (pD->nEndPos < nNext) && (pD->nStartPos == WW8_CP_MAX) )
    4515             :             {
    4516             :                 // sonst ist Anfang = Ende
    4517      540698 :                 nNext = pD->nEndPos;
    4518      540698 :                 nNextIdx = i;
    4519      540698 :                 bStart = false;
    4520             :             }
    4521             :         }
    4522             :     }
    4523     4005182 :     for (i=nPLCF; i > 0; i--)
    4524             :     {
    4525     3638212 :         pD = &aD[i-1];
    4526     3638212 :         if (pD != pPcdA)
    4527             :         {
    4528     3279310 :             if( pD->nStartPos < nNext )
    4529             :             {
    4530      211332 :                 nNext = pD->nStartPos;
    4531      211332 :                 nNextIdx = i-1;
    4532      211332 :                 bStart = true;
    4533             :             }
    4534             :         }
    4535             :     }
    4536      366970 :     if( pPos )
    4537      122822 :         *pPos = nNext;
    4538      366970 :     if( pbStart )
    4539      244148 :         *pbStart = bStart;
    4540      366970 :     return nNextIdx;
    4541             : }
    4542             : 
    4543             : // gibt die CP-Pos der naechsten Attribut-Aenderung zurueck
    4544      122822 : WW8_CP WW8PLCFMan::Where() const
    4545             : {
    4546             :     long l;
    4547      122822 :     WhereIdx(0, &l);
    4548      122822 :     return l;
    4549             : }
    4550             : 
    4551         194 : void WW8PLCFMan::SeekPos( long nNewCp )
    4552             : {
    4553         194 :     pChp->pPLCFx->SeekPos( nNewCp + nCpO ); // Attribute neu
    4554         194 :     pPap->pPLCFx->SeekPos( nNewCp + nCpO ); // aufsetzen
    4555         194 :     pFld->pPLCFx->SeekPos( nNewCp );
    4556         194 :     if( pPcd )
    4557         194 :         pPcd->pPLCFx->SeekPos( nNewCp + nCpO );
    4558         194 :     if( pBkm )
    4559         194 :         pBkm->pPLCFx->SeekPos( nNewCp + nCpO );
    4560         194 : }
    4561             : 
    4562         122 : void WW8PLCFMan::SaveAllPLCFx( WW8PLCFxSaveAll& rSave ) const
    4563             : {
    4564         122 :     sal_uInt16 i, n=0;
    4565         122 :     if( pPcd )
    4566         122 :         pPcd->Save(  rSave.aS[n++] );
    4567         122 :     if( pPcdA )
    4568         122 :         pPcdA->Save( rSave.aS[n++] );
    4569             : 
    4570        1342 :     for(i=0; i<nPLCF; ++i)
    4571        1220 :         if( pPcd != &aD[i] && pPcdA != &aD[i] )
    4572         976 :             aD[i].Save( rSave.aS[n++] );
    4573         122 : }
    4574             : 
    4575         122 : void WW8PLCFMan::RestoreAllPLCFx( const WW8PLCFxSaveAll& rSave )
    4576             : {
    4577         122 :     sal_uInt16 i, n=0;
    4578         122 :     if( pPcd )
    4579         122 :         pPcd->Restore(  rSave.aS[n++] );
    4580         122 :     if( pPcdA )
    4581         122 :         pPcdA->Restore( rSave.aS[n++] );
    4582             : 
    4583        1342 :     for(i=0; i<nPLCF; ++i)
    4584        1220 :         if( pPcd != &aD[i] && pPcdA != &aD[i] )
    4585         976 :             aD[i].Restore( rSave.aS[n++] );
    4586         122 : }
    4587             : 
    4588       62964 : void WW8PLCFMan::GetSprmStart( short nIdx, WW8PLCFManResult* pRes ) const
    4589             : {
    4590       62964 :     memset( pRes, 0, sizeof( WW8PLCFManResult ) );
    4591             : 
    4592             :     // Pruefen !!!
    4593             : 
    4594       62964 :     pRes->nMemLen = 0;
    4595             : 
    4596       62964 :     const WW8PLCFxDesc* p = &aD[nIdx];
    4597             : 
    4598             :     // first Sprm in a Group
    4599       62964 :     if( p->bFirstSprm )
    4600             :     {
    4601       19014 :         if( p == pPap )
    4602        6688 :             pRes->nFlags |= MAN_MASK_NEW_PAP;
    4603       12326 :         else if( p == pSep )
    4604          84 :             pRes->nFlags |= MAN_MASK_NEW_SEP;
    4605             :     }
    4606       62964 :     pRes->pMemPos = p->pMemPos;
    4607       62964 :     pRes->nSprmId = GetId(p);
    4608       62964 :     pRes->nCp2OrIdx = p->nCp2OrIdx;
    4609       62964 :     if ((p == pFtn) || (p == pEdn) || (p == pAnd))
    4610           2 :         pRes->nMemLen = p->nSprmsLen;
    4611       62962 :     else if (p->nSprmsLen >= maSprmParser.MinSprmLen()) //Normal
    4612             :     {
    4613             :         // Length of actual sprm
    4614       52584 :         pRes->nMemLen = maSprmParser.GetSprmSize(pRes->nSprmId, pRes->pMemPos);
    4615             :     }
    4616       62964 : }
    4617             : 
    4618       59746 : void WW8PLCFMan::GetSprmEnd( short nIdx, WW8PLCFManResult* pRes ) const
    4619             : {
    4620       59746 :     memset( pRes, 0, sizeof( WW8PLCFManResult ) );
    4621             : 
    4622       59746 :     const WW8PLCFxDesc* p = &aD[nIdx];
    4623             : 
    4624       59746 :     if (!(p->pIdStk->empty()))
    4625       59746 :         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       59746 : }
    4632             : 
    4633        7532 : void WW8PLCFMan::GetNoSprmStart( short nIdx, WW8PLCFManResult* pRes ) const
    4634             : {
    4635        7532 :     const WW8PLCFxDesc* p = &aD[nIdx];
    4636             : 
    4637        7532 :     pRes->nCpPos = p->nStartPos;
    4638        7532 :     pRes->nMemLen = p->nSprmsLen;
    4639        7532 :     pRes->nCp2OrIdx = p->nCp2OrIdx;
    4640             : 
    4641        7532 :     if( p == pFld )
    4642           0 :         pRes->nSprmId = eFLD;
    4643        7532 :     else if( p == pFtn )
    4644           0 :         pRes->nSprmId = eFTN;
    4645        7532 :     else if( p == pEdn )
    4646           0 :         pRes->nSprmId = eEDN;
    4647        7532 :     else if( p == pBkm )
    4648          24 :         pRes->nSprmId = eBKN;
    4649        7508 :     else if( p == pAnd )
    4650           0 :         pRes->nSprmId = eAND;
    4651        7508 :     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        7508 :         GetSprmStart( nIdx+1, pRes );
    4656             :     }
    4657             :     else
    4658           0 :         pRes->nSprmId = 0;          // default: not found
    4659        7532 : }
    4660             : 
    4661        7242 : void WW8PLCFMan::GetNoSprmEnd( short nIdx, WW8PLCFManResult* pRes ) const
    4662             : {
    4663        7242 :     pRes->nMemLen = -1;     // Ende-Kennzeichen
    4664             : 
    4665        7242 :     if( &aD[nIdx] == pBkm )
    4666           0 :         pRes->nSprmId = eBKN;
    4667        7242 :     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        7242 :         GetSprmEnd( nIdx+1, pRes );
    4672             :     }
    4673             :     else
    4674           0 :         pRes->nSprmId = 0;
    4675        7242 : }
    4676             : 
    4677         156 : bool WW8PLCFMan::TransferOpenSprms(std::stack<sal_uInt16> &rStack)
    4678             : {
    4679        1470 :     for (int i = 0; i < nPLCF; ++i)
    4680             :     {
    4681        1314 :         WW8PLCFxDesc* p = &aD[i];
    4682        1314 :         if (!p || !p->pIdStk)
    4683         396 :             continue;
    4684        2526 :         while (!p->pIdStk->empty())
    4685             :         {
    4686         690 :             rStack.push(p->pIdStk->top());
    4687         690 :             p->pIdStk->pop();
    4688             :         }
    4689             :     }
    4690         156 :     return rStack.empty();
    4691             : }
    4692             : 
    4693      121390 : void WW8PLCFMan::AdvSprm(short nIdx, bool bStart)
    4694             : {
    4695      121390 :     WW8PLCFxDesc* p = &aD[nIdx];    // Sprm-Klasse(!) ermitteln
    4696             : 
    4697      121390 :     p->bFirstSprm = false;
    4698      121390 :     if( bStart )
    4699             :     {
    4700       61644 :         sal_uInt16 nLastId = GetId(p);
    4701       61644 :         p->pIdStk->push(nLastId);   // merke Id fuer Attribut-Ende
    4702             : 
    4703       61644 :         if( p->nSprmsLen )
    4704             :         {   /*
    4705             :                 Pruefe, ob noch Sprm(s) abzuarbeiten sind
    4706             :             */
    4707       51266 :             if( p->pMemPos )
    4708             :             {
    4709             :                 // Length of last sprm
    4710       51264 :                 sal_uInt16 nSprmL = maSprmParser.GetSprmSize(nLastId, p->pMemPos);
    4711             : 
    4712             :                 // Gesamtlaenge Sprms um SprmLaenge verringern
    4713       51264 :                 p->nSprmsLen -= nSprmL;
    4714             : 
    4715             :                 // Pos des evtl. naechsten Sprm
    4716       51264 :                 if (p->nSprmsLen < maSprmParser.MinSprmLen())
    4717             :                 {
    4718             :                     // sicherheitshalber auf Null setzen, da Enden folgen!
    4719        7314 :                     p->pMemPos = 0;
    4720        7314 :                     p->nSprmsLen = 0;
    4721             :                 }
    4722             :                 else
    4723       43950 :                     p->pMemPos += nSprmL;
    4724             :             }
    4725             :             else
    4726           2 :                 p->nSprmsLen = 0;
    4727             :         }
    4728       61644 :         if (p->nSprmsLen < maSprmParser.MinSprmLen())
    4729       17694 :             p->nStartPos = WW8_CP_MAX;    // es folgen Enden
    4730             :     }
    4731             :     else
    4732             :     {
    4733       59746 :         if (!(p->pIdStk->empty()))
    4734       59746 :             p->pIdStk->pop();
    4735       59746 :         if (p->pIdStk->empty())
    4736             :         {
    4737       17106 :             if ( (p == pChp) || (p == pPap) )
    4738             :             {
    4739        9746 :                 p->pMemPos = 0;
    4740        9746 :                 p->nSprmsLen = 0;
    4741        9746 :                 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        9746 :                 if (!(*p->pPLCFx).SeekPos(p->nStartPos))
    4750             :                 {
    4751          68 :                     p->nEndPos = WW8_CP_MAX;
    4752          68 :                     p->pPLCFx->SetDirty(true);
    4753             :                 }
    4754        9746 :                 if (!p->pPLCFx->GetDirty() || pPcd)
    4755        9746 :                     GetNewSprms( *p );
    4756        9746 :                 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       19492 :                 if (pPcd && ((p->nStartPos > pPcd->nStartPos) ||
    4782             :                     (pPcd->nStartPos == WW8_CP_MAX)) &&
    4783             :                     (pPcd->nEndPos != p->nStartPos))
    4784             :                 {
    4785        7348 :                     pPcd->nEndPos = p->nStartPos;
    4786             :                     ((WW8PLCFx_PCD *)(pPcd->pPLCFx))->SetClipStart(
    4787        7348 :                         p->nStartPos);
    4788             :                 }
    4789             : 
    4790             :             }
    4791             :             else
    4792             :             {
    4793        7360 :                 p->pPLCFx->advance(); // next Group of Sprms
    4794        7360 :                 p->pMemPos = 0;       // !!!
    4795        7360 :                 p->nSprmsLen = 0;
    4796        7360 :                 GetNewSprms( *p );
    4797             :             }
    4798             :             OSL_ENSURE( p->nStartPos <= p->nEndPos, "Attribut ueber Kreuz" );
    4799             :         }
    4800             :     }
    4801      121390 : }
    4802             : 
    4803       14774 : 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       14774 :     WW8PLCFxDesc* p = &aD[nIdx];
    4812             : 
    4813       14774 :     if( p == pPcd )
    4814             :     {
    4815       14750 :         AdvSprm(nIdx+1,bStart);
    4816       14750 :         if( bStart )
    4817        7508 :             p->nStartPos = aD[nIdx+1].nStartPos;
    4818             :         else
    4819             :         {
    4820        7242 :             if (aD[nIdx+1].pIdStk->empty())
    4821             :             {
    4822        7242 :                 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        7242 :                 if (pTemp->GetClipStart() == -1)
    4831           8 :                     p->pPLCFx->advance();
    4832        7242 :                 p->pMemPos = 0;
    4833        7242 :                 p->nSprmsLen = 0;
    4834        7242 :                 GetNewSprms( aD[nIdx+1] );
    4835        7242 :                 GetNewNoSprms( *p );
    4836        7242 :                 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        7234 :                     p->nStartPos = pTemp->GetClipStart();
    4845        7234 :                     pTemp->SetClipStart(-1);
    4846             :                 }
    4847             :             }
    4848             :         }
    4849             :     }
    4850             :     else
    4851             :     {                                  // NoSprm ohne Ende
    4852          24 :         p->pPLCFx->advance();
    4853          24 :         p->pMemPos = 0;                     // MemPos ungueltig
    4854          24 :         p->nSprmsLen = 0;
    4855          24 :         GetNewNoSprms( *p );
    4856             :     }
    4857       14774 : }
    4858             : 
    4859      121414 : void WW8PLCFMan::advance()
    4860             : {
    4861             :     bool bStart;
    4862      121414 :     sal_uInt16 nIdx = WhereIdx(&bStart);
    4863      121414 :     if (nIdx < nPLCF)
    4864             :     {
    4865      121414 :         WW8PLCFxDesc* p = &aD[nIdx];
    4866             : 
    4867      121414 :         p->bFirstSprm = true;                       // Default
    4868             : 
    4869      121414 :         if( p->pPLCFx->IsSprm() )
    4870      106640 :             AdvSprm( nIdx, bStart );
    4871             :         else                                        // NoSprm
    4872       14774 :             AdvNoSprm( nIdx, bStart );
    4873             :     }
    4874      121414 : }
    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      122734 : bool WW8PLCFMan::Get(WW8PLCFManResult* pRes) const
    4881             : {
    4882      122734 :     memset( pRes, 0, sizeof( WW8PLCFManResult ) );
    4883             :     bool bStart;
    4884      122734 :     sal_uInt16 nIdx = WhereIdx(&bStart);
    4885             : 
    4886      122734 :     if( nIdx >= nPLCF )
    4887             :     {
    4888             :         OSL_ENSURE( !this, "Position not found" );
    4889           0 :         return true;
    4890             :     }
    4891             : 
    4892      122734 :     if( aD[nIdx].pPLCFx->IsSprm() )
    4893             :     {
    4894      107960 :         if( bStart )
    4895             :         {
    4896       55456 :             GetSprmStart( nIdx, pRes );
    4897       55456 :             return true;
    4898             :         }
    4899             :         else
    4900             :         {
    4901       52504 :             GetSprmEnd( nIdx, pRes );
    4902       52504 :             return false;
    4903             :         }
    4904             :     }
    4905             :     else
    4906             :     {
    4907       14774 :         if( bStart )
    4908             :         {
    4909        7532 :             GetNoSprmStart( nIdx, pRes );
    4910        7532 :             return true;
    4911             :         }
    4912             :         else
    4913             :         {
    4914        7242 :             GetNoSprmEnd( nIdx, pRes );
    4915        7242 :             return false;
    4916             :         }
    4917             :     }
    4918             : }
    4919             : 
    4920       10068 : sal_uInt16 WW8PLCFMan::GetColl() const
    4921             : {
    4922       10068 :     if( pPap->pPLCFx )
    4923       10068 :         return  pPap->pPLCFx->GetIstd();
    4924             :     else
    4925             :     {
    4926             :         OSL_ENSURE( !this, "GetColl ohne PLCF_Pap" );
    4927           0 :         return 0;
    4928             :     }
    4929             : }
    4930             : 
    4931         142 : WW8PLCFx_FLD* WW8PLCFMan::GetFld() const
    4932             : {
    4933         142 :     return (WW8PLCFx_FLD*)pFld->pPLCFx;
    4934             : }
    4935             : 
    4936       26796 : const sal_uInt8* WW8PLCFMan::HasParaSprm( sal_uInt16 nId ) const
    4937             : {
    4938       26796 :     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        2752 : void WW8PLCFx::Save( WW8PLCFxSave1& rSave ) const
    4955             : {
    4956        2752 :     rSave.nPLCFxPos    = GetIdx();
    4957        2752 :     rSave.nPLCFxPos2   = GetIdx2();
    4958        2752 :     rSave.nPLCFxMemOfs = 0;
    4959        2752 :     rSave.nStartFC     = GetStartFc();
    4960        2752 : }
    4961             : 
    4962        2752 : void WW8PLCFx::Restore( const WW8PLCFxSave1& rSave )
    4963             : {
    4964        2752 :     SetIdx(     rSave.nPLCFxPos  );
    4965        2752 :     SetIdx2(    rSave.nPLCFxPos2 );
    4966        2752 :     SetStartFc( rSave.nStartFC   );
    4967        2752 : }
    4968             : 
    4969        1776 : sal_uLong WW8PLCFx_Cp_FKP::GetIdx2() const
    4970             : {
    4971        1776 :     return GetPCDIdx();
    4972             : }
    4973             : 
    4974        1776 : void WW8PLCFx_Cp_FKP::SetIdx2( sal_uLong nIdx )
    4975             : {
    4976        1776 :     SetPCDIdx( nIdx );
    4977        1776 : }
    4978             : 
    4979        1776 : void WW8PLCFx_Cp_FKP::Save( WW8PLCFxSave1& rSave ) const
    4980             : {
    4981        1776 :     WW8PLCFx::Save( rSave );
    4982             : 
    4983        1776 :     rSave.nAttrStart = nAttrStart;
    4984        1776 :     rSave.nAttrEnd   = nAttrEnd;
    4985        1776 :     rSave.bLineEnd   = bLineEnd;
    4986        1776 : }
    4987             : 
    4988        1776 : void WW8PLCFx_Cp_FKP::Restore( const WW8PLCFxSave1& rSave )
    4989             : {
    4990        1776 :     WW8PLCFx::Restore( rSave );
    4991             : 
    4992        1776 :     nAttrStart = rSave.nAttrStart;
    4993        1776 :     nAttrEnd   = rSave.nAttrEnd;
    4994        1776 :     bLineEnd   = rSave.bLineEnd;
    4995        1776 : }
    4996             : 
    4997        2752 : void WW8PLCFxDesc::Save( WW8PLCFxSave1& rSave ) const
    4998             : {
    4999        2752 :     if( pPLCFx )
    5000             :     {
    5001        2752 :         pPLCFx->Save( rSave );
    5002        2752 :         if( pPLCFx->IsSprm() )
    5003             :         {
    5004        2508 :             WW8PLCFxDesc aD;
    5005        2508 :             aD.nStartPos = nOrigStartPos+nCpOfs;
    5006        2508 :             aD.nCpOfs = rSave.nCpOfs = nCpOfs;
    5007        2508 :             if (!(pPLCFx->SeekPos(aD.nStartPos)))
    5008             :             {
    5009         466 :                 aD.nEndPos = WW8_CP_MAX;
    5010         466 :                 pPLCFx->SetDirty(true);
    5011             :             }
    5012        2508 :             pPLCFx->GetSprms(&aD);
    5013        2508 :             pPLCFx->SetDirty(false);
    5014        2508 :             aD.ReduceByOffset();
    5015        2508 :             rSave.nStartCp = aD.nStartPos;
    5016        2508 :             rSave.nPLCFxMemOfs = nOrigSprmsLen - nSprmsLen;
    5017             :         }
    5018             :     }
    5019        2752 : }
    5020             : 
    5021        2752 : void WW8PLCFxDesc::Restore( const WW8PLCFxSave1& rSave )
    5022             : {
    5023        2752 :     if( pPLCFx )
    5024             :     {
    5025        2752 :         pPLCFx->Restore( rSave );
    5026        2752 :         if( pPLCFx->IsSprm() )
    5027             :         {
    5028        2508 :             WW8PLCFxDesc aD;
    5029        2508 :             aD.nStartPos = rSave.nStartCp+rSave.nCpOfs;
    5030        2508 :             nCpOfs = aD.nCpOfs = rSave.nCpOfs;
    5031        2508 :             if (!(pPLCFx->SeekPos(aD.nStartPos)))
    5032             :             {
    5033         466 :                 aD.nEndPos = WW8_CP_MAX;
    5034         466 :                 pPLCFx->SetDirty(true);
    5035             :             }
    5036        2508 :             pPLCFx->GetSprms(&aD);
    5037        2508 :             pPLCFx->SetDirty(false);
    5038        2508 :             aD.ReduceByOffset();
    5039        2508 :             pMemPos = aD.pMemPos + rSave.nPLCFxMemOfs;
    5040             :         }
    5041             :     }
    5042        2752 : }
    5043             : 
    5044             : //-----------------------------------------
    5045             : 
    5046             : namespace
    5047             : {
    5048        2812 :     sal_uInt32 Readcb(SvStream& rSt, ww::WordVersion eVer)
    5049             :     {
    5050        2812 :         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        2812 :             rSt >> nLong;
    5060        2812 :             return nLong;
    5061             :         }
    5062             :     }
    5063             : }
    5064             : 
    5065         494 : WW8_CP WW8Fib::GetBaseCp(ManTypes nType) const
    5066             : {
    5067         494 :     WW8_CP nOffset = 0;
    5068             : 
    5069         494 :     switch( nType )
    5070             :     {
    5071             :         default:
    5072             :         case MAN_MAINTEXT:
    5073          74 :             break;
    5074             :         case MAN_FTN:
    5075           2 :             nOffset = ccpText;
    5076           2 :             break;
    5077             :         case MAN_HDFT:
    5078          76 :             nOffset = ccpText + ccpFtn;
    5079          76 :             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         338 :             nOffset = ccpText + ccpFtn + ccpHdr + ccpMcr + ccpAtn + ccpEdn;
    5098         338 :             break;
    5099             :         case MAN_TXBX_HDFT:
    5100             :             nOffset = ccpText + ccpFtn + ccpHdr + ccpMcr + ccpAtn + ccpEdn +
    5101           4 :                 ccpTxbx;
    5102           4 :             break;
    5103             :     }
    5104         494 :     return nOffset;
    5105             : }
    5106             : 
    5107      146248 : ww::WordVersion WW8Fib::GetFIBVersion() const
    5108             : {
    5109      146248 :     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      146248 :     if (wIdent == 0xa5db)
    5127           0 :         eVer = ww::eWW2;
    5128             :     else
    5129             :     {
    5130      146248 :         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      146248 :                 eVer = ww::eWW8;
    5140      146248 :                 break;
    5141             :         }
    5142             :     }
    5143      146248 :     return eVer;
    5144             : }
    5145             : 
    5146          74 : WW8Fib::WW8Fib(SvStream& rSt, sal_uInt8 nWantedVersion, sal_uInt32 nOffset)
    5147          74 :     : nFibError( 0 )
    5148             : {
    5149          74 :     memset(this, 0, sizeof(*this));
    5150             :     sal_uInt8 aBits1;
    5151             :     sal_uInt8 aBits2;
    5152             :     sal_uInt8 aVer8Bits1;    // nur ab WinWord 8 benutzt
    5153          74 :     rSt.Seek( nOffset );
    5154             :     /*
    5155             :         Wunsch-Nr vermerken, File-Versionsnummer ermitteln
    5156             :         und gegen Wunsch-Nr. checken !
    5157             :     */
    5158          74 :     nVersion = nWantedVersion;
    5159          74 :     rSt >> wIdent;
    5160          74 :     rSt >> nFib;
    5161          74 :     rSt >> nProduct;
    5162          74 :     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          74 :             return;                         // und hopp raus!
    5195             :         }
    5196             :     }
    5197             : 
    5198          74 :     ww::WordVersion eVer = GetFIBVersion();
    5199             : 
    5200             :     // Hilfs-Varis fuer Ver67:
    5201          74 :     sal_Int16 pnChpFirst_Ver67=0;
    5202          74 :     sal_Int16 pnPapFirst_Ver67=0;
    5203          74 :     sal_Int16 cpnBteChp_Ver67=0;
    5204          74 :     sal_Int16 cpnBtePap_Ver67=0;
    5205             : 
    5206             :     // und auf gehts: FIB einlesen
    5207          74 :     rSt >> lid;
    5208          74 :     rSt >> pnNext;
    5209          74 :     rSt >> aBits1;
    5210          74 :     rSt >> aBits2;
    5211          74 :     rSt >> nFibBack;
    5212          74 :     rSt >> nHash;
    5213          74 :     rSt >> nKey;
    5214          74 :     rSt >> envr;
    5215          74 :     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          74 :     rSt >> chse;
    5225          74 :     rSt >> chseTables;
    5226          74 :     rSt >> fcMin;
    5227          74 :     rSt >> fcMac;
    5228             : 
    5229             : // Einschub fuer WW8 *****************************************************
    5230          74 :     if (IsEightPlus(eVer))
    5231             :     {
    5232          74 :         rSt >> csw;
    5233             : 
    5234             :         // Marke: "rgsw"  Beginning of the array of shorts
    5235          74 :         rSt >> wMagicCreated;
    5236          74 :         rSt >> wMagicRevised;
    5237          74 :         rSt >> wMagicCreatedPrivate;
    5238          74 :         rSt >> wMagicRevisedPrivate;
    5239          74 :         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          74 :         rSt >> lidFE;
    5254          74 :         rSt >> clw;
    5255             :     }
    5256             : 
    5257             : // Ende des Einschubs fuer WW8 *******************************************
    5258             : 
    5259             :         // Marke: "rglw"  Beginning of the array of longs
    5260          74 :     rSt >> cbMac;
    5261             : 
    5262             :         // 2 Longs uebergehen, da unwichtiger Quatsch
    5263          74 :     rSt.SeekRel( 2 * sizeof( sal_Int32) );
    5264             : 
    5265             :         // weitere 2 Longs nur bei Ver67 ueberspringen
    5266          74 :     if (IsSevenMinus(eVer))
    5267           0 :         rSt.SeekRel( 2 * sizeof( sal_Int32) );
    5268             : 
    5269          74 :     rSt >> ccpText;
    5270          74 :     rSt >> ccpFtn;
    5271          74 :     rSt >> ccpHdr;
    5272          74 :     rSt >> ccpMcr;
    5273          74 :     rSt >> ccpAtn;
    5274          74 :     rSt >> ccpEdn;
    5275          74 :     rSt >> ccpTxbx;
    5276          74 :     rSt >> ccpHdrTxbx;
    5277             : 
    5278             :         // weiteres Long nur bei Ver67 ueberspringen
    5279          74 :     if (IsSevenMinus(eVer))
    5280           0 :         rSt.SeekRel( 1 * sizeof( sal_Int32) );
    5281             :     else
    5282             :     {
    5283             : // Einschub fuer WW8 *****************************************************
    5284          74 :         rSt >> pnFbpChpFirst;
    5285          74 :         rSt >> pnChpFirst;
    5286          74 :         rSt >> cpnBteChp;
    5287          74 :         rSt >> pnFbpPapFirst;
    5288          74 :         rSt >> pnPapFirst;
    5289          74 :         rSt >> cpnBtePap;
    5290          74 :         rSt >> pnFbpLvcFirst;
    5291          74 :         rSt >> pnLvcFirst;
    5292          74 :         rSt >> cpnBteLvc;
    5293          74 :         rSt >> fcIslandFirst;
    5294          74 :         rSt >> fcIslandLim;
    5295          74 :         rSt >> cfclcb;
    5296             :     }
    5297             : 
    5298             : // Ende des Einschubs fuer WW8 *******************************************
    5299             : 
    5300             :     // Marke: "rgfclcb" Beginning of array of FC/LCB pairs.
    5301          74 :     rSt >> fcStshfOrig;
    5302          74 :     lcbStshfOrig = Readcb(rSt, eVer);
    5303          74 :     rSt >> fcStshf;
    5304          74 :     lcbStshf = Readcb(rSt, eVer);
    5305          74 :     rSt >> fcPlcffndRef;
    5306          74 :     lcbPlcffndRef = Readcb(rSt, eVer);
    5307          74 :     rSt >> fcPlcffndTxt;
    5308          74 :     lcbPlcffndTxt = Readcb(rSt, eVer);
    5309          74 :     rSt >> fcPlcfandRef;
    5310          74 :     lcbPlcfandRef = Readcb(rSt, eVer);
    5311          74 :     rSt >> fcPlcfandTxt;
    5312          74 :     lcbPlcfandTxt = Readcb(rSt, eVer);
    5313          74 :     rSt >> fcPlcfsed;
    5314          74 :     lcbPlcfsed = Readcb(rSt, eVer);
    5315          74 :     rSt >> fcPlcfpad;
    5316          74 :     lcbPlcfpad = Readcb(rSt, eVer);
    5317          74 :     rSt >> fcPlcfphe;
    5318          74 :     lcbPlcfphe = Readcb(rSt, eVer);
    5319          74 :     rSt >> fcSttbfglsy;
    5320          74 :     lcbSttbfglsy = Readcb(rSt, eVer);
    5321          74 :     rSt >> fcPlcfglsy;
    5322          74 :     lcbPlcfglsy = Readcb(rSt, eVer);
    5323          74 :     rSt >> fcPlcfhdd;
    5324          74 :     lcbPlcfhdd = Readcb(rSt, eVer);
    5325          74 :     rSt >> fcPlcfbteChpx;
    5326          74 :     lcbPlcfbteChpx = Readcb(rSt, eVer);
    5327          74 :     rSt >> fcPlcfbtePapx;
    5328          74 :     lcbPlcfbtePapx = Readcb(rSt, eVer);
    5329          74 :     rSt >> fcPlcfsea;
    5330          74 :     lcbPlcfsea = Readcb(rSt, eVer);
    5331          74 :     rSt >> fcSttbfffn;
    5332          74 :     lcbSttbfffn = Readcb(rSt, eVer);
    5333          74 :     rSt >> fcPlcffldMom;
    5334          74 :     lcbPlcffldMom = Readcb(rSt, eVer);
    5335          74 :     rSt >> fcPlcffldHdr;
    5336          74 :     lcbPlcffldHdr = Readcb(rSt, eVer);
    5337          74 :     rSt >> fcPlcffldFtn;
    5338          74 :     lcbPlcffldFtn = Readcb(rSt, eVer);
    5339          74 :     rSt >> fcPlcffldAtn;
    5340          74 :     lcbPlcffldAtn = Readcb(rSt, eVer);
    5341          74 :     rSt >> fcPlcffldMcr;
    5342          74 :     lcbPlcffldMcr = Readcb(rSt, eVer);
    5343          74 :     rSt >> fcSttbfbkmk;
    5344          74 :     lcbSttbfbkmk = Readcb(rSt, eVer);
    5345          74 :     rSt >> fcPlcfbkf;
    5346          74 :     lcbPlcfbkf = Readcb(rSt, eVer);
    5347          74 :     rSt >> fcPlcfbkl;
    5348          74 :     lcbPlcfbkl = Readcb(rSt, eVer);
    5349          74 :     rSt >> fcCmds;
    5350          74 :     lcbCmds = Readcb(rSt, eVer);
    5351          74 :     rSt >> fcPlcfmcr;
    5352          74 :     lcbPlcfmcr = Readcb(rSt, eVer);
    5353          74 :     rSt >> fcSttbfmcr;
    5354          74 :     lcbSttbfmcr = Readcb(rSt, eVer);
    5355          74 :     rSt >> fcPrDrvr;
    5356          74 :     lcbPrDrvr = Readcb(rSt, eVer);
    5357          74 :     rSt >> fcPrEnvPort;
    5358          74 :     lcbPrEnvPort = Readcb(rSt, eVer);
    5359          74 :     rSt >> fcPrEnvLand;
    5360          74 :     lcbPrEnvLand = Readcb(rSt, eVer);
    5361          74 :     rSt >> fcWss;
    5362          74 :     lcbWss = Readcb(rSt, eVer);
    5363          74 :     rSt >> fcDop;
    5364          74 :     lcbDop = Readcb(rSt, eVer);
    5365          74 :     rSt >> fcSttbfAssoc;
    5366          74 :     lcbSttbfAssoc = Readcb(rSt, eVer);
    5367          74 :     rSt >> fcClx;
    5368          74 :     lcbClx = Readcb(rSt, eVer);
    5369          74 :     rSt >> fcPlcfpgdFtn;
    5370          74 :     lcbPlcfpgdFtn = Readcb(rSt, eVer);
    5371          74 :     rSt >> fcAutosaveSource;
    5372          74 :     lcbAutosaveSource = Readcb(rSt, eVer);
    5373          74 :     rSt >> fcGrpStAtnOwners;
    5374          74 :     lcbGrpStAtnOwners = Readcb(rSt, eVer);
    5375          74 :     rSt >> fcSttbfAtnbkmk;
    5376          74 :     lcbSttbfAtnbkmk = Readcb(rSt, eVer);
    5377             : 
    5378             :     // weiteres short nur bei Ver67 ueberspringen
    5379          74 :     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          74 :     if (eVer > ww::eWW2)
    5391             :     {
    5392          74 :         rSt >> fcPlcfdoaMom;
    5393          74 :         rSt >> lcbPlcfdoaMom;
    5394          74 :         rSt >> fcPlcfdoaHdr;
    5395          74 :         rSt >> lcbPlcfdoaHdr;
    5396          74 :         rSt >> fcPlcfspaMom;
    5397          74 :         rSt >> lcbPlcfspaMom;
    5398          74 :         rSt >> fcPlcfspaHdr;
    5399          74 :         rSt >> lcbPlcfspaHdr;
    5400             : 
    5401          74 :         rSt >> fcPlcfAtnbkf;
    5402          74 :         rSt >> lcbPlcfAtnbkf;
    5403          74 :         rSt >> fcPlcfAtnbkl;
    5404          74 :         rSt >> lcbPlcfAtnbkl;
    5405          74 :         rSt >> fcPms;
    5406          74 :         rSt >> lcbPMS;
    5407          74 :         rSt >> fcFormFldSttbf;
    5408          74 :         rSt >> lcbFormFldSttbf;
    5409          74 :         rSt >> fcPlcfendRef;
    5410          74 :         rSt >> lcbPlcfendRef;
    5411          74 :         rSt >> fcPlcfendTxt;
    5412          74 :         rSt >> lcbPlcfendTxt;
    5413          74 :         rSt >> fcPlcffldEdn;
    5414          74 :         rSt >> lcbPlcffldEdn;
    5415          74 :         rSt >> fcPlcfpgdEdn;
    5416          74 :         rSt >> lcbPlcfpgdEdn;
    5417          74 :         rSt >> fcDggInfo;
    5418          74 :         rSt >> lcbDggInfo;
    5419          74 :         rSt >> fcSttbfRMark;
    5420          74 :         rSt >> lcbSttbfRMark;
    5421          74 :         rSt >> fcSttbfCaption;
    5422          74 :         rSt >> lcbSttbfCaption;
    5423          74 :         rSt >> fcSttbAutoCaption;
    5424          74 :         rSt >> lcbSttbAutoCaption;
    5425          74 :         rSt >> fcPlcfwkb;
    5426          74 :         rSt >> lcbPlcfwkb;
    5427          74 :         rSt >> fcPlcfspl;
    5428          74 :         rSt >> lcbPlcfspl;
    5429          74 :         rSt >> fcPlcftxbxTxt;
    5430          74 :         rSt >> lcbPlcftxbxTxt;
    5431          74 :         rSt >> fcPlcffldTxbx;
    5432          74 :         rSt >> lcbPlcffldTxbx;
    5433          74 :         rSt >> fcPlcfHdrtxbxTxt;
    5434          74 :         rSt >> lcbPlcfHdrtxbxTxt;
    5435          74 :         rSt >> fcPlcffldHdrTxbx;
    5436          74 :         rSt >> lcbPlcffldHdrTxbx;
    5437          74 :         rSt >> fcStwUser;
    5438          74 :         rSt >> lcbStwUser;
    5439          74 :         rSt >> fcSttbttmbd;
    5440          74 :         rSt >> lcbSttbttmbd;
    5441             :     }
    5442             : 
    5443          74 :     if( 0 == rSt.GetError() )
    5444             :     {
    5445             :         // Bit-Flags setzen
    5446          74 :         fDot        =   aBits1 & 0x01       ;
    5447          74 :         fGlsy       = ( aBits1 & 0x02 ) >> 1;
    5448          74 :         fComplex    = ( aBits1 & 0x04 ) >> 2;
    5449          74 :         fHasPic     = ( aBits1 & 0x08 ) >> 3;
    5450          74 :         cQuickSaves = ( aBits1 & 0xf0 ) >> 4;
    5451          74 :         fEncrypted  =   aBits2 & 0x01       ;
    5452          74 :         fWhichTblStm= ( aBits2 & 0x02 ) >> 1;
    5453          74 :         fReadOnlyRecommended = (aBits2 & 0x4) >> 2;
    5454          74 :         fWriteReservation = (aBits2 & 0x8) >> 3;
    5455          74 :         fExtChar    = ( aBits2 & 0x10 ) >> 4;
    5456             :         // dummy    = ( aBits2 & 0x20 ) >> 5;
    5457          74 :         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          74 :         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          74 :         else if (IsEightPlus(eVer))
    5472             :         {
    5473          74 :           fMac              =   aVer8Bits1  & 0x01           ;
    5474          74 :           fEmptySpecial     = ( aVer8Bits1  & 0x02 ) >> 1;
    5475          74 :           fLoadOverridePage = ( aVer8Bits1  & 0x04 ) >> 2;
    5476          74 :           fFuturesavedUndo  = ( aVer8Bits1  & 0x08 ) >> 3;
    5477          74 :           fWord97Saved      = ( aVer8Bits1  & 0x10 ) >> 4;
    5478          74 :           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          74 :             long nOldPos = rSt.Tell();
    5486             : 
    5487          74 :             rSt.Seek( 0x02da );
    5488          74 :             rSt >> fcSttbFnm;
    5489          74 :             rSt >> lcbSttbFnm;
    5490          74 :             rSt >> fcPlcfLst;
    5491          74 :             rSt >> lcbPlcfLst;
    5492          74 :             rSt >> fcPlfLfo;
    5493          74 :             rSt >> lcbPlfLfo;
    5494          74 :             rSt >> fcPlcftxbxBkd;
    5495          74 :             rSt >> lcbPlcftxbxBkd;
    5496          74 :             rSt >> fcPlcfHdrtxbxBkd;
    5497          74 :             rSt >> lcbPlcfHdrtxbxBkd;
    5498          74 :             if( 0 != rSt.GetError() )
    5499             :             {
    5500           0 :                 nFibError = ERR_SWG_READ_ERROR;
    5501             :             }
    5502             : 
    5503          74 :             rSt.Seek( 0x372 );          // fcSttbListNames
    5504          74 :             rSt >> fcSttbListNames;
    5505          74 :             rSt >> lcbSttbListNames;
    5506             : 
    5507          74 :             if (cfclcb > 93)
    5508             :             {
    5509          68 :                 rSt.Seek( 0x382 );          // MagicTables
    5510          68 :                 rSt >> fcPlcfTch;
    5511          68 :                 rSt >> lcbPlcfTch;
    5512             :             }
    5513             : 
    5514          74 :             if (cfclcb > 113)
    5515             :             {
    5516          48 :                 rSt.Seek( 0x41A );          // new ATRD
    5517          48 :                 rSt >> fcAtrdExtra;
    5518          48 :                 rSt >> lcbAtrdExtra;
    5519             :             }
    5520             : 
    5521          74 :             if( 0 != rSt.GetError() )
    5522           0 :                 nFibError = ERR_SWG_READ_ERROR;
    5523             : 
    5524          74 :             rSt.Seek( 0x5bc );          // Actual nFib introduced in Word 2003
    5525          74 :             rSt >> nFib_actual;
    5526             : 
    5527          74 :             rSt.Seek( nOldPos );
    5528             :         }
    5529             :     }
    5530             :     else
    5531             :     {
    5532           0 :         nFibError = ERR_SWG_READ_ERROR;     // Error melden
    5533             :     }
    5534             : }
    5535             : 
    5536             : 
    5537           8 : WW8Fib::WW8Fib(sal_uInt8 nVer)
    5538             : {
    5539           8 :     memset(this, 0, sizeof(*this));
    5540           8 :     nVersion = nVer;
    5541           8 :     if (8 == nVer)
    5542             :     {
    5543           8 :         fcMin = 0x800;
    5544           8 :         wIdent = 0xa5ec;
    5545           8 :         nFib = 0x0101;
    5546           8 :         nFibBack = 0xbf;
    5547           8 :         nProduct = 0x204D;
    5548             : 
    5549           8 :         csw = 0x0e;     // muss das sein ???
    5550           8 :         cfclcb = 0x88;  //      -""-
    5551           8 :         clw = 0x16;     //      -""-
    5552           8 :         pnFbpChpFirst = pnFbpPapFirst = pnFbpLvcFirst = 0x000fffff;
    5553           8 :         fExtChar = true;
    5554           8 :         fWord97Saved = fWord2000Saved = true;
    5555             : 
    5556           8 :         wMagicCreated = 0x6143;
    5557           8 :         wMagicRevised = 0x6C6F;
    5558           8 :         wMagicCreatedPrivate = 0x6E61;
    5559           8 :         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           8 :     cQuickSaves = nFib >= 0x00D9 ? 0xF : 0;
    5571             : 
    5572             :     // --> #i90932#
    5573           8 :     lid = 0x409; // LANGUAGE_ENGLISH_US
    5574             : 
    5575           8 :     LanguageType nLang = Application::GetSettings().GetLanguageTag().getLanguageType();
    5576           8 :     fFarEast = MsLangId::isCJK(nLang);
    5577           8 :     if (fFarEast)
    5578           0 :         lidFE = nLang;
    5579             :     else
    5580           8 :         lidFE = lid;
    5581             : 
    5582           8 :     LanguageTag aLanguageTag( lid );
    5583           8 :     LocaleDataWrapper aLocaleWrapper( aLanguageTag );
    5584           8 :     nNumDecimalSep = aLocaleWrapper.getNumDecimalSep()[0];
    5585           8 : }
    5586             : 
    5587           0 : sal_Unicode WW8Fib::getNumDecimalSep() const
    5588             : {
    5589           0 :     return nNumDecimalSep;
    5590             : }
    5591             : 
    5592           8 : bool WW8Fib::WriteHeader(SvStream& rStrm)
    5593             : {
    5594           8 :     bool bVer8 = 8 == nVersion;
    5595             : 
    5596           8 :     size_t nUnencryptedHdr = bVer8 ? 0x44 : 0x24;
    5597           8 :     sal_uInt8 *pDataPtr = new sal_uInt8[ nUnencryptedHdr ];
    5598           8 :     sal_uInt8 *pData = pDataPtr;
    5599           8 :     memset( pData, 0, nUnencryptedHdr );
    5600             : 
    5601           8 :     sal_uLong nPos = rStrm.Tell();
    5602           8 :     cbMac = rStrm.Seek( STREAM_SEEK_TO_END );
    5603           8 :     rStrm.Seek( nPos );
    5604             : 
    5605           8 :     Set_UInt16( pData, wIdent );
    5606           8 :     Set_UInt16( pData, nFib );
    5607           8 :     Set_UInt16( pData, nProduct );
    5608           8 :     Set_UInt16( pData, lid );
    5609           8 :     Set_UInt16( pData, pnNext );
    5610             : 
    5611           8 :     sal_uInt16 nBits16 = 0;
    5612           8 :     if( fDot )          nBits16 |= 0x0001;
    5613           8 :     if( fGlsy)          nBits16 |= 0x0002;
    5614           8 :     if( fComplex )      nBits16 |= 0x0004;
    5615           8 :     if( fHasPic )       nBits16 |= 0x0008;
    5616           8 :     nBits16 |= (0xf0 & ( cQuickSaves << 4 ));
    5617           8 :     if( fEncrypted )    nBits16 |= 0x0100;
    5618           8 :     if( fWhichTblStm )  nBits16 |= 0x0200;
    5619             : 
    5620           8 :     if (fReadOnlyRecommended)
    5621           0 :         nBits16 |= 0x0400;
    5622           8 :     if (fWriteReservation)
    5623           0 :         nBits16 |= 0x0800;
    5624             : 
    5625           8 :     if( fExtChar )      nBits16 |= 0x1000;
    5626           8 :     if( fFarEast )      nBits16 |= 0x4000;  // #i90932#
    5627           8 :     if( fObfuscated )   nBits16 |= 0x8000;
    5628           8 :     Set_UInt16( pData, nBits16 );
    5629             : 
    5630           8 :     Set_UInt16( pData, nFibBack );
    5631           8 :     Set_UInt16( pData, nHash );
    5632           8 :     Set_UInt16( pData, nKey );
    5633           8 :     Set_UInt8( pData, envr );
    5634             : 
    5635           8 :     sal_uInt8 nBits8 = 0;
    5636           8 :     if( bVer8 )
    5637             :     {
    5638           8 :         if( fMac )                  nBits8 |= 0x0001;
    5639           8 :         if( fEmptySpecial )         nBits8 |= 0x0002;
    5640           8 :         if( fLoadOverridePage )     nBits8 |= 0x0004;
    5641           8 :         if( fFuturesavedUndo )      nBits8 |= 0x0008;
    5642           8 :         if( fWord97Saved )          nBits8 |= 0x0010;
    5643           8 :         if( fWord2000Saved )        nBits8 |= 0x0020;
    5644             :     }
    5645             :     // unter Ver67 these are only reserved
    5646           8 :     Set_UInt8( pData, nBits8  );
    5647             : 
    5648           8 :     Set_UInt16( pData, chse );
    5649           8 :     Set_UInt16( pData, chseTables );
    5650           8 :     Set_UInt32( pData, fcMin );
    5651           8 :     Set_UInt32( pData, fcMac );
    5652             : 
    5653             : // Einschub fuer WW8 *****************************************************
    5654             : 
    5655             :     // Marke: "rgsw"  Beginning of the array of shorts
    5656           8 :     if( bVer8 )
    5657             :     {
    5658           8 :         Set_UInt16( pData, csw );
    5659           8 :         Set_UInt16( pData, wMagicCreated );
    5660           8 :         Set_UInt16( pData, wMagicRevised );
    5661           8 :         Set_UInt16( pData, wMagicCreatedPrivate );
    5662           8 :         Set_UInt16( pData, wMagicRevisedPrivate );
    5663           8 :         pData += 9 * sizeof( sal_Int16 );
    5664           8 :         Set_UInt16( pData, lidFE );
    5665           8 :         Set_UInt16( pData, clw );
    5666             :     }
    5667             : 
    5668             : // Ende des Einschubs fuer WW8 *******************************************
    5669             : 
    5670             :     // Marke: "rglw"  Beginning of the array of longs
    5671           8 :     Set_UInt32( pData, cbMac );
    5672             : 
    5673           8 :     rStrm.Write( pDataPtr, nUnencryptedHdr );
    5674           8 :     delete[] pDataPtr;
    5675           8 :     return 0 == rStrm.GetError();
    5676             : }
    5677             : 
    5678           8 : bool WW8Fib::Write(SvStream& rStrm)
    5679             : {
    5680           8 :     bool bVer8 = 8 == nVersion;
    5681             : 
    5682           8 :     WriteHeader( rStrm );
    5683             : 
    5684           8 :     size_t nUnencryptedHdr = bVer8 ? 0x44 : 0x24;
    5685             : 
    5686           8 :     sal_uInt8 *pDataPtr = new sal_uInt8[ fcMin - nUnencryptedHdr ];
    5687           8 :     sal_uInt8 *pData = pDataPtr;
    5688           8 :     memset( pData, 0, fcMin - nUnencryptedHdr );
    5689             : 
    5690           8 :     sal_uLong nPos = rStrm.Tell();
    5691           8 :     cbMac = rStrm.Seek( STREAM_SEEK_TO_END );
    5692           8 :     rStrm.Seek( nPos );
    5693             : 
    5694             :     // 2 Longs uebergehen, da unwichtiger Quatsch
    5695           8 :     pData += 2 * sizeof( sal_Int32);
    5696             : 
    5697             :     // weitere 2 Longs nur bei Ver67 ueberspringen
    5698           8 :     if( !bVer8 )
    5699           0 :         pData += 2 * sizeof( sal_Int32);
    5700             : 
    5701           8 :     Set_UInt32( pData, ccpText );
    5702           8 :     Set_UInt32( pData, ccpFtn );
    5703           8 :     Set_UInt32( pData, ccpHdr );
    5704           8 :     Set_UInt32( pData, ccpMcr );
    5705           8 :     Set_UInt32( pData, ccpAtn );
    5706           8 :     Set_UInt32( pData, ccpEdn );
    5707           8 :     Set_UInt32( pData, ccpTxbx );
    5708           8 :     Set_UInt32( pData, ccpHdrTxbx );
    5709             : 
    5710             :         // weiteres Long nur bei Ver67 ueberspringen
    5711           8 :     if( !bVer8 )
    5712           0 :         pData += 1 * sizeof( sal_Int32);
    5713             : 
    5714             : // Einschub fuer WW8 *****************************************************
    5715           8 :     if( bVer8 )
    5716             :     {
    5717           8 :         Set_UInt32( pData, pnFbpChpFirst );
    5718           8 :         Set_UInt32( pData, pnChpFirst );
    5719           8 :         Set_UInt32( pData, cpnBteChp );
    5720           8 :         Set_UInt32( pData, pnFbpPapFirst );
    5721           8 :         Set_UInt32( pData, pnPapFirst );
    5722           8 :         Set_UInt32( pData, cpnBtePap );
    5723           8 :         Set_UInt32( pData, pnFbpLvcFirst );
    5724           8 :         Set_UInt32( pData, pnLvcFirst );
    5725           8 :         Set_UInt32( pData, cpnBteLvc );
    5726           8 :         Set_UInt32( pData, fcIslandFirst );
    5727           8 :         Set_UInt32( pData, fcIslandLim );
    5728           8 :         Set_UInt16( pData, cfclcb );
    5729             :     }
    5730             : // Ende des Einschubs fuer WW8 *******************************************
    5731             : 
    5732             :     // Marke: "rgfclcb" Beginning of array of FC/LCB pairs.
    5733           8 :     Set_UInt32( pData, fcStshfOrig );
    5734           8 :     Set_UInt32( pData, lcbStshfOrig );
    5735           8 :     Set_UInt32( pData, fcStshf );
    5736           8 :     Set_UInt32( pData, lcbStshf );
    5737           8 :     Set_UInt32( pData, fcPlcffndRef );
    5738           8 :     Set_UInt32( pData, lcbPlcffndRef );
    5739           8 :     Set_UInt32( pData, fcPlcffndTxt );
    5740           8 :     Set_UInt32( pData, lcbPlcffndTxt );
    5741           8 :     Set_UInt32( pData, fcPlcfandRef );
    5742           8 :     Set_UInt32( pData, lcbPlcfandRef );
    5743           8 :     Set_UInt32( pData, fcPlcfandTxt );
    5744           8 :     Set_UInt32( pData, lcbPlcfandTxt );
    5745           8 :     Set_UInt32( pData, fcPlcfsed );
    5746           8 :     Set_UInt32( pData, lcbPlcfsed );
    5747           8 :     Set_UInt32( pData, fcPlcfpad );
    5748           8 :     Set_UInt32( pData, lcbPlcfpad );
    5749           8 :     Set_UInt32( pData, fcPlcfphe );
    5750           8 :     Set_UInt32( pData, lcbPlcfphe );
    5751           8 :     Set_UInt32( pData, fcSttbfglsy );
    5752           8 :     Set_UInt32( pData, lcbSttbfglsy );
    5753           8 :     Set_UInt32( pData, fcPlcfglsy );
    5754           8 :     Set_UInt32( pData, lcbPlcfglsy );
    5755           8 :     Set_UInt32( pData, fcPlcfhdd );
    5756           8 :     Set_UInt32( pData, lcbPlcfhdd );
    5757           8 :     Set_UInt32( pData, fcPlcfbteChpx );
    5758           8 :     Set_UInt32( pData, lcbPlcfbteChpx );
    5759           8 :     Set_UInt32( pData, fcPlcfbtePapx );
    5760           8 :     Set_UInt32( pData, lcbPlcfbtePapx );
    5761           8 :     Set_UInt32( pData, fcPlcfsea );
    5762           8 :     Set_UInt32( pData, lcbPlcfsea );
    5763           8 :     Set_UInt32( pData, fcSttbfffn );
    5764           8 :     Set_UInt32( pData, lcbSttbfffn );
    5765           8 :     Set_UInt32( pData, fcPlcffldMom );
    5766           8 :     Set_UInt32( pData, lcbPlcffldMom );
    5767           8 :     Set_UInt32( pData, fcPlcffldHdr );
    5768           8 :     Set_UInt32( pData, lcbPlcffldHdr );
    5769           8 :     Set_UInt32( pData, fcPlcffldFtn );
    5770           8 :     Set_UInt32( pData, lcbPlcffldFtn );
    5771           8 :     Set_UInt32( pData, fcPlcffldAtn );
    5772           8 :     Set_UInt32( pData, lcbPlcffldAtn );
    5773           8 :     Set_UInt32( pData, fcPlcffldMcr );
    5774           8 :     Set_UInt32( pData, lcbPlcffldMcr );
    5775           8 :     Set_UInt32( pData, fcSttbfbkmk );
    5776           8 :     Set_UInt32( pData, lcbSttbfbkmk );
    5777           8 :     Set_UInt32( pData, fcPlcfbkf );
    5778           8 :     Set_UInt32( pData, lcbPlcfbkf );
    5779           8 :     Set_UInt32( pData, fcPlcfbkl );
    5780           8 :     Set_UInt32( pData, lcbPlcfbkl );
    5781           8 :     Set_UInt32( pData, fcCmds );
    5782           8 :     Set_UInt32( pData, lcbCmds );
    5783           8 :     Set_UInt32( pData, fcPlcfmcr );
    5784           8 :     Set_UInt32( pData, lcbPlcfmcr );
    5785           8 :     Set_UInt32( pData, fcSttbfmcr );
    5786           8 :     Set_UInt32( pData, lcbSttbfmcr );
    5787           8 :     Set_UInt32( pData, fcPrDrvr );
    5788           8 :     Set_UInt32( pData, lcbPrDrvr );
    5789           8 :     Set_UInt32( pData, fcPrEnvPort );
    5790           8 :     Set_UInt32( pData, lcbPrEnvPort );
    5791           8 :     Set_UInt32( pData, fcPrEnvLand );
    5792           8 :     Set_UInt32( pData, lcbPrEnvLand );
    5793           8 :     Set_UInt32( pData, fcWss );
    5794           8 :     Set_UInt32( pData, lcbWss );
    5795           8 :     Set_UInt32( pData, fcDop );
    5796           8 :     Set_UInt32( pData, lcbDop );
    5797           8 :     Set_UInt32( pData, fcSttbfAssoc );
    5798           8 :     Set_UInt32( pData, lcbSttbfAssoc );
    5799           8 :     Set_UInt32( pData, fcClx );
    5800           8 :     Set_UInt32( pData, lcbClx );
    5801           8 :     Set_UInt32( pData, fcPlcfpgdFtn );
    5802           8 :     Set_UInt32( pData, lcbPlcfpgdFtn );
    5803           8 :     Set_UInt32( pData, fcAutosaveSource );
    5804           8 :     Set_UInt32( pData, lcbAutosaveSource );
    5805           8 :     Set_UInt32( pData, fcGrpStAtnOwners );
    5806           8 :     Set_UInt32( pData, lcbGrpStAtnOwners );
    5807           8 :     Set_UInt32( pData, fcSttbfAtnbkmk );
    5808           8 :     Set_UInt32( pData, lcbSttbfAtnbkmk );
    5809             : 
    5810             :     // weiteres short nur bei Ver67 ueberspringen
    5811           8 :     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           8 :     Set_UInt32( pData, fcPlcfdoaMom ); // nur bei Ver67, in Ver8 unused
    5821           8 :     Set_UInt32( pData, lcbPlcfdoaMom ); // nur bei Ver67, in Ver8 unused
    5822           8 :     Set_UInt32( pData, fcPlcfdoaHdr ); // nur bei Ver67, in Ver8 unused
    5823           8 :     Set_UInt32( pData, lcbPlcfdoaHdr ); // nur bei Ver67, in Ver8 unused
    5824             : 
    5825           8 :     Set_UInt32( pData, fcPlcfspaMom ); // in Ver67 leere Reserve
    5826           8 :     Set_UInt32( pData, lcbPlcfspaMom ); // in Ver67 leere Reserve
    5827           8 :     Set_UInt32( pData, fcPlcfspaHdr ); // in Ver67 leere Reserve
    5828           8 :     Set_UInt32( pData, lcbPlcfspaHdr ); // in Ver67 leere Reserve
    5829             : 
    5830           8 :     Set_UInt32( pData, fcPlcfAtnbkf );
    5831           8 :     Set_UInt32( pData, lcbPlcfAtnbkf );
    5832           8 :     Set_UInt32( pData, fcPlcfAtnbkl );
    5833           8 :     Set_UInt32( pData, lcbPlcfAtnbkl );
    5834           8 :     Set_UInt32( pData, fcPms );
    5835           8 :     Set_UInt32( pData, lcbPMS );
    5836           8 :     Set_UInt32( pData, fcFormFldSttbf );
    5837           8 :     Set_UInt32( pData, lcbFormFldSttbf );
    5838           8 :     Set_UInt32( pData, fcPlcfendRef );
    5839           8 :     Set_UInt32( pData, lcbPlcfendRef );
    5840           8 :     Set_UInt32( pData, fcPlcfendTxt );
    5841           8 :     Set_UInt32( pData, lcbPlcfendTxt );
    5842           8 :     Set_UInt32( pData, fcPlcffldEdn );
    5843           8 :     Set_UInt32( pData, lcbPlcffldEdn );
    5844           8 :     Set_UInt32( pData, fcPlcfpgdEdn );
    5845           8 :     Set_UInt32( pData, lcbPlcfpgdEdn );
    5846           8 :     Set_UInt32( pData, fcDggInfo ); // in Ver67 leere Reserve
    5847           8 :     Set_UInt32( pData, lcbDggInfo ); // in Ver67 leere Reserve
    5848           8 :     Set_UInt32( pData, fcSttbfRMark );
    5849           8 :     Set_UInt32( pData, lcbSttbfRMark );
    5850           8 :     Set_UInt32( pData, fcSttbfCaption );
    5851           8 :     Set_UInt32( pData, lcbSttbfCaption );
    5852           8 :     Set_UInt32( pData, fcSttbAutoCaption );
    5853           8 :     Set_UInt32( pData, lcbSttbAutoCaption );
    5854           8 :     Set_UInt32( pData, fcPlcfwkb );
    5855           8 :     Set_UInt32( pData, lcbPlcfwkb );
    5856           8 :     Set_UInt32( pData, fcPlcfspl ); // in Ver67 leere Reserve
    5857           8 :     Set_UInt32( pData, lcbPlcfspl ); // in Ver67 leere Reserve
    5858           8 :     Set_UInt32( pData, fcPlcftxbxTxt );
    5859           8 :     Set_UInt32( pData, lcbPlcftxbxTxt );
    5860           8 :     Set_UInt32( pData, fcPlcffldTxbx );
    5861           8 :     Set_UInt32( pData, lcbPlcffldTxbx );
    5862           8 :     Set_UInt32( pData, fcPlcfHdrtxbxTxt );
    5863           8 :     Set_UInt32( pData, lcbPlcfHdrtxbxTxt );
    5864           8 :     Set_UInt32( pData, fcPlcffldHdrTxbx );
    5865           8 :     Set_UInt32( pData, lcbPlcffldHdrTxbx );
    5866             : 
    5867           8 :     if( bVer8 )
    5868             :     {
    5869           8 :         pData += 0x2da - 0x27a;         // Pos + Offset (fcPlcfLst - fcStwUser)
    5870           8 :         Set_UInt32( pData, fcSttbFnm);
    5871           8 :         Set_UInt32( pData, lcbSttbFnm);
    5872           8 :         Set_UInt32( pData, fcPlcfLst );
    5873           8 :         Set_UInt32( pData, lcbPlcfLst );
    5874           8 :         Set_UInt32( pData, fcPlfLfo );
    5875           8 :         Set_UInt32( pData, lcbPlfLfo );
    5876           8 :         Set_UInt32( pData, fcPlcftxbxBkd );
    5877           8 :         Set_UInt32( pData, lcbPlcftxbxBkd );
    5878           8 :         Set_UInt32( pData, fcPlcfHdrtxbxBkd );
    5879           8 :         Set_UInt32( pData, lcbPlcfHdrtxbxBkd );
    5880             : 
    5881           8 :         pData += 0x372 - 0x302; // Pos + Offset (fcSttbListNames - fcDocUndo)
    5882           8 :         Set_UInt32( pData, fcSttbListNames );
    5883           8 :         Set_UInt32( pData, lcbSttbListNames );
    5884             : 
    5885           8 :         pData += 0x382 - 0x37A;
    5886           8 :         Set_UInt32( pData, fcPlcfTch );
    5887           8 :         Set_UInt32( pData, lcbPlcfTch );
    5888             : 
    5889           8 :         pData += 0x3FA - 0x38A;
    5890           8 :         Set_UInt16( pData, (sal_uInt16)0x0002);
    5891           8 :         Set_UInt16( pData, (sal_uInt16)0x00D9);
    5892             : 
    5893           8 :         pData += 0x41A - 0x3FE;
    5894           8 :         Set_UInt32( pData, fcAtrdExtra );
    5895           8 :         Set_UInt32( pData, lcbAtrdExtra );
    5896             : 
    5897           8 :         pData += 0x4DA - 0x422;
    5898           8 :         Set_UInt32( pData, fcHplxsdr );
    5899           8 :         Set_UInt32( pData, 0);
    5900             :     }
    5901             : 
    5902           8 :     rStrm.Write( pDataPtr, fcMin - nUnencryptedHdr );
    5903           8 :     delete[] pDataPtr;
    5904           8 :     return 0 == rStrm.GetError();
    5905             : }
    5906             : 
    5907         152 : 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         152 :         : rtl_getTextEncodingFromWindowsCharset( static_cast<sal_uInt8>(chs) );
    5914         152 :     return eCharSet;
    5915             : }
    5916             : 
    5917          74 : WW8Style::WW8Style(SvStream& rStream, WW8Fib& rFibPara)
    5918             :     : rFib(rFibPara), rSt(rStream), cstd(0), cbSTDBaseInFile(0),
    5919             :     stiMaxWhenSaved(0), istdMaxFixedWhenSaved(0), nVerBuiltInNamesWhenSaved(0),
    5920          74 :     ftcAsci(0), ftcFE(0), ftcOther(0), ftcBi(0)
    5921             : {
    5922          74 :     if (!checkSeek(rSt, rFib.fcStshf))
    5923             :         return;
    5924             : 
    5925          74 :     sal_uInt16 cbStshi = 0; //  2 bytes size of the following STSHI structure
    5926          74 :     sal_uInt32 nRemaining = rFib.lcbStshf;
    5927          74 :     const sal_uInt32 nMinValidStshi = 4;
    5928             : 
    5929          74 :     if (rFib.GetFIBVersion() <= ww::eWW2)
    5930             :     {
    5931           0 :         cbStshi = 0;
    5932           0 :         cstd = 256;
    5933             :     }
    5934             :     else
    5935             :     {
    5936          74 :         if (rFib.nFib < 67) // old Version ? (need to find this again to fix)
    5937           0 :             cbStshi = nMinValidStshi;
    5938             :         else    // new version
    5939             :         {
    5940          74 :             if (nRemaining < sizeof(cbStshi))
    5941             :                 return;
    5942             :             // lies die Laenge der in der Datei gespeicherten Struktur
    5943          74 :             rSt >> cbStshi;
    5944          74 :             nRemaining-=2;
    5945             :         }
    5946             :     }
    5947             : 
    5948          74 :     cbStshi = std::min(static_cast<sal_uInt32>(cbStshi), nRemaining);
    5949          74 :     if (cbStshi < nMinValidStshi)
    5950             :         return;
    5951             : 
    5952          74 :     sal_uInt16 nRead = cbStshi;
    5953          52 :     do
    5954             :     {
    5955             :         sal_uInt16 a16Bit;
    5956             : 
    5957          74 :         if(  2 > nRead ) break;
    5958          74 :         rSt >> cstd;
    5959             : 
    5960          74 :         if(  4 > nRead ) break;
    5961          74 :         rSt >> cbSTDBaseInFile;
    5962             : 
    5963          74 :         if(  6 > nRead ) break;
    5964          74 :         rSt >> a16Bit;
    5965          74 :         fStdStylenamesWritten = a16Bit & 0x0001;
    5966             : 
    5967          74 :         if(  8 > nRead ) break;
    5968          74 :         rSt >> stiMaxWhenSaved;
    5969             : 
    5970          74 :         if( 10 > nRead ) break;
    5971          74 :         rSt >> istdMaxFixedWhenSaved;
    5972             : 
    5973          74 :         if( 12 > nRead ) break;
    5974          74 :         rSt >> nVerBuiltInNamesWhenSaved;
    5975             : 
    5976          74 :         if( 14 > nRead ) break;
    5977          74 :         rSt >> ftcAsci;
    5978             : 
    5979          74 :         if( 16 > nRead ) break;
    5980          74 :         rSt >> ftcFE;
    5981             : 
    5982          74 :         if ( 18 > nRead ) break;
    5983          74 :         rSt >> ftcOther;
    5984             : 
    5985          74 :         ftcBi = ftcOther;
    5986             : 
    5987          74 :         if ( 20 > nRead ) break;
    5988          52 :         rSt >> ftcBi;
    5989             : 
    5990             :         // ggfs. den Rest ueberlesen
    5991          52 :         if( 20 < nRead )
    5992          26 :             rSt.SeekRel( nRead-20 );
    5993             :     }
    5994          52 :     while( !this ); // Trick: obiger Block wird genau einmal durchlaufen
    5995             :                     //   und kann vorzeitig per "break" verlassen werden.
    5996             : 
    5997          74 :     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          74 :     const sal_uInt32 nMinRecordSize = sizeof(sal_uInt16);
    6002          74 :     sal_uInt16 nMaxPossibleRecords = nRemaining/nMinRecordSize;
    6003             : 
    6004             :     OSL_ENSURE(cstd <= nMaxPossibleRecords,
    6005             :         "allegedly more styles that available data\n");
    6006          74 :     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        2356 : WW8_STD* WW8Style::Read1STDFixed( short& rSkip, short* pcbStd )
    6014             : {
    6015        2356 :     WW8_STD* pStd = 0;
    6016             : 
    6017        2356 :     sal_uInt16 cbStd(0);
    6018        2356 :     rSt >> cbStd;   // lies Laenge
    6019             : 
    6020        2356 :     sal_uInt16 nRead = cbSTDBaseInFile;
    6021        2356 :     if( cbStd >= cbSTDBaseInFile )
    6022             :     {
    6023             :         // Fixed part vollst. vorhanden
    6024             : 
    6025             :         // read fixed part of STD
    6026        1608 :         pStd = new WW8_STD;
    6027        1608 :         memset( pStd, 0, sizeof( *pStd ) );
    6028             : 
    6029        1608 :         do
    6030             :         {
    6031             :             sal_uInt16 a16Bit;
    6032             : 
    6033        1608 :             if( 2 > nRead ) break;
    6034        1608 :             a16Bit = 0;
    6035        1608 :             rSt >> a16Bit;
    6036        1608 :             pStd->sti          =        a16Bit & 0x0fff  ;
    6037        1608 :             pStd->fScratch     = 0 != ( a16Bit & 0x1000 );
    6038        1608 :             pStd->fInvalHeight = 0 != ( a16Bit & 0x2000 );
    6039        1608 :             pStd->fHasUpe      = 0 != ( a16Bit & 0x4000 );
    6040        1608 :             pStd->fMassCopy    = 0 != ( a16Bit & 0x8000 );
    6041             : 
    6042        1608 :             if( 4 > nRead ) break;
    6043        1608 :             a16Bit = 0;
    6044        1608 :             rSt >> a16Bit;
    6045        1608 :             pStd->sgc      =   a16Bit & 0x000f       ;
    6046        1608 :             pStd->istdBase = ( a16Bit & 0xfff0 ) >> 4;
    6047             : 
    6048        1608 :             if( 6 > nRead ) break;
    6049        1608 :             a16Bit = 0;
    6050        1608 :             rSt >> a16Bit;
    6051        1608 :             pStd->cupx     =   a16Bit & 0x000f       ;
    6052        1608 :             pStd->istdNext = ( a16Bit & 0xfff0 ) >> 4;
    6053             : 
    6054        1608 :             if( 8 > nRead ) break;
    6055        1608 :             a16Bit = 0;
    6056        1608 :             rSt >> pStd->bchUpe;
    6057             : 
    6058             :             // ab Ver8 sollten diese beiden Felder dazukommen:
    6059        1608 :             if(10 > nRead ) break;
    6060        1608 :             a16Bit = 0;
    6061        1608 :             rSt >> a16Bit;
    6062        1608 :             pStd->fAutoRedef =   a16Bit & 0x0001       ;
    6063        1608 :             pStd->fHidden    = ( a16Bit & 0x0002 ) >> 2;
    6064             : 
    6065             :             // man kann nie wissen: vorsichtshalber ueberlesen
    6066             :             // wir eventuelle Fuellsel, die noch zum BASE-Part gehoeren...
    6067        1608 :             if( 10 < nRead )
    6068         744 :                 rSt.SeekRel( nRead-10 );
    6069             :         }
    6070        1608 :         while( !this ); // Trick: obiger Block wird genau einmal durchlaufen
    6071             :                         //   und kann vorzeitig per "break" verlassen werden.
    6072             : 
    6073        1608 :         if( (0 != rSt.GetError()) || !nRead )
    6074           0 :             DELETEZ( pStd );        // per NULL den Error melden
    6075             : 
    6076        1608 :       rSkip = cbStd - cbSTDBaseInFile;
    6077             :     }
    6078             :     else
    6079             :     {           // Fixed part zu kurz
    6080         748 :         if( cbStd )
    6081           0 :             rSt.SeekRel( cbStd );           // ueberlies Reste
    6082         748 :         rSkip = 0;
    6083             :     }
    6084        2356 :     if( pcbStd )
    6085         804 :         *pcbStd = cbStd;
    6086        2356 :     return pStd;
    6087             : }
    6088             : 
    6089        2356 : 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        2356 :     WW8_STD* pStd = Read1STDFixed( rSkip, pcbStd );         // lese STD
    6095             : 
    6096             :     // String gewuenscht ?
    6097        2356 :     if( pString )
    6098             :     {   // echter Style ?
    6099         804 :         if ( pStd )
    6100             :         {
    6101         804 :             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         804 :                     if (TestBeltAndBraces<sal_Unicode>(rSt))
    6114             :                     {
    6115         804 :                         *pString = read_uInt16_BeltAndBracesString(rSt);
    6116         804 :                         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         804 :                     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        2356 :     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         430 : 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         430 :     sal_Unicode* pBuffer = sString.GetBufferAccess();
    6190         430 :     xub_StrLen nLen = sString.Len();
    6191         430 :     bool bFound = false;
    6192        4998 :     for( xub_StrLen n = 0; n < nLen; n++ )
    6193             :     {
    6194        4568 :         if( pBuffer[n] < sal_Unicode( 0x20 ) )
    6195             :         {
    6196           0 :             pBuffer[n] = sal_Unicode( 1 );
    6197           0 :             bFound = true;
    6198             :         }
    6199             :     }
    6200         430 :     sString.ReleaseBufferAccess();
    6201             : 
    6202             :     // if anything was found, remove \u0001 + leading/trailing ';'
    6203         430 :     if( bFound )
    6204             :     {
    6205           0 :         sString = comphelper::string::remove(sString, 1);
    6206           0 :         sString = comphelper::string::strip(sString, ';');
    6207             :     }
    6208         430 : }
    6209             : 
    6210             : namespace
    6211             : {
    6212          74 :     sal_uInt16 calcMaxFonts(sal_uInt8 *p, sal_Int32 nFFn)
    6213             :     {
    6214             :         // Figure out the max number of fonts defined here
    6215          74 :         sal_uInt16 nMax = 0;
    6216          74 :         sal_Int32 nRemaining = nFFn;
    6217         624 :         while (nRemaining)
    6218             :         {
    6219             :             //p[0] is cbFfnM1, the alleged total length of FFN - 1.
    6220             :             //i.e. length after cbFfnM1
    6221         550 :             sal_uInt16 cbFfnM1 = *p++;
    6222         550 :             --nRemaining;
    6223             : 
    6224         550 :             if (cbFfnM1 > nRemaining)
    6225          74 :                 break;
    6226             : 
    6227         476 :             nMax++;
    6228         476 :             nRemaining -= cbFfnM1;
    6229         476 :             p += cbFfnM1;
    6230             :         }
    6231          74 :         return nMax;
    6232             :     }
    6233             : }
    6234             : 
    6235          74 : WW8Fonts::WW8Fonts( SvStream& rSt, WW8Fib& rFib )
    6236          74 :     : pFontA(0), nMax(0)
    6237             : {
    6238             :     // Attention: MacWord-Documents have their Fontnames
    6239             :     // always in ANSI, even if eStructCharSet == CHARSET_MAC !!
    6240          74 :     if( rFib.lcbSttbfffn <= 2 )
    6241             :     {
    6242             :         OSL_ENSURE( !this, "Fonttabelle kaputt! (rFib.lcbSttbfffn < 2)" );
    6243             :         return;
    6244             :     }
    6245             : 
    6246          74 :     if (!checkSeek(rSt, rFib.fcSttbfffn))
    6247             :         return;
    6248             : 
    6249          74 :     sal_Int32 nFFn = rFib.lcbSttbfffn - 2;
    6250             : 
    6251             :     // allocate Font Array
    6252          74 :     sal_uInt8* pA = new sal_uInt8[nFFn];
    6253          74 :     memset(pA, 0, nFFn);
    6254             : 
    6255          74 :     ww::WordVersion eVersion = rFib.GetFIBVersion();
    6256             : 
    6257          74 :     if( eVersion >= ww::eWW8 )
    6258             :     {
    6259             :         // bVer8: read the count of strings in nMax
    6260          74 :         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          74 :     rSt.SeekRel( 2 );
    6267             : 
    6268             :     // read all font information
    6269          74 :     nFFn = rSt.Read(pA, nFFn);
    6270          74 :     sal_uInt16 nCalcMax = calcMaxFonts(pA, nFFn);
    6271             : 
    6272          74 :     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          74 :         nMax = std::min(nMax, nCalcMax);
    6279             :     }
    6280             : 
    6281          74 :     if( nMax )
    6282             :     {
    6283             :         // allocate Index Array
    6284          72 :         pFontA = new WW8_FFN[ nMax ];
    6285          72 :         WW8_FFN* p = pFontA;
    6286             : 
    6287          72 :         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          72 :         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          72 :             const sal_uInt8 cbMinFFNPayload = 41;
    6363          72 :             sal_uInt16 nValidFonts = 0;
    6364          72 :             sal_Int32 nRemainingFFn = nFFn;
    6365          72 :             sal_uInt8* pRaw = pA;
    6366         502 :             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         430 :                 sal_uInt8 cbFfnM1 = *pRaw++;
    6371         430 :                 --nRemainingFFn;
    6372             : 
    6373         430 :                 if (cbFfnM1 > nRemainingFFn)
    6374           0 :                     break;
    6375             : 
    6376         430 :                 if (cbFfnM1 < cbMinFFNPayload)
    6377           0 :                     break;
    6378             : 
    6379         430 :                 p->cbFfnM1 = cbFfnM1;
    6380             : 
    6381         430 :                 sal_uInt8 *pVer8 = pRaw;
    6382             : 
    6383         430 :                 sal_uInt8 c2 = *pVer8++;
    6384         430 :                 --cbFfnM1;
    6385             : 
    6386         430 :                 p->prg = c2 & 0x02;
    6387         430 :                 p->fTrueType = (c2 & 0x04) >> 2;
    6388             :                 // ein Reserve-Bit ueberspringen
    6389         430 :                 p->ff = (c2 & 0x70) >> 4;
    6390             : 
    6391         430 :                 p->wWeight = SVBT16ToShort(*(SVBT16*)pVer8);
    6392         430 :                 pVer8+=2;
    6393         430 :                 cbFfnM1-=2;
    6394             : 
    6395         430 :                 p->chs = *pVer8++;
    6396         430 :                 --cbFfnM1;
    6397             : 
    6398         430 :                 p->ibszAlt = *pVer8++;
    6399         430 :                 --cbFfnM1;
    6400             : 
    6401         430 :                 pVer8 += 10; //PANOSE
    6402         430 :                 cbFfnM1-=10;
    6403         430 :                 pVer8 += 24; //FONTSIGNATURE
    6404         430 :                 cbFfnM1-=24;
    6405             : 
    6406             :                 OSL_ASSERT(cbFfnM1 >= 2);
    6407             : 
    6408         430 :                 sal_uInt8 nMaxNullTerminatedPossible = cbFfnM1/2 - 1;
    6409         430 :                 sal_Unicode *pPrimary = reinterpret_cast<sal_Unicode*>(pVer8);
    6410         430 :                 pPrimary[nMaxNullTerminatedPossible] = 0;
    6411             : #ifdef OSL_BIGENDIAN
    6412             :                 swapEndian(pPrimary);
    6413             : #endif
    6414         430 :                 p->sFontname = pPrimary;
    6415         430 :                 if (p->ibszAlt && p->ibszAlt < nMaxNullTerminatedPossible)
    6416             :                 {
    6417          44 :                     p->sFontname.Append(';');
    6418          44 :                     sal_Unicode *pSecondary = pPrimary + p->ibszAlt;
    6419             : #ifdef OSL_BIGENDIAN
    6420             :                     swapEndian(pSecondary);
    6421             : #endif
    6422          44 :                     p->sFontname.Append(pSecondary);
    6423             :                 }
    6424             : 
    6425             :                 // #i43762# check font name for illegal characters
    6426         430 :                 lcl_checkFontname( p->sFontname );
    6427             : 
    6428             :                 // Zeiger auf Ursprungsarray einen Font nach hinten setzen
    6429         430 :                 pRaw += p->cbFfnM1;
    6430         430 :                 nRemainingFFn -= p->cbFfnM1;
    6431         430 :                 ++nValidFonts;
    6432             :             }
    6433             :             OSL_ENSURE(nMax == nValidFonts, "Font count differs with availability");
    6434          72 :             nMax = std::min(nMax, nValidFonts);
    6435             :         }
    6436             :     }
    6437          74 :     delete[] pA;
    6438             : }
    6439             : 
    6440        5600 : const WW8_FFN* WW8Fonts::GetFont( sal_uInt16 nNum ) const
    6441             : {
    6442        5600 :     if( !pFontA || nNum >= nMax )
    6443         330 :         return 0;
    6444             : 
    6445        5270 :     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          36 : WW8PLCF_HdFt::WW8PLCF_HdFt( SvStream* pSt, WW8Fib& rFib, WW8Dop& rDop )
    6467          36 :     : aPLCF(*pSt, rFib.fcPlcfhdd , rFib.lcbPlcfhdd , 0)
    6468             : {
    6469          36 :     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         252 :     for( sal_uInt8 nI = 0x1; nI <= 0x20; nI <<= 1 )
    6484         216 :         if( nI & rDop.grpfIhdt )                // Bit gesetzt ?
    6485           0 :             nIdxOffset++;
    6486             : 
    6487          36 :     nTextOfs = rFib.ccpText + rFib.ccpFtn;  // Groesse des Haupttextes
    6488             :                                             // und der Fussnoten
    6489          36 : }
    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         212 : bool WW8PLCF_HdFt::GetTextPosExact(short nIdx, WW8_CP& rStart, long& rLen)
    6519             : {
    6520             :     WW8_CP nEnd;
    6521             :     void* pData;
    6522             : 
    6523         212 :     aPLCF.SetIdx( nIdx );               // Lookup suitable CP
    6524         212 :     aPLCF.Get( rStart, nEnd, pData );
    6525         212 :     rLen = nEnd - rStart;
    6526         212 :     return true;
    6527             : }
    6528             : 
    6529          22 : void WW8PLCF_HdFt::UpdateIndex( sal_uInt8 grpfIhdt )
    6530             : {
    6531             :     // Caution: Description is not correct
    6532         154 :     for( sal_uInt8 nI = 0x01; nI <= 0x20; nI <<= 1 )
    6533         132 :         if( nI & grpfIhdt )
    6534          68 :             nIdxOffset++;
    6535          22 : }
    6536             : 
    6537             : //-----------------------------------------
    6538             : //          WW8Dop
    6539             : //-----------------------------------------
    6540             : 
    6541          74 : WW8Dop::WW8Dop(SvStream& rSt, sal_Int16 nFib, sal_Int32 nPos, sal_uInt32 nSize) : bUseThaiLineBreakingRules(false)
    6542             : {
    6543          74 :     memset( &nDataStart, 0, (&nDataEnd - &nDataStart) );
    6544          74 :     fDontUseHTMLAutoSpacing = true; //default
    6545          74 :     fAcetateShowAtn = true; //default
    6546          74 :     const sal_uInt32 nMaxDopSize = 0x268;
    6547          74 :     sal_uInt8* pDataPtr = new sal_uInt8[ nMaxDopSize ];
    6548          74 :     sal_uInt8* pData = pDataPtr;
    6549             : 
    6550          74 :     sal_uInt32 nRead = nMaxDopSize < nSize ? nMaxDopSize : nSize;
    6551          74 :     rSt.Seek( nPos );
    6552          74 :     if (2 > nSize || nRead != rSt.Read(pData, nRead))
    6553           0 :         nDopError = ERR_SWG_READ_ERROR;     // Error melden
    6554             :     else
    6555             :     {
    6556          74 :         if (nMaxDopSize > nRead)
    6557          48 :             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          74 :         a16Bit = Get_UShort( pData );        // 0 0x00
    6565          74 :         fFacingPages        = 0 != ( a16Bit  &  0x0001 )     ;
    6566          74 :         fWidowControl       = 0 != ( a16Bit  &  0x0002 )     ;
    6567          74 :         fPMHMainDoc         = 0 != ( a16Bit  &  0x0004 )     ;
    6568          74 :         grfSuppression      =      ( a16Bit  &  0x0018 ) >> 3;
    6569          74 :         fpc                 =      ( a16Bit  &  0x0060 ) >> 5;
    6570          74 :         grpfIhdt            =      ( a16Bit  &  0xff00 ) >> 8;
    6571             : 
    6572          74 :         a16Bit = Get_UShort( pData );        // 2 0x02
    6573          74 :         rncFtn              =   a16Bit  &  0x0003        ;
    6574          74 :         nFtn                = ( a16Bit  & ~0x0003 ) >> 2 ;
    6575             : 
    6576          74 :         a8Bit = Get_Byte( pData );           // 4 0x04
    6577          74 :         fOutlineDirtySave      = 0 != ( a8Bit  &  0x01   );
    6578             : 
    6579          74 :         a8Bit = Get_Byte( pData );           // 5 0x05
    6580          74 :         fOnlyMacPics           = 0 != ( a8Bit  &  0x01   );
    6581          74 :         fOnlyWinPics           = 0 != ( a8Bit  &  0x02   );
    6582          74 :         fLabelDoc              = 0 != ( a8Bit  &  0x04   );
    6583          74 :         fHyphCapitals          = 0 != ( a8Bit  &  0x08   );
    6584          74 :         fAutoHyphen            = 0 != ( a8Bit  &  0x10   );
    6585          74 :         fFormNoFields          = 0 != ( a8Bit  &  0x20   );
    6586          74 :         fLinkStyles            = 0 != ( a8Bit  &  0x40   );
    6587          74 :         fRevMarking            = 0 != ( a8Bit  &  0x80   );
    6588             : 
    6589          74 :         a8Bit = Get_Byte( pData );           // 6 0x06
    6590          74 :         fBackup                = 0 != ( a8Bit  &  0x01   );
    6591          74 :         fExactCWords           = 0 != ( a8Bit  &  0x02   );
    6592          74 :         fPagHidden             = 0 != ( a8Bit  &  0x04   );
    6593          74 :         fPagResults            = 0 != ( a8Bit  &  0x08   );
    6594          74 :         fLockAtn               = 0 != ( a8Bit  &  0x10   );
    6595          74 :         fMirrorMargins         = 0 != ( a8Bit  &  0x20   );
    6596          74 :         fReadOnlyRecommended   = 0 != ( a8Bit  &  0x40   );
    6597          74 :         fDfltTrueType          = 0 != ( a8Bit  &  0x80   );
    6598             : 
    6599          74 :         a8Bit = Get_Byte( pData );           // 7 0x07
    6600          74 :         fPagSuppressTopSpacing = 0 != ( a8Bit  &  0x01   );
    6601          74 :         fProtEnabled           = 0 != ( a8Bit  &  0x02   );
    6602          74 :         fDispFormFldSel        = 0 != ( a8Bit  &  0x04   );
    6603          74 :         fRMView                = 0 != ( a8Bit  &  0x08   );
    6604          74 :         fRMPrint               = 0 != ( a8Bit  &  0x10   );
    6605          74 :         fWriteReservation      = 0 != ( a8Bit  &  0x20   );
    6606          74 :         fLockRev               = 0 != ( a8Bit  &  0x40   );
    6607          74 :         fEmbedFonts            = 0 != ( a8Bit  &  0x80   );
    6608             : 
    6609             : 
    6610          74 :         a8Bit = Get_Byte( pData );           // 8 0x08
    6611          74 :         copts_fNoTabForInd           = 0 != ( a8Bit  &  0x01   );
    6612          74 :         copts_fNoSpaceRaiseLower     = 0 != ( a8Bit  &  0x02   );
    6613          74 :         copts_fSupressSpbfAfterPgBrk = 0 != ( a8Bit  &  0x04   );
    6614          74 :         copts_fWrapTrailSpaces       = 0 != ( a8Bit  &  0x08   );
    6615          74 :         copts_fMapPrintTextColor     = 0 != ( a8Bit  &  0x10   );
    6616          74 :         copts_fNoColumnBalance       = 0 != ( a8Bit  &  0x20   );
    6617          74 :         copts_fConvMailMergeEsc      = 0 != ( a8Bit  &  0x40   );
    6618          74 :         copts_fSupressTopSpacing     = 0 != ( a8Bit  &  0x80   );
    6619             : 
    6620          74 :         a8Bit = Get_Byte( pData );           // 9 0x09
    6621          74 :         copts_fOrigWordTableRules    = 0 != ( a8Bit  &  0x01   );
    6622          74 :         copts_fTransparentMetafiles  = 0 != ( a8Bit  &  0x02   );
    6623          74 :         copts_fShowBreaksInFrames    = 0 != ( a8Bit  &  0x04   );
    6624          74 :         copts_fSwapBordersFacingPgs  = 0 != ( a8Bit  &  0x08   );
    6625          74 :         copts_fExpShRtn              = 0 != ( a8Bit  &  0x20   );  // #i56856#
    6626             : 
    6627          74 :         dxaTab = Get_Short( pData );         // 10 0x0a
    6628          74 :         wSpare = Get_UShort( pData );        // 12 0x0c
    6629          74 :         dxaHotZ = Get_UShort( pData );       // 14 0x0e
    6630          74 :         cConsecHypLim = Get_UShort( pData ); // 16 0x10
    6631          74 :         wSpare2 = Get_UShort( pData );       // 18 0x12
    6632          74 :         dttmCreated = Get_Long( pData );     // 20 0x14
    6633          74 :         dttmRevised = Get_Long( pData );     // 24 0x18
    6634          74 :         dttmLastPrint = Get_Long( pData );   // 28 0x1c
    6635          74 :         nRevision = Get_Short( pData );      // 32 0x20
    6636          74 :         tmEdited = Get_Long( pData );        // 34 0x22
    6637          74 :         cWords = Get_Long( pData );          // 38 0x26
    6638          74 :         cCh = Get_Long( pData );             // 42 0x2a
    6639          74 :         cPg = Get_Short( pData );            // 46 0x2e
    6640          74 :         cParas = Get_Long( pData );          // 48 0x30
    6641             : 
    6642          74 :         a16Bit = Get_UShort( pData );        // 52 0x34
    6643          74 :         rncEdn =   a16Bit &  0x0003       ;
    6644          74 :         nEdn   = ( a16Bit & ~0x0003 ) >> 2;
    6645             : 
    6646          74 :         a16Bit = Get_UShort( pData );        // 54 0x36
    6647          74 :         epc            =   a16Bit &  0x0003       ;
    6648          74 :         nfcFtnRef      = ( a16Bit &  0x003c ) >> 2;
    6649          74 :         nfcEdnRef      = ( a16Bit &  0x03c0 ) >> 6;
    6650          74 :         fPrintFormData = 0 != ( a16Bit &  0x0400 );
    6651          74 :         fSaveFormData  = 0 != ( a16Bit &  0x0800 );
    6652          74 :         fShadeFormData = 0 != ( a16Bit &  0x1000 );
    6653          74 :         fWCFtnEdn      = 0 != ( a16Bit &  0x8000 );
    6654             : 
    6655          74 :         cLines = Get_Long( pData );          // 56 0x38
    6656          74 :         cWordsFtnEnd = Get_Long( pData );    // 60 0x3c
    6657          74 :         cChFtnEdn = Get_Long( pData );       // 64 0x40
    6658          74 :         cPgFtnEdn = Get_Short( pData );      // 68 0x44
    6659          74 :         cParasFtnEdn = Get_Long( pData );    // 70 0x46
    6660          74 :         cLinesFtnEdn = Get_Long( pData );    // 74 0x4a
    6661          74 :         lKeyProtDoc = Get_Long( pData );     // 78 0x4e
    6662             : 
    6663          74 :         a16Bit = Get_UShort( pData );        // 82 0x52
    6664          74 :         wvkSaved    =   a16Bit & 0x0007        ;
    6665          74 :         wScaleSaved = ( a16Bit & 0x0ff8 ) >> 3 ;
    6666          74 :         zkSaved     = ( a16Bit & 0x3000 ) >> 12;
    6667          74 :         fRotateFontW6 = ( a16Bit & 0x4000 ) >> 14;
    6668          74 :         iGutterPos = ( a16Bit &  0x8000 ) >> 15;
    6669             :         /*
    6670             :             bei nFib >= 103 gehts weiter:
    6671             :         */
    6672          74 :         if (nFib >= 103) // Word 6/32bit, 95, 97, 2000, 2002, 2003, 2007
    6673             :         {
    6674          74 :             a32Bit = Get_ULong( pData );     // 84 0x54
    6675          74 :             SetCompatabilityOptions(a32Bit);
    6676             :         }
    6677             : 
    6678             :         //#i22436#, for all WW7- documents
    6679          74 :         if (nFib <= 104) // Word 95
    6680           0 :             fUsePrinterMetrics = 1;
    6681             : 
    6682             :         /*
    6683             :             bei nFib > 105 gehts weiter:
    6684             :         */
    6685          74 :         if (nFib > 105) // Word 97, 2000, 2002, 2003, 2007
    6686             :         {
    6687          74 :             adt = Get_Short( pData );            // 88 0x58
    6688             : 
    6689          74 :             doptypography.ReadFromMem(pData);    // 90 0x5a
    6690             : 
    6691          74 :             memcpy( &dogrid, pData, sizeof( WW8_DOGRID )); // 400 0x190
    6692          74 :             pData += sizeof( WW8_DOGRID );
    6693             : 
    6694          74 :             a16Bit = Get_UShort( pData );        // 410 0x19a
    6695             :             // die untersten 9 Bit sind uninteressant
    6696          74 :             fHtmlDoc                = ( a16Bit &  0x0200 ) >>  9 ;
    6697          74 :             fSnapBorder             = ( a16Bit &  0x0800 ) >> 11 ;
    6698          74 :             fIncludeHeader          = ( a16Bit &  0x1000 ) >> 12 ;
    6699          74 :             fIncludeFooter          = ( a16Bit &  0x2000 ) >> 13 ;
    6700          74 :             fForcePageSizePag       = ( a16Bit &  0x4000 ) >> 14 ;
    6701          74 :             fMinFontSizePag         = ( a16Bit &  0x8000 ) >> 15 ;
    6702             : 
    6703          74 :             a16Bit = Get_UShort( pData );        // 412 0x19c
    6704          74 :             fHaveVersions   = 0 != ( a16Bit  &  0x0001 );
    6705          74 :             fAutoVersion    = 0 != ( a16Bit  &  0x0002 );
    6706             : 
    6707          74 :             pData += 12;                         // 414 0x19e
    6708             : 
    6709          74 :             cChWS = Get_Long( pData );           // 426 0x1aa
    6710          74 :             cChWSFtnEdn = Get_Long( pData );     // 430 0x1ae
    6711          74 :             grfDocEvents = Get_Long( pData );    // 434 0x1b2
    6712             : 
    6713          74 :             pData += 4+30+8;  // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc
    6714             : 
    6715          74 :             cDBC = Get_Long( pData );            // 480 0x1e0
    6716          74 :             cDBCFtnEdn = Get_Long( pData );      // 484 0x1e4
    6717             : 
    6718          74 :             pData += 1 * sizeof( sal_Int32);         // 488 0x1e8
    6719             : 
    6720          74 :             nfcFtnRef = Get_Short( pData );      // 492 0x1ec
    6721          74 :             nfcEdnRef = Get_Short( pData );      // 494 0x1ee
    6722          74 :             hpsZoonFontPag = Get_Short( pData ); // 496 0x1f0
    6723          74 :             dywDispPag = Get_Short( pData );     // 498 0x1f2
    6724             : 
    6725          74 :             if (nRead >= 516)
    6726             :             {
    6727             :                 //500 -> 508, Appear to be repeated here in 2000+
    6728          66 :                 pData += 8;                      // 500 0x1f4
    6729          66 :                 a32Bit = Get_Long( pData );      // 508 0x1fc
    6730          66 :                 SetCompatabilityOptions(a32Bit);
    6731          66 :                 a32Bit = Get_Long( pData );      // 512 0x200
    6732             : 
    6733             :                 // i#78591#
    6734          66 :                 SetCompatabilityOptions2(a32Bit);
    6735             :             }
    6736          74 :             if (nRead >= 550)
    6737             :             {
    6738          52 :                 pData += 32;
    6739          52 :                 a16Bit = Get_UShort( pData );
    6740          52 :                 fDoNotEmbedSystemFont = ( a16Bit &  0x0001 );
    6741          52 :                 fWordCompat = ( a16Bit &  0x0002 ) >> 1;
    6742          52 :                 fLiveRecover = ( a16Bit &  0x0004 ) >> 2;
    6743          52 :                 fEmbedFactoids = ( a16Bit &  0x0008 ) >> 3;
    6744          52 :                 fFactoidXML = ( a16Bit &  0x00010 ) >> 4;
    6745          52 :                 fFactoidAllDone = ( a16Bit &  0x0020 ) >> 5;
    6746          52 :                 fFolioPrint = ( a16Bit &  0x0040 ) >> 6;
    6747          52 :                 fReverseFolio = ( a16Bit &  0x0080 ) >> 7;
    6748          52 :                 iTextLineEnding = ( a16Bit &  0x0700 ) >> 8;
    6749          52 :                 fHideFcc = ( a16Bit &  0x0800 ) >> 11;
    6750          52 :                 fAcetateShowMarkup = ( a16Bit &  0x1000 ) >> 12;
    6751          52 :                 fAcetateShowAtn = ( a16Bit &  0x2000 ) >> 13;
    6752          52 :                 fAcetateShowInsDel = ( a16Bit &  0x4000 ) >> 14;
    6753          52 :                 fAcetateShowProps = ( a16Bit &  0x8000 ) >> 15;
    6754             :             }
    6755          74 :             if (nRead >= 600)
    6756             :             {
    6757          40 :                 pData += 48;
    6758          40 :                 a16Bit = Get_Short(pData);
    6759          40 :                 fUseBackGroundInAllmodes = (a16Bit & 0x0080) >> 7;
    6760             :             }
    6761             :         }
    6762             :     }
    6763          74 :     delete[] pDataPtr;
    6764          74 : }
    6765             : 
    6766           8 : WW8Dop::WW8Dop() : bUseThaiLineBreakingRules(false)
    6767             : {
    6768             :     // first set everything to a default of 0
    6769           8 :     memset( &nDataStart, 0, (&nDataEnd - &nDataStart) );
    6770             : 
    6771           8 :     fWidowControl = 1;
    6772           8 :     fpc = 1;
    6773           8 :     nFtn = 1;
    6774           8 :     fOutlineDirtySave = 1;
    6775           8 :     fHyphCapitals = 1;
    6776           8 :     fBackup = 1;
    6777           8 :     fPagHidden = 1;
    6778           8 :     fPagResults = 1;
    6779           8 :     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           8 :     fNoLeading = 1;
    6787           8 :     fUsePrinterMetrics = 1;
    6788             : 
    6789           8 :     fRMView = 1;
    6790           8 :     fRMPrint = 1;
    6791           8 :     dxaTab = 0x2d0;
    6792           8 :     dxaHotZ = 0x168;
    6793           8 :     nRevision = 1;
    6794           8 :     nEdn = 1;
    6795             : 
    6796           8 :     epc = 3;
    6797           8 :     nfcEdnRef = 2;
    6798           8 :     fShadeFormData = 1;
    6799             : 
    6800           8 :     wvkSaved = 2;
    6801           8 :     wScaleSaved = 100;
    6802           8 :     zkSaved = 0;
    6803             : 
    6804           8 :     lvl = 9;
    6805           8 :     fIncludeHeader = 1;
    6806           8 :     fIncludeFooter = 1;
    6807             : 
    6808           8 :     cChWS = /**!!**/ 0;
    6809           8 :     cChWSFtnEdn = /**!!**/ 0;
    6810             : 
    6811           8 :     cDBC = /**!!**/ 0;
    6812           8 :     cDBCFtnEdn = /**!!**/ 0;
    6813             : 
    6814           8 :     fAcetateShowAtn = true;
    6815           8 : }
    6816             : 
    6817         148 : void WW8Dop::SetCompatabilityOptions(sal_uInt32 a32Bit)
    6818             : {
    6819         148 :     fNoTabForInd                = ( a32Bit &  0x00000001 )       ;
    6820         148 :     fNoSpaceRaiseLower          = ( a32Bit &  0x00000002 ) >>  1 ;
    6821         148 :     fSupressSpbfAfterPageBreak  = ( a32Bit &  0x00000004 ) >>  2 ;
    6822         148 :     fWrapTrailSpaces            = ( a32Bit &  0x00000008 ) >>  3 ;
    6823         148 :     fMapPrintTextColor          = ( a32Bit &  0x00000010 ) >>  4 ;
    6824         148 :     fNoColumnBalance            = ( a32Bit &  0x00000020 ) >>  5 ;
    6825         148 :     fConvMailMergeEsc           = ( a32Bit &  0x00000040 ) >>  6 ;
    6826         148 :     fSupressTopSpacing          = ( a32Bit &  0x00000080 ) >>  7 ;
    6827         148 :     fOrigWordTableRules         = ( a32Bit &  0x00000100 ) >>  8 ;
    6828         148 :     fTransparentMetafiles       = ( a32Bit &  0x00000200 ) >>  9 ;
    6829         148 :     fShowBreaksInFrames         = ( a32Bit &  0x00000400 ) >> 10 ;
    6830         148 :     fSwapBordersFacingPgs       = ( a32Bit &  0x00000800 ) >> 11 ;
    6831         148 :     fCompatabilityOptions_Unknown1_13       = ( a32Bit &  0x00001000 ) >> 12 ;
    6832         148 :     fExpShRtn                   = ( a32Bit &  0x00002000 ) >> 13 ; // #i56856#
    6833         148 :     fCompatabilityOptions_Unknown1_15       = ( a32Bit &  0x00004000 ) >> 14 ;
    6834         148 :     fCompatabilityOptions_Unknown1_16       = ( a32Bit &  0x00008000 ) >> 15 ;
    6835         148 :     fSuppressTopSpacingMac5     = ( a32Bit &  0x00010000 ) >> 16 ;
    6836         148 :     fTruncDxaExpand             = ( a32Bit &  0x00020000 ) >> 17 ;
    6837         148 :     fPrintBodyBeforeHdr         = ( a32Bit &  0x00040000 ) >> 18 ;
    6838         148 :     fNoLeading                  = ( a32Bit &  0x00080000 ) >> 19 ;
    6839         148 :     fCompatabilityOptions_Unknown1_21       = ( a32Bit &  0x00100000 ) >> 20 ;
    6840         148 :     fMWSmallCaps                = ( a32Bit &  0x00200000 ) >> 21 ;
    6841         148 :     fCompatabilityOptions_Unknown1_23       = ( a32Bit &  0x00400000 ) >> 22 ;
    6842         148 :     fCompatabilityOptions_Unknown1_24       = ( a32Bit &  0x00800800 ) >> 23 ;
    6843         148 :     fCompatabilityOptions_Unknown1_25       = ( a32Bit &  0x01000000 ) >> 24 ;
    6844         148 :     fCompatabilityOptions_Unknown1_26       = ( a32Bit &  0x02000000 ) >> 25 ;
    6845         148 :     fCompatabilityOptions_Unknown1_27       = ( a32Bit &  0x04000000 ) >> 26 ;
    6846         148 :     fCompatabilityOptions_Unknown1_28       = ( a32Bit &  0x08000000 ) >> 27 ;
    6847         148 :     fCompatabilityOptions_Unknown1_29       = ( a32Bit &  0x10000000 ) >> 28 ;
    6848         148 :     fCompatabilityOptions_Unknown1_30       = ( a32Bit &  0x20000000 ) >> 29 ;
    6849         148 :     fCompatabilityOptions_Unknown1_31       = ( a32Bit &  0x40000000 ) >> 30 ;
    6850             : 
    6851         148 :     fUsePrinterMetrics          = ( a32Bit &  0x80000000 ) >> 31 ;
    6852         148 : }
    6853             : 
    6854          90 : sal_uInt32 WW8Dop::GetCompatabilityOptions() const
    6855             : {
    6856          90 :     sal_uInt32 a32Bit = 0;
    6857          90 :     if (fNoTabForInd)                   a32Bit |= 0x00000001;
    6858          90 :     if (fNoSpaceRaiseLower)             a32Bit |= 0x00000002;
    6859          90 :     if (fSupressSpbfAfterPageBreak)     a32Bit |= 0x00000004;
    6860          90 :     if (fWrapTrailSpaces)               a32Bit |= 0x00000008;
    6861          90 :     if (fMapPrintTextColor)             a32Bit |= 0x00000010;
    6862          90 :     if (fNoColumnBalance)               a32Bit |= 0x00000020;
    6863          90 :     if (fConvMailMergeEsc)              a32Bit |= 0x00000040;
    6864          90 :     if (fSupressTopSpacing)             a32Bit |= 0x00000080;
    6865          90 :     if (fOrigWordTableRules)            a32Bit |= 0x00000100;
    6866          90 :     if (fTransparentMetafiles)          a32Bit |= 0x00000200;
    6867          90 :     if (fShowBreaksInFrames)            a32Bit |= 0x00000400;
    6868          90 :     if (fSwapBordersFacingPgs)          a32Bit |= 0x00000800;
    6869          90 :     if (fCompatabilityOptions_Unknown1_13)          a32Bit |= 0x00001000;
    6870          90 :     if (fExpShRtn)                      a32Bit |= 0x00002000; // #i56856#
    6871          90 :     if (fCompatabilityOptions_Unknown1_15)          a32Bit |= 0x00004000;
    6872          90 :     if (fCompatabilityOptions_Unknown1_16)          a32Bit |= 0x00008000;
    6873          90 :     if (fSuppressTopSpacingMac5)        a32Bit |= 0x00010000;
    6874          90 :     if (fTruncDxaExpand)                a32Bit |= 0x00020000;
    6875          90 :     if (fPrintBodyBeforeHdr)            a32Bit |= 0x00040000;
    6876          90 :     if (fNoLeading)                     a32Bit |= 0x00080000;
    6877          90 :     if (fCompatabilityOptions_Unknown1_21)          a32Bit |= 0x00100000;
    6878          90 :     if (fMWSmallCaps)                   a32Bit |= 0x00200000;
    6879          90 :     if (fCompatabilityOptions_Unknown1_23)          a32Bit |= 0x00400000;
    6880          90 :     if (fCompatabilityOptions_Unknown1_24)          a32Bit |= 0x00800000;
    6881          90 :     if (fCompatabilityOptions_Unknown1_25)          a32Bit |= 0x01000000;
    6882          90 :     if (fCompatabilityOptions_Unknown1_26)          a32Bit |= 0x02000000;
    6883          90 :     if (fCompatabilityOptions_Unknown1_27)          a32Bit |= 0x04000000;
    6884          90 :     if (fCompatabilityOptions_Unknown1_28)          a32Bit |= 0x08000000;
    6885          90 :     if (fCompatabilityOptions_Unknown1_29)          a32Bit |= 0x10000000;
    6886          90 :     if (fCompatabilityOptions_Unknown1_30)          a32Bit |= 0x20000000;
    6887          90 :     if (fCompatabilityOptions_Unknown1_31)          a32Bit |= 0x40000000;
    6888          90 :     if (fUsePrinterMetrics)             a32Bit |= 0x80000000;
    6889          90 :     return a32Bit;
    6890             : }
    6891             : 
    6892             : // i#78591#
    6893          74 : void WW8Dop::SetCompatabilityOptions2(sal_uInt32 a32Bit)
    6894             : {
    6895          74 :     fCompatabilityOptions_Unknown2_1                        = ( a32Bit &  0x00000001 );
    6896          74 :     fCompatabilityOptions_Unknown2_2                        = ( a32Bit &  0x00000002 ) >>  1 ;
    6897          74 :     fDontUseHTMLAutoSpacing     = ( a32Bit &  0x00000004 ) >>  2 ;
    6898          74 :     fCompatabilityOptions_Unknown2_4                    = ( a32Bit &  0x00000008 ) >>  3 ;
    6899          74 :        fCompatabilityOptions_Unknown2_5                 = ( a32Bit &  0x00000010 ) >>  4 ;
    6900          74 :        fCompatabilityOptions_Unknown2_6                 = ( a32Bit &  0x00000020 ) >>  5 ;
    6901          74 :        fCompatabilityOptions_Unknown2_7                 = ( a32Bit &  0x00000040 ) >>  6 ;
    6902          74 :        fCompatabilityOptions_Unknown2_8                 = ( a32Bit &  0x00000080 ) >>  7 ;
    6903          74 :        fCompatabilityOptions_Unknown2_9                 = ( a32Bit &  0x00000100 ) >>  8 ;
    6904          74 :        fCompatabilityOptions_Unknown2_10                    = ( a32Bit &  0x00000200 ) >>  9 ;
    6905          74 :        fCompatabilityOptions_Unknown2_11                    = ( a32Bit &  0x00000400 ) >> 10 ;
    6906          74 :        fCompatabilityOptions_Unknown2_12                    = ( a32Bit &  0x00000800 ) >> 11 ;
    6907          74 :     fCompatabilityOptions_Unknown2_13                   = ( a32Bit &  0x00001000 ) >> 12 ;
    6908          74 :     fCompatabilityOptions_Unknown2_14                   = ( a32Bit &  0x00002000 ) >> 13 ;
    6909          74 :     fCompatabilityOptions_Unknown2_15                   = ( a32Bit &  0x00004000 ) >> 14 ;
    6910          74 :     fCompatabilityOptions_Unknown2_16                   = ( a32Bit &  0x00008000 ) >> 15 ;
    6911          74 :        fCompatabilityOptions_Unknown2_17                    = ( a32Bit &  0x00010000 ) >> 16 ;
    6912          74 :        fCompatabilityOptions_Unknown2_18                    = ( a32Bit &  0x00020000 ) >> 17 ;
    6913          74 :        fCompatabilityOptions_Unknown2_19                    = ( a32Bit &  0x00040000 ) >> 18 ;
    6914          74 :        fCompatabilityOptions_Unknown2_20                    = ( a32Bit &  0x00080000 ) >> 19 ;
    6915          74 :     fCompatabilityOptions_Unknown2_21                   = ( a32Bit &  0x00100000 ) >> 20 ;
    6916          74 :        fCompatabilityOptions_Unknown2_22                    = ( a32Bit &  0x00200000 ) >> 21 ;
    6917          74 :     fCompatabilityOptions_Unknown2_23                   = ( a32Bit &  0x00400000 ) >> 22 ;
    6918          74 :     fCompatabilityOptions_Unknown2_24                   = ( a32Bit &  0x00800800 ) >> 23 ;
    6919          74 :     fCompatabilityOptions_Unknown2_25                   = ( a32Bit &  0x01000800 ) >> 24 ;
    6920          74 :     fCompatabilityOptions_Unknown2_26                   = ( a32Bit &  0x02000800 ) >> 25 ;
    6921          74 :     fCompatabilityOptions_Unknown2_27                   = ( a32Bit &  0x04000800 ) >> 26 ;
    6922          74 :     fCompatabilityOptions_Unknown2_28                   = ( a32Bit &  0x08000800 ) >> 27 ;
    6923          74 :     fCompatabilityOptions_Unknown2_29                   = ( a32Bit &  0x10000800 ) >> 28 ;
    6924          74 :     fCompatabilityOptions_Unknown2_30                   = ( a32Bit &  0x20000800 ) >> 29 ;
    6925          74 :     fCompatabilityOptions_Unknown2_31                   = ( a32Bit &  0x40000800 ) >> 30 ;
    6926          74 :        fCompatabilityOptions_Unknown2_32                    = ( a32Bit &  0x80000000 ) >> 31 ;
    6927          74 : }
    6928             : 
    6929          82 : sal_uInt32 WW8Dop::GetCompatabilityOptions2() const
    6930             : {
    6931          82 :     sal_uInt32 a32Bit = 0;
    6932          82 :     if (fCompatabilityOptions_Unknown2_1)           a32Bit |= 0x00000001;
    6933          82 :     if (fCompatabilityOptions_Unknown2_2)           a32Bit |= 0x00000002;
    6934          82 :     if (fDontUseHTMLAutoSpacing)     a32Bit |= 0x00000004;
    6935          82 :     if (fCompatabilityOptions_Unknown2_4)           a32Bit |= 0x00000008;
    6936          82 :     if (fCompatabilityOptions_Unknown2_5)           a32Bit |= 0x00000010;
    6937          82 :     if (fCompatabilityOptions_Unknown2_6)           a32Bit |= 0x00000020;
    6938          82 :     if (fCompatabilityOptions_Unknown2_7)           a32Bit |= 0x00000040;
    6939          82 :     if (fCompatabilityOptions_Unknown2_8)           a32Bit |= 0x00000080;
    6940          82 :     if (fCompatabilityOptions_Unknown2_9)           a32Bit |= 0x00000100;
    6941          82 :     if (fCompatabilityOptions_Unknown2_10)          a32Bit |= 0x00000200;
    6942          82 :     if (fCompatabilityOptions_Unknown2_11)          a32Bit |= 0x00000400;
    6943          82 :     if (fCompatabilityOptions_Unknown2_12)          a32Bit |= 0x00000800;
    6944          82 :     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          82 :     if (bUseThaiLineBreakingRules)          a32Bit |= 0x00002000;
    6949          82 :     else if (fCompatabilityOptions_Unknown2_14)         a32Bit |= 0x00002000;
    6950          82 :     if (fCompatabilityOptions_Unknown2_15)          a32Bit |= 0x00004000;
    6951          82 :     if (fCompatabilityOptions_Unknown2_16)          a32Bit |= 0x00008000;
    6952          82 :     if (fCompatabilityOptions_Unknown2_17)          a32Bit |= 0x00010000;
    6953          82 :     if (fCompatabilityOptions_Unknown2_18)          a32Bit |= 0x00020000;
    6954          82 :     if (fCompatabilityOptions_Unknown2_19)          a32Bit |= 0x00040000;
    6955          82 :     if (fCompatabilityOptions_Unknown2_20)          a32Bit |= 0x00080000;
    6956          82 :     if (fCompatabilityOptions_Unknown2_21)          a32Bit |= 0x00100000;
    6957          82 :     if (fCompatabilityOptions_Unknown2_22)          a32Bit |= 0x00200000;
    6958          82 :     if (fCompatabilityOptions_Unknown2_23)          a32Bit |= 0x00400000;
    6959          82 :     if (fCompatabilityOptions_Unknown2_24)          a32Bit |= 0x00800000;
    6960          82 :     if (fCompatabilityOptions_Unknown2_25)          a32Bit |= 0x01000000;
    6961          82 :     if (fCompatabilityOptions_Unknown2_26)          a32Bit |= 0x02000000;
    6962          82 :     if (fCompatabilityOptions_Unknown2_27)          a32Bit |= 0x04000000;
    6963          82 :     if (fCompatabilityOptions_Unknown2_28)          a32Bit |= 0x08000000;
    6964          82 :     if (fCompatabilityOptions_Unknown2_29)          a32Bit |= 0x10000000;
    6965          82 :     if (fCompatabilityOptions_Unknown2_30)          a32Bit |= 0x20000000;
    6966          82 :     if (fCompatabilityOptions_Unknown2_31)          a32Bit |= 0x40000000;
    6967          82 :     if (fCompatabilityOptions_Unknown2_32)          a32Bit |= 0x80000000;
    6968          82 :     return a32Bit;
    6969             : }
    6970             : 
    6971           8 : bool WW8Dop::Write(SvStream& rStrm, WW8Fib& rFib) const
    6972             : {
    6973           8 :     const int nMaxDopLen = 610;
    6974           8 :     sal_uInt32 nLen = 8 == rFib.nVersion ? nMaxDopLen : 84;
    6975           8 :     rFib.fcDop =  rStrm.Tell();
    6976           8 :     rFib.lcbDop = nLen;
    6977             : 
    6978             :     sal_uInt8 aData[ nMaxDopLen ];
    6979           8 :     memset( aData, 0, nMaxDopLen );
    6980           8 :     sal_uInt8* pData = aData;
    6981             : 
    6982             :     // dann mal die Daten auswerten
    6983             :     sal_uInt16 a16Bit;
    6984             :     sal_uInt8   a8Bit;
    6985             : 
    6986           8 :     a16Bit = 0;                         // 0 0x00
    6987           8 :     if (fFacingPages)
    6988           2 :         a16Bit |= 0x0001;
    6989           8 :     if (fWidowControl)
    6990           8 :         a16Bit |= 0x0002;
    6991           8 :     if (fPMHMainDoc)
    6992           0 :         a16Bit |= 0x0004;
    6993           8 :     a16Bit |= ( 0x0018 & (grfSuppression << 3));
    6994           8 :     a16Bit |= ( 0x0060 & (fpc << 5));
    6995           8 :     a16Bit |= ( 0xff00 & (grpfIhdt << 8));
    6996           8 :     Set_UInt16( pData, a16Bit );
    6997             : 
    6998           8 :     a16Bit = 0;                         // 2 0x02
    6999           8 :     a16Bit |= ( 0x0003 & rncFtn );
    7000           8 :     a16Bit |= ( ~0x0003 & (nFtn << 2));
    7001           8 :     Set_UInt16( pData, a16Bit );
    7002             : 
    7003           8 :     a8Bit = 0;                          // 4 0x04
    7004           8 :     if( fOutlineDirtySave ) a8Bit |= 0x01;
    7005           8 :     Set_UInt8( pData, a8Bit );
    7006             : 
    7007           8 :     a8Bit = 0;                          // 5 0x05
    7008           8 :     if( fOnlyMacPics )  a8Bit |= 0x01;
    7009           8 :     if( fOnlyWinPics )  a8Bit |= 0x02;
    7010           8 :     if( fLabelDoc )     a8Bit |= 0x04;
    7011           8 :     if( fHyphCapitals ) a8Bit |= 0x08;
    7012           8 :     if( fAutoHyphen )   a8Bit |= 0x10;
    7013           8 :     if( fFormNoFields ) a8Bit |= 0x20;
    7014           8 :     if( fLinkStyles )   a8Bit |= 0x40;
    7015           8 :     if( fRevMarking )   a8Bit |= 0x80;
    7016           8 :     Set_UInt8( pData, a8Bit );
    7017             : 
    7018           8 :     a8Bit = 0;                          // 6 0x06
    7019           8 :     if( fBackup )               a8Bit |= 0x01;
    7020           8 :     if( fExactCWords )          a8Bit |= 0x02;
    7021           8 :     if( fPagHidden )            a8Bit |= 0x04;
    7022           8 :     if( fPagResults )           a8Bit |= 0x08;
    7023           8 :     if( fLockAtn )              a8Bit |= 0x10;
    7024           8 :     if( fMirrorMargins )        a8Bit |= 0x20;
    7025           8 :     if( fReadOnlyRecommended )  a8Bit |= 0x40;
    7026           8 :     if( fDfltTrueType )         a8Bit |= 0x80;
    7027           8 :     Set_UInt8( pData, a8Bit );
    7028             : 
    7029           8 :     a8Bit = 0;                          // 7 0x07
    7030           8 :     if( fPagSuppressTopSpacing )    a8Bit |= 0x01;
    7031           8 :     if( fProtEnabled )              a8Bit |= 0x02;
    7032           8 :     if( fDispFormFldSel )           a8Bit |= 0x04;
    7033           8 :     if( fRMView )                   a8Bit |= 0x08;
    7034           8 :     if( fRMPrint )                  a8Bit |= 0x10;
    7035           8 :     if( fWriteReservation )         a8Bit |= 0x20;
    7036           8 :     if( fLockRev )                  a8Bit |= 0x40;
    7037           8 :     if( fEmbedFonts )               a8Bit |= 0x80;
    7038           8 :     Set_UInt8( pData, a8Bit );
    7039             : 
    7040             : 
    7041           8 :     a8Bit = 0;                          // 8 0x08
    7042           8 :     if( copts_fNoTabForInd )            a8Bit |= 0x01;
    7043           8 :     if( copts_fNoSpaceRaiseLower )      a8Bit |= 0x02;
    7044           8 :     if( copts_fSupressSpbfAfterPgBrk )  a8Bit |= 0x04;
    7045           8 :     if( copts_fWrapTrailSpaces )        a8Bit |= 0x08;
    7046           8 :     if( copts_fMapPrintTextColor )      a8Bit |= 0x10;
    7047           8 :     if( copts_fNoColumnBalance )        a8Bit |= 0x20;
    7048           8 :     if( copts_fConvMailMergeEsc )       a8Bit |= 0x40;
    7049           8 :     if( copts_fSupressTopSpacing )      a8Bit |= 0x80;
    7050           8 :     Set_UInt8( pData, a8Bit );
    7051             : 
    7052           8 :     a8Bit = 0;                          // 9 0x09
    7053           8 :     if( copts_fOrigWordTableRules )     a8Bit |= 0x01;
    7054           8 :     if( copts_fTransparentMetafiles )   a8Bit |= 0x02;
    7055           8 :     if( copts_fShowBreaksInFrames )     a8Bit |= 0x04;
    7056           8 :     if( copts_fSwapBordersFacingPgs )   a8Bit |= 0x08;
    7057           8 :     if( copts_fExpShRtn )               a8Bit |= 0x20;  // #i56856#
    7058           8 :     Set_UInt8( pData, a8Bit );
    7059             : 
    7060           8 :     Set_UInt16( pData, dxaTab );        // 10 0x0a
    7061           8 :     Set_UInt16( pData, wSpare );        // 12 0x0c
    7062           8 :     Set_UInt16( pData, dxaHotZ );       // 14 0x0e
    7063           8 :     Set_UInt16( pData, cConsecHypLim ); // 16 0x10
    7064           8 :     Set_UInt16( pData, wSpare2 );       // 18 0x12
    7065           8 :     Set_UInt32( pData, dttmCreated );   // 20 0x14
    7066           8 :     Set_UInt32( pData, dttmRevised );   // 24 0x18
    7067           8 :     Set_UInt32( pData, dttmLastPrint ); // 28 0x1c
    7068           8 :     Set_UInt16( pData, nRevision );     // 32 0x20
    7069           8 :     Set_UInt32( pData, tmEdited );      // 34 0x22
    7070           8 :     Set_UInt32( pData, cWords );        // 38 0x26
    7071           8 :     Set_UInt32( pData, cCh );           // 42 0x2a
    7072           8 :     Set_UInt16( pData, cPg );           // 46 0x2e
    7073           8 :     Set_UInt32( pData, cParas );        // 48 0x30
    7074             : 
    7075           8 :     a16Bit = 0;                         // 52 0x34
    7076           8 :     a16Bit |= ( 0x0003 & rncEdn );
    7077           8 :     a16Bit |= (~0x0003 & ( nEdn << 2));
    7078           8 :     Set_UInt16( pData, a16Bit );
    7079             : 
    7080           8 :     a16Bit = 0;                         // 54 0x36
    7081           8 :     a16Bit |= (0x0003 & epc );
    7082           8 :     a16Bit |= (0x003c & (nfcFtnRef << 2));
    7083           8 :     a16Bit |= (0x03c0 & (nfcEdnRef << 6));
    7084           8 :     if( fPrintFormData )    a16Bit |= 0x0400;
    7085           8 :     if( fSaveFormData )     a16Bit |= 0x0800;
    7086           8 :     if( fShadeFormData )    a16Bit |= 0x1000;
    7087           8 :     if( fWCFtnEdn )         a16Bit |= 0x8000;
    7088           8 :     Set_UInt16( pData, a16Bit );
    7089             : 
    7090           8 :     Set_UInt32( pData, cLines );        // 56 0x38
    7091           8 :     Set_UInt32( pData, cWordsFtnEnd );  // 60 0x3c
    7092           8 :     Set_UInt32( pData, cChFtnEdn );     // 64 0x40
    7093           8 :     Set_UInt16( pData, cPgFtnEdn );     // 68 0x44
    7094           8 :     Set_UInt32( pData, cParasFtnEdn );  // 70 0x46
    7095           8 :     Set_UInt32( pData, cLinesFtnEdn );  // 74 0x4a
    7096           8 :     Set_UInt32( pData, lKeyProtDoc );   // 78 0x4e
    7097             : 
    7098           8 :     a16Bit = 0;                         // 82 0x52
    7099           8 :     if (wvkSaved)
    7100           8 :         a16Bit |= 0x0007;
    7101           8 :     a16Bit |= (0x0ff8 & (wScaleSaved << 3));
    7102           8 :     a16Bit |= (0x3000 & (zkSaved << 12));
    7103           8 :     Set_UInt16( pData, a16Bit );
    7104             : 
    7105           8 :     if( 8 == rFib.nVersion )
    7106             :     {
    7107           8 :         Set_UInt32(pData, GetCompatabilityOptions());  // 84 0x54
    7108             : 
    7109           8 :         Set_UInt16( pData, adt );                      // 88 0x58
    7110             : 
    7111           8 :         doptypography.WriteToMem(pData);               // 400 0x190
    7112             : 
    7113           8 :         memcpy( pData, &dogrid, sizeof( WW8_DOGRID ));
    7114           8 :         pData += sizeof( WW8_DOGRID );
    7115             : 
    7116           8 :         a16Bit = 0x12;      // lvl auf 9 setzen        // 410 0x19a
    7117           8 :         if( fHtmlDoc )          a16Bit |= 0x0200;
    7118           8 :         if( fSnapBorder )       a16Bit |= 0x0800;
    7119           8 :         if( fIncludeHeader )    a16Bit |= 0x1000;
    7120           8 :         if( fIncludeFooter )    a16Bit |= 0x2000;
    7121           8 :         if( fForcePageSizePag ) a16Bit |= 0x4000;
    7122           8 :         if( fMinFontSizePag )   a16Bit |= 0x8000;
    7123           8 :         Set_UInt16( pData, a16Bit );
    7124             : 
    7125           8 :         a16Bit = 0;                                    // 412 0x19c
    7126           8 :         if( fHaveVersions ) a16Bit |= 0x0001;
    7127           8 :         if( fAutoVersion )  a16Bit |= 0x0002;
    7128           8 :         Set_UInt16( pData, a16Bit );
    7129             : 
    7130           8 :         pData += 12;                                   // 414 0x19e
    7131             : 
    7132           8 :         Set_UInt32( pData, cChWS );                    // 426 0x1aa
    7133           8 :         Set_UInt32( pData, cChWSFtnEdn );              // 430 0x1ae
    7134           8 :         Set_UInt32( pData, grfDocEvents );             // 434 0x1b2
    7135             : 
    7136           8 :         pData += 4+30+8;  // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc
    7137             : 
    7138           8 :         Set_UInt32( pData, cDBC );                     // 480 0x1e0
    7139           8 :         Set_UInt32( pData, cDBCFtnEdn );               // 484 0x1e4
    7140             : 
    7141           8 :         pData += 1 * sizeof( sal_Int32);                   // 488 0x1e8
    7142             : 
    7143           8 :         Set_UInt16( pData, nfcFtnRef );                // 492 0x1ec
    7144           8 :         Set_UInt16( pData, nfcEdnRef );                // 494 0x1ee
    7145           8 :         Set_UInt16( pData, hpsZoonFontPag );           // 496 0x1f0
    7146           8 :         Set_UInt16( pData, dywDispPag );               // 498 0x1f2
    7147             : 
    7148             :         //500 -> 508, Appear to be repeated here in 2000+
    7149           8 :         pData += 8;
    7150           8 :         Set_UInt32(pData, GetCompatabilityOptions());
    7151           8 :         Set_UInt32(pData, GetCompatabilityOptions2());
    7152           8 :         pData += 32;
    7153             : 
    7154           8 :         a16Bit = 0;
    7155           8 :         if (fAcetateShowMarkup)
    7156           0 :             a16Bit |= 0x1000;
    7157             :         //Word XP at least requires fAcetateShowMarkup to honour fAcetateShowAtn
    7158           8 :         if (fAcetateShowAtn)
    7159             :         {
    7160           8 :             a16Bit |= 0x1000;
    7161           8 :             a16Bit |= 0x2000;
    7162             :         }
    7163           8 :         Set_UInt16(pData, a16Bit);
    7164             : 
    7165           8 :         pData += 48;
    7166           8 :         a16Bit = 0x0080;
    7167           8 :         Set_UInt16(pData, a16Bit);
    7168             :     }
    7169           8 :     rStrm.Write( aData, nLen );
    7170           8 :     return 0 == rStrm.GetError();
    7171             : }
    7172             : 
    7173          74 : void WW8DopTypography::ReadFromMem(sal_uInt8 *&pData)
    7174             : {
    7175          74 :     sal_uInt16 a16Bit = Get_UShort(pData);
    7176          74 :     fKerningPunct = (a16Bit & 0x0001);
    7177          74 :     iJustification = (a16Bit & 0x0006) >>  1;
    7178          74 :     iLevelOfKinsoku = (a16Bit & 0x0018) >>  3;
    7179          74 :     f2on1 = (a16Bit & 0x0020) >>  5;
    7180          74 :     reserved1 = (a16Bit & 0x03C0) >>  6;
    7181          74 :     reserved2 = (a16Bit & 0xFC00) >>  10;
    7182             : 
    7183          74 :     cchFollowingPunct = Get_Short(pData);
    7184          74 :     cchLeadingPunct = Get_Short(pData);
    7185             : 
    7186             :     sal_Int16 i;
    7187        7548 :     for (i=0; i < nMaxFollowing; ++i)
    7188        7474 :         rgxchFPunct[i] = Get_Short(pData);
    7189        3848 :     for (i=0; i < nMaxLeading; ++i)
    7190        3774 :         rgxchLPunct[i] = Get_Short(pData);
    7191             : 
    7192          74 :     if (cchFollowingPunct >= 0 && cchFollowingPunct < nMaxFollowing)
    7193          72 :         rgxchFPunct[cchFollowingPunct]=0;
    7194             :     else
    7195           2 :         rgxchFPunct[nMaxFollowing - 1]=0;
    7196             : 
    7197          74 :     if (cchLeadingPunct >= 0 && cchLeadingPunct < nMaxLeading)
    7198          74 :         rgxchLPunct[cchLeadingPunct]=0;
    7199             :     else
    7200           0 :         rgxchLPunct[nMaxLeading - 1]=0;
    7201             : 
    7202          74 : }
    7203             : 
    7204           8 : void WW8DopTypography::WriteToMem(sal_uInt8 *&pData) const
    7205             : {
    7206           8 :     sal_uInt16 a16Bit = fKerningPunct;
    7207           8 :     a16Bit |= (iJustification << 1) & 0x0006;
    7208           8 :     a16Bit |= (iLevelOfKinsoku << 3) & 0x0018;
    7209           8 :     a16Bit |= (f2on1 << 5) & 0x002;
    7210           8 :     a16Bit |= (reserved1 << 6) & 0x03C0;
    7211           8 :     a16Bit |= (reserved2 << 10) & 0xFC00;
    7212           8 :     Set_UInt16(pData,a16Bit);
    7213             : 
    7214           8 :     Set_UInt16(pData,cchFollowingPunct);
    7215           8 :     Set_UInt16(pData,cchLeadingPunct);
    7216             : 
    7217             :     sal_Int16 i;
    7218         816 :     for (i=0; i < nMaxFollowing; ++i)
    7219         808 :         Set_UInt16(pData,rgxchFPunct[i]);
    7220         416 :     for (i=0; i < nMaxLeading; ++i)
    7221         408 :         Set_UInt16(pData,rgxchLPunct[i]);
    7222           8 : }
    7223             : 
    7224          36 : 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          36 :     switch(reserved1 & 0xE)
    7238             :     {
    7239             :         case 2:     //Japan
    7240          12 :             nLang = LANGUAGE_JAPANESE;
    7241          12 :             break;
    7242             :         case 4:     //Chinese (Peoples Republic)
    7243           8 :             nLang = LANGUAGE_CHINESE_SIMPLIFIED;
    7244           8 :             break;
    7245             :         case 6:     //Korean
    7246           8 :             nLang = LANGUAGE_KOREAN;
    7247           8 :             break;
    7248             :         case 8:     //Chinese (Taiwan)
    7249           8 :             nLang = LANGUAGE_CHINESE_TRADITIONAL;
    7250           8 :             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          36 :     return nLang;
    7263             : }
    7264             : 
    7265             : //-----------------------------------------
    7266             : //              Sprms
    7267             : //-----------------------------------------
    7268      512734 : sal_uInt16 wwSprmParser::GetSprmTailLen(sal_uInt16 nId, const sal_uInt8* pSprm)
    7269             :     const
    7270             : {
    7271      512734 :     SprmInfo aSprm = GetSprmInfo(nId);
    7272      512734 :     sal_uInt16 nL = 0;                      // number of Bytes to read
    7273             : 
    7274             :     //sprmPChgTabs
    7275      512734 :     switch( nId )
    7276             :     {
    7277             :         case 23:
    7278             :         case 0xC615:
    7279        3164 :             if( pSprm[1 + mnDelta] != 255 )
    7280        3164 :                 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        3164 :             break;
    7289             :         case 0xD608:
    7290        3794 :             nL = SVBT16ToShort( &pSprm[1 + mnDelta] );
    7291        3794 :             break;
    7292             :         default:
    7293      505776 :             switch (aSprm.nVari)
    7294             :             {
    7295             :                 case L_FIX:
    7296      441144 :                     nL = aSprm.nLen;        // Excl. Token
    7297      441144 :                     break;
    7298             :                 case L_VAR:
    7299             :                     // Variable 1-Byte Length?
    7300             :                     // Excl. Token + Var-Lengthbyte
    7301       64632 :                     nL = static_cast< sal_uInt16 >(pSprm[1 + mnDelta] + aSprm.nLen);
    7302       64632 :                     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      505776 :             break;
    7313             :     }
    7314      512734 :     return nL;
    7315             : }
    7316             : 
    7317             : // one or two bytes at the beginning at the sprm id
    7318      467180 : sal_uInt16 wwSprmParser::GetSprmId(const sal_uInt8* pSp) const
    7319             : {
    7320      467180 :     ASSERT_RET_ON_FAIL(pSp, "Why GetSprmId with pSp of 0", 0);
    7321             : 
    7322      467180 :     sal_uInt16 nId = 0;
    7323             : 
    7324      467180 :     if (ww::IsSevenMinus(meVersion))
    7325             :     {
    7326           0 :         nId = *pSp;
    7327           0 :         if (0x0100 < nId)
    7328           0 :             nId = 0;
    7329             :     }
    7330             :     else
    7331             :     {
    7332      467180 :         nId = SVBT16ToShort(pSp);
    7333      467180 :         if (0x0800 > nId)
    7334        7442 :             nId = 0;
    7335             :     }
    7336             : 
    7337      467180 :     return nId;
    7338             : }
    7339             : 
    7340             : // with tokens and length byte
    7341      512734 : sal_uInt16 wwSprmParser::GetSprmSize(sal_uInt16 nId, const sal_uInt8* pSprm) const
    7342             : {
    7343      512734 :     return GetSprmTailLen(nId, pSprm) + 1 + mnDelta + SprmDataOfs(nId);
    7344             : }
    7345             : 
    7346      909172 : sal_uInt8 wwSprmParser::SprmDataOfs(sal_uInt16 nId) const
    7347             : {
    7348      909172 :     return GetSprmInfo(nId).nVari;
    7349             : }
    7350             : 
    7351      396438 : sal_uInt16 wwSprmParser::DistanceToData(sal_uInt16 nId) const
    7352             : {
    7353      396438 :     return 1 + mnDelta + SprmDataOfs(nId);
    7354             : }
    7355             : 
    7356        9642 : sal_uInt8* wwSprmParser::findSprmData(sal_uInt16 nId, sal_uInt8* pSprms,
    7357             :     sal_uInt16 nLen) const
    7358             : {
    7359       30552 :     while (nLen >= MinSprmLen())
    7360             :     {
    7361       20760 :         sal_uInt16 nAktId = GetSprmId(pSprms);
    7362             :         // gib Zeiger auf Daten
    7363       20760 :         sal_uInt16 nSize = GetSprmSize(nAktId, pSprms);
    7364             : 
    7365       20760 :         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       20760 :         if (nAktId == nId && bValid) // Sprm found
    7372        9492 :             return pSprms + DistanceToData(nId);
    7373             : 
    7374             :         //Clip to available size if wrong
    7375       11268 :         nSize = std::min(nSize, nLen);
    7376       11268 :         pSprms += nSize;
    7377       11268 :         nLen -= nSize;
    7378             :     }
    7379             :     // Sprm not found
    7380         150 :     return 0;
    7381             : }
    7382             : 
    7383         168 : 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         168 :     reserved4(0)
    7397             : {
    7398         168 :     memset(rgdxaColumnWidthSpacing, 0, sizeof(rgdxaColumnWidthSpacing));
    7399         168 : }
    7400             : 
    7401       22620 : bool checkSeek(SvStream &rSt, sal_uInt32 nOffset)
    7402             : {
    7403       22620 :     return (rSt.Seek(nOffset) == static_cast<sal_Size>(nOffset));
    7404             : }
    7405             : 
    7406        1576 : bool checkRead(SvStream &rSt, void *pDest, sal_uInt32 nLength)
    7407             : {
    7408        1576 :     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