LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - ww8scan.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 3054 3581 85.3 %
Date: 2014-04-11 Functions: 220 246 89.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10