LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - wrtw8sty.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 1059 1291 82.0 %
Date: 2014-04-11 Functions: 96 106 90.6 %
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 <algorithm>
      21             : #include <functional>
      22             : 
      23             : #include <boost/scoped_array.hpp>
      24             : #include <boost/unordered_set.hpp>
      25             : 
      26             : #include <com/sun/star/i18n/ScriptType.hpp>
      27             : #include <rtl/tencinfo.h>
      28             : #include <hintids.hxx>
      29             : #include <editeng/boxitem.hxx>
      30             : #include <editeng/fontitem.hxx>
      31             : #include <svx/svdobj.hxx>
      32             : #include <svx/svdotext.hxx>
      33             : #include <svx/fmglob.hxx>
      34             : #include <editeng/frmdiritem.hxx>
      35             : #include <editeng/lrspitem.hxx>
      36             : #include <editeng/ulspitem.hxx>
      37             : #include <doc.hxx>
      38             : #include <wrtww8.hxx>
      39             : #include <docary.hxx>
      40             : #include <poolfmt.hxx>
      41             : #include <fmtpdsc.hxx>
      42             : #include <pagedesc.hxx>
      43             : #include <ndtxt.hxx>
      44             : #include <ftninfo.hxx>
      45             : #include <fmthdft.hxx>
      46             : #include <section.hxx>
      47             : #include <fmtcntnt.hxx>
      48             : #include <fmtftn.hxx>
      49             : #include <ndindex.hxx>
      50             : #include <txtftn.hxx>
      51             : #include <charfmt.hxx>
      52             : #include <docufld.hxx>
      53             : #include <dcontact.hxx>
      54             : #include <fmtcnct.hxx>
      55             : #include <ftnidx.hxx>
      56             : #include <fmtclds.hxx>
      57             : #include <lineinfo.hxx>
      58             : #include <fmtline.hxx>
      59             : #include <swtable.hxx>
      60             : #include <msfilter.hxx>
      61             : #include <swmodule.hxx>
      62             : 
      63             : #include <filter/msfilter/sprmids.hxx>
      64             : 
      65             : #include "writerhelper.hxx"
      66             : #include "writerwordglue.hxx"
      67             : #include "../inc/wwstyles.hxx"
      68             : #include "ww8par.hxx"
      69             : #include "ww8attributeoutput.hxx"
      70             : #include "docxattributeoutput.hxx"
      71             : #include "rtfattributeoutput.hxx"
      72             : 
      73             : using namespace css;
      74             : using namespace sw::util;
      75             : using namespace nsHdFtFlags;
      76             : 
      77             : /// For the output of sections.
      78          15 : struct WW8_PdAttrDesc
      79             : {
      80             :     ::boost::scoped_array<sal_uInt8> m_pData;
      81             :     sal_uInt16 m_nLen;
      82             :     WW8_FC m_nSepxFcPos;
      83          15 :     WW8_PdAttrDesc() : m_nLen(0), m_nSepxFcPos(0xffffffff) /*default: none*/
      84          15 :         { }
      85             : };
      86             : 
      87             : struct WW8_SED
      88             : {
      89             :     SVBT16 aBits1;      // orientation change + internal, Default: 6
      90             :     SVBT32 fcSepx;      //  FC  file offset to beginning of SEPX for section.
      91             :                         //  0xFFFFFFFF for no Sprms
      92             :     SVBT16 fnMpr;       //  used internally by Windows Word, Default: 0
      93             :     SVBT32 fcMpr;       //  FC, points to offset in FC space for MacWord
      94             :                         // Default: 0xffffffff ( nothing )
      95             :                         //  cbSED is 12 (decimal)), C (hex).
      96             : };
      97             : 
      98             : // class WW8_WrPlc0 is only used for header and footer positioning
      99             : // ie there is no content support structure
     100          17 : class WW8_WrPlc0
     101             : {
     102             : private:
     103             :     std::vector<sal_uLong> aPos;      // PTRARR of CPs / FCs
     104             :     sal_uLong nOfs;
     105             : 
     106             :     //No copying
     107             :     WW8_WrPlc0(const WW8_WrPlc0&);
     108             :     WW8_WrPlc0 &operator=(const WW8_WrPlc0&);
     109             : public:
     110             :     WW8_WrPlc0( sal_uLong nOffset );
     111          17 :     sal_uInt16 Count() const                { return aPos.size(); }
     112             :     void Append( sal_uLong nStartCpOrFc );
     113             :     void Write( SvStream& rStrm );
     114             : };
     115             : 
     116             : //  Styles
     117             : 
     118             : #define WW8_RESERVED_SLOTS 15
     119             : 
     120             : // GetId( SwCharFmt ) for use in text -> zero is not allowed,
     121             : // use "Default Char Style" instead
     122         492 : sal_uInt16 MSWordExportBase::GetId( const SwCharFmt& rFmt ) const
     123             : {
     124         492 :     sal_uInt16 nRet = pStyles->GetSlot( rFmt );
     125         492 :     return ( nRet != 0x0fff ) ? nRet : 10;      // Default Char Style
     126             : }
     127             : 
     128             : // GetId( SwTxtFmtColl ) for use in TextNodes -> zero is not allowed,
     129             : // "Standard" instead
     130        6030 : sal_uInt16 MSWordExportBase::GetId( const SwTxtFmtColl& rColl ) const
     131             : {
     132        6030 :     sal_uInt16 nRet = pStyles->GetSlot( rColl );
     133        6030 :     return ( nRet != 0xfff ) ? nRet : 0;        // Default TxtFmtColl
     134             : }
     135             : 
     136             : //typedef pFmtT
     137         340 : MSWordStyles::MSWordStyles( MSWordExportBase& rExport, bool bListStyles )
     138             :     : m_rExport( rExport ),
     139         340 :     m_bListStyles(bListStyles)
     140             : {
     141             :     // if exist any Foot-/End-Notes then get from the EndNoteInfo struct
     142             :     // the CharFormats. They will create it!
     143         340 :     if ( !m_rExport.pDoc->GetFtnIdxs().empty() )
     144             :     {
     145           7 :         m_rExport.pDoc->GetEndNoteInfo().GetAnchorCharFmt( *m_rExport.pDoc );
     146           7 :         m_rExport.pDoc->GetEndNoteInfo().GetCharFmt( *m_rExport.pDoc );
     147           7 :         m_rExport.pDoc->GetFtnInfo().GetAnchorCharFmt( *m_rExport.pDoc );
     148           7 :         m_rExport.pDoc->GetFtnInfo().GetCharFmt( *m_rExport.pDoc );
     149             :     }
     150         340 :     sal_uInt16 nAlloc = WW8_RESERVED_SLOTS + m_rExport.pDoc->GetCharFmts()->size() - 1 +
     151         340 :                                          m_rExport.pDoc->GetTxtFmtColls()->size() - 1 +
     152         680 :                                          (bListStyles ? m_rExport.pDoc->GetNumRuleTbl().size() - 1 : 0);
     153             : 
     154             :     // somewhat generous ( free for up to 15 )
     155         340 :     pFmtA = new SwFmt*[ nAlloc ];
     156         340 :     memset( pFmtA, 0, nAlloc * sizeof( SwFmt* ) );
     157             : 
     158         340 :     BuildStylesTable();
     159         340 :     BuildStyleIds();
     160         340 : }
     161             : 
     162         568 : MSWordStyles::~MSWordStyles()
     163             : {
     164         284 :     delete[] pFmtA;
     165         284 : }
     166             : 
     167             : // Sty_SetWWSlot() dependencies for the styles -> zero is allowed
     168       17370 : sal_uInt16 MSWordStyles::GetSlot( const SwFmt& rFmt ) const
     169             : {
     170             :     sal_uInt16 n;
     171      384448 :     for ( n = 0; n < nUsedSlots; n++ )
     172      383256 :         if ( pFmtA[n] == &rFmt )
     173       16178 :             return n;
     174        1192 :     return 0xfff;                   // 0xfff: WW: zero
     175             : }
     176             : 
     177        5424 : sal_uInt16 MSWordStyles::BuildGetSlot( const SwFmt& rFmt )
     178             : {
     179             :     sal_uInt16 nRet;
     180        5424 :     switch ( nRet = rFmt.GetPoolFmtId() )
     181             :     {
     182             :         case RES_POOLCOLL_STANDARD:
     183         340 :             nRet = 0;
     184         340 :             break;
     185             : 
     186             :         case RES_POOLCOLL_HEADLINE1:
     187             :         case RES_POOLCOLL_HEADLINE2:
     188             :         case RES_POOLCOLL_HEADLINE3:
     189             :         case RES_POOLCOLL_HEADLINE4:
     190             :         case RES_POOLCOLL_HEADLINE5:
     191             :         case RES_POOLCOLL_HEADLINE6:
     192             :         case RES_POOLCOLL_HEADLINE7:
     193             :         case RES_POOLCOLL_HEADLINE8:
     194             :         case RES_POOLCOLL_HEADLINE9:
     195         262 :             nRet -= RES_POOLCOLL_HEADLINE1-1;
     196         262 :             break;
     197             : 
     198             :         default:
     199        4822 :             nRet = nUsedSlots++;
     200        4822 :             break;
     201             :     }
     202        5424 :     return nRet;
     203             : }
     204             : 
     205        4264 : sal_uInt16 MSWordStyles::BuildGetSlot(const SwNumRule&)
     206             : {
     207        4264 :     return nUsedSlots++;
     208             : }
     209             : 
     210        5424 : sal_uInt16 MSWordStyles::GetWWId( const SwFmt& rFmt ) const
     211             : {
     212        5424 :     sal_uInt16 nRet = ww::stiUser;    // User-Style als default
     213        5424 :     sal_uInt16 nPoolId = rFmt.GetPoolFmtId();
     214        5424 :     if( nPoolId == RES_POOLCOLL_STANDARD )
     215         340 :         nRet = 0;
     216        5084 :     else if( nPoolId >= RES_POOLCOLL_HEADLINE1 &&
     217             :              nPoolId <= RES_POOLCOLL_HEADLINE9 )
     218         262 :         nRet = static_cast< sal_uInt16 >(nPoolId + 1 - RES_POOLCOLL_HEADLINE1);
     219        4822 :     else if( nPoolId >= RES_POOLCOLL_TOX_IDX1 &&
     220             :              nPoolId <= RES_POOLCOLL_TOX_IDX3 )
     221           0 :         nRet = static_cast< sal_uInt16 >(nPoolId + 10 - RES_POOLCOLL_TOX_IDX1);
     222        4822 :     else if( nPoolId >= RES_POOLCOLL_TOX_CNTNT1 &&
     223             :              nPoolId <= RES_POOLCOLL_TOX_CNTNT5 )
     224          93 :         nRet = static_cast< sal_uInt16 >(nPoolId + 19 - RES_POOLCOLL_TOX_CNTNT1);
     225        4729 :     else if( nPoolId >= RES_POOLCOLL_TOX_CNTNT6 &&
     226             :              nPoolId <= RES_POOLCOLL_TOX_CNTNT9 )
     227          41 :         nRet = static_cast< sal_uInt16 >(nPoolId + 24 - RES_POOLCOLL_TOX_CNTNT6);
     228             :     else
     229        4688 :         switch( nPoolId )
     230             :         {
     231           9 :         case RES_POOLCOLL_FOOTNOTE:         nRet = 29;  break;
     232           0 :         case RES_POOLCOLL_MARGINAL:         nRet = 30;  break;
     233          88 :         case RES_POOLCOLL_HEADER:           nRet = 31;  break;
     234          89 :         case RES_POOLCOLL_FOOTER:           nRet = 32;  break;
     235           1 :         case RES_POOLCOLL_TOX_IDXH:         nRet = 33;  break;
     236         338 :         case RES_POOLCOLL_LABEL:            nRet = 34;  break;
     237           1 :         case RES_POOLCOLL_LABEL_DRAWING:    nRet = 35;  break;
     238           0 :         case RES_POOLCOLL_JAKETADRESS:      nRet = 36;  break;
     239           0 :         case RES_POOLCOLL_SENDADRESS:       nRet = 37;  break;
     240           2 :         case RES_POOLCOLL_ENDNOTE:          nRet = 43;  break;
     241           0 :         case RES_POOLCOLL_TOX_AUTHORITIESH: nRet = 44;  break;
     242          22 :         case RES_POOLCOLL_TOX_CNTNTH:       nRet = 46;  break;
     243           0 :         case RES_POOLCOLL_BUL_LEVEL1:       nRet = 48;  break;
     244         338 :         case RES_POOLCOLL_LISTS_BEGIN:      nRet = 47;  break;
     245           1 :         case RES_POOLCOLL_NUM_LEVEL1:       nRet = 49;  break;
     246           3 :         case RES_POOLCOLL_BUL_LEVEL2:       nRet = 54;  break;
     247           3 :         case RES_POOLCOLL_BUL_LEVEL3:       nRet = 55;  break;
     248           3 :         case RES_POOLCOLL_BUL_LEVEL4:       nRet = 56;  break;
     249           3 :         case RES_POOLCOLL_BUL_LEVEL5:       nRet = 57;  break;
     250           1 :         case RES_POOLCOLL_NUM_LEVEL2:       nRet = 58;  break;
     251           1 :         case RES_POOLCOLL_NUM_LEVEL3:       nRet = 59;  break;
     252           0 :         case RES_POOLCOLL_NUM_LEVEL4:       nRet = 60;  break;
     253           1 :         case RES_POOLCOLL_NUM_LEVEL5:       nRet = 61;  break;
     254          26 :         case RES_POOLCOLL_DOC_TITEL:        nRet = 62;  break;
     255           3 :         case RES_POOLCOLL_SIGNATURE:        nRet = 64;  break;
     256         339 :         case RES_POOLCOLL_TEXT:             nRet = 66;  break;
     257          17 :         case RES_POOLCOLL_TEXT_MOVE:        nRet = 67;  break;
     258           0 :         case RES_POOLCOLL_BUL_NONUM1:       nRet = 68;  break;
     259           0 :         case RES_POOLCOLL_BUL_NONUM2:       nRet = 69;  break;
     260           0 :         case RES_POOLCOLL_BUL_NONUM3:       nRet = 70;  break;
     261           0 :         case RES_POOLCOLL_BUL_NONUM4:       nRet = 71;  break;
     262           0 :         case RES_POOLCOLL_BUL_NONUM5:       nRet = 72;  break;
     263          16 :         case RES_POOLCOLL_DOC_SUBTITEL:     nRet = 74;  break;
     264           3 :         case RES_POOLCOLL_GREETING:         nRet = 75;  break;
     265           1 :         case RES_POOLCOLL_TEXT_IDENT:       nRet = 77;  break;
     266             : 
     267           9 :         case RES_POOLCHR_FOOTNOTE_ANCHOR:   nRet = 38;  break;
     268           9 :         case RES_POOLCHR_ENDNOTE_ANCHOR:    nRet = 42;  break;
     269          56 :         case RES_POOLCHR_INET_NORMAL:       nRet = 85;  break;
     270           1 :         case RES_POOLCHR_INET_VISIT:        nRet = 86;  break;
     271           2 :         case RES_POOLCHR_HTML_STRONG:       nRet = 87;  break;
     272          14 :         case RES_POOLCHR_HTML_EMPHASIS:     nRet = 88;  break;
     273           3 :         case RES_POOLCHR_LINENUM:           nRet = 40;  break;
     274           1 :         case RES_POOLCHR_PAGENO:            nRet = 41;  break;
     275             :         }
     276        5424 :     return nRet;
     277             : }
     278             : 
     279         340 : void MSWordStyles::BuildStylesTable()
     280             : {
     281         340 :     nUsedSlots = WW8_RESERVED_SLOTS;    // soviele sind reserviert fuer
     282             :                                         // Standard und HeadingX u.a.
     283         340 :     const SwCharFmts& rArr = *m_rExport.pDoc->GetCharFmts();       // first CharFmt
     284             :     // das Default-ZeichenStyle ( 0 ) wird nicht mit ausgegeben !
     285        1889 :     for( sal_uInt16 n = 1; n < rArr.size(); n++ )
     286             :     {
     287        1549 :         SwCharFmt* pFmt = rArr[n];
     288        1549 :         pFmtA[ BuildGetSlot( *pFmt ) ] = pFmt;
     289             :     }
     290             : 
     291         340 :     const SwTxtFmtColls& rArr2 = *m_rExport.pDoc->GetTxtFmtColls();   // then TxtFmtColls
     292             :     // das Default-TextStyle ( 0 ) wird nicht mit ausgegeben !
     293        4215 :     for( sal_uInt16 n = 1; n < rArr2.size(); n++ )
     294             :     {
     295        3875 :         SwTxtFmtColl* pFmt = rArr2[n];
     296        3875 :         pFmtA[ BuildGetSlot( *pFmt ) ] = pFmt;
     297             :     }
     298             : 
     299         340 :     if (!m_bListStyles)
     300         408 :         return;
     301             : 
     302         272 :     const SwNumRuleTbl& rNumRuleTbl = m_rExport.pDoc->GetNumRuleTbl();
     303        5531 :     for (size_t i = 0; i < rNumRuleTbl.size(); ++i)
     304             :     {
     305        5259 :         const SwNumRule* pNumRule = rNumRuleTbl[i];
     306        5259 :         if (pNumRule->IsAutoRule() || pNumRule->GetName().startsWith("WWNum"))
     307         995 :             continue;
     308        4264 :         sal_uInt16 nSlot = BuildGetSlot(*pNumRule);
     309        4264 :         m_aNumRules[nSlot] = pNumRule;
     310             :     }
     311             : }
     312             : 
     313         340 : void MSWordStyles::BuildStyleIds()
     314             : {
     315         340 :     boost::unordered_set<OString, OStringHash> aUsed;
     316             : 
     317         340 :     m_aStyleIds.push_back("Normal");
     318         340 :     aUsed.insert("normal");
     319             : 
     320       14186 :     for (sal_uInt16 n = 1; n < nUsedSlots; ++n)
     321             :     {
     322       13846 :         const OUString aName(pFmtA[n]? pFmtA[n]->GetName(): (m_aNumRules.find(n) != m_aNumRules.end() ? m_aNumRules[n]->GetName() : OUString()));
     323             : 
     324       27692 :         OStringBuffer aStyleIdBuf(aName.getLength());
     325      117553 :         for (int i = 0; i < aName.getLength(); ++i)
     326             :         {
     327      103707 :             sal_Unicode nChar = aName[i];
     328      103707 :             if (('0' <= nChar && nChar <= '9') ||
     329       56754 :                 ('a' <= nChar && nChar <= 'z') ||
     330       17841 :                 ('A' <= nChar && nChar <= 'Z'))
     331             :             {
     332             :                 // first letter should be uppercase
     333       94142 :                 if (aStyleIdBuf.isEmpty() && 'a' <= nChar && nChar <= 'z')
     334         327 :                     aStyleIdBuf.append(char(nChar - ('a' - 'A')));
     335             :                 else
     336       93815 :                     aStyleIdBuf.append(char(nChar));
     337             :             }
     338             :         }
     339             : 
     340       27692 :         OString aStyleId(aStyleIdBuf.makeStringAndClear());
     341       13846 :         if (aStyleId.isEmpty())
     342        4548 :             aStyleId = "Style";
     343             : 
     344       27692 :         OString aLower(aStyleId.toAsciiLowerCase());
     345             : 
     346             :         // check for uniqueness & construct something unique if we have to
     347       13846 :         if (aUsed.find(aLower) == aUsed.end())
     348             :         {
     349        9591 :             aUsed.insert(aLower);
     350        9591 :             m_aStyleIds.push_back(aStyleId);
     351             :         }
     352             :         else
     353             :         {
     354        4255 :             int nFree = 1;
     355       33200 :             while (aUsed.find(aLower + OString::number(nFree)) != aUsed.end())
     356       24690 :                 ++nFree;
     357             : 
     358        4255 :             aUsed.insert(aLower + OString::number(nFree));
     359        4255 :             m_aStyleIds.push_back(aStyleId + OString::number(nFree));
     360             :         }
     361       14186 :     }
     362         340 : }
     363             : 
     364       19268 : OString MSWordStyles::GetStyleId(sal_uInt16 nId) const
     365             : {
     366       19268 :     return m_aStyleIds[nId];
     367             : }
     368             : 
     369             : /// For WW8 only - extend pO so that the size of pTableStrm is even.
     370         552 : static void impl_SkipOdd( ww::bytes* pO, sal_Size nTableStrmTell )
     371             : {
     372         552 :     if ( ( nTableStrmTell + pO->size() ) & 1 )     // Start auf gerader
     373         308 :         pO->push_back( (sal_uInt8)0 );         // Address
     374         552 : }
     375             : 
     376         217 : void WW8AttributeOutput::EndStyle()
     377             : {
     378         217 :     impl_SkipOdd( m_rWW8Export.pO, m_rWW8Export.pTableStrm->Tell() );
     379             : 
     380         217 :     short nLen = m_rWW8Export.pO->size() - 2;            // length of the style
     381         217 :     sal_uInt8* p = &m_rWW8Export.pO->front() + nPOPosStdLen1;
     382         217 :     ShortToSVBT16( nLen, p );               // nachtragen
     383         217 :     p = &m_rWW8Export.pO->front() + nPOPosStdLen2;
     384         217 :     ShortToSVBT16( nLen, p );               // dito
     385             : 
     386         217 :     m_rWW8Export.pTableStrm->Write( m_rWW8Export.pO->data(), m_rWW8Export.pO->size() );      // write it into the file
     387         217 :     m_rWW8Export.pO->clear();
     388         217 : }
     389             : 
     390         217 : void WW8AttributeOutput::StartStyle( const OUString& rName, StyleType eType, sal_uInt16 nWwBase,
     391             :     sal_uInt16 nWwNext, sal_uInt16 nWwId, sal_uInt16 /*nId*/, bool bAutoUpdate )
     392             : {
     393             :     sal_uInt8 aWW8_STD[ sizeof( WW8_STD ) ];
     394         217 :     sal_uInt8* pData = aWW8_STD;
     395         217 :     memset( &aWW8_STD, 0, sizeof( WW8_STD ) );
     396             : 
     397         217 :     sal_uInt16 nBit16 = 0x1000;         // fInvalHeight
     398         217 :     nBit16 |= (ww::stiNil & nWwId);
     399         217 :     Set_UInt16( pData, nBit16 );
     400             : 
     401         217 :     nBit16 = nWwBase << 4;          // istdBase
     402         217 :     nBit16 |= (eType == STYLE_TYPE_PARA ? 1 : 2);      // sgc
     403         217 :     Set_UInt16( pData, nBit16 );
     404             : 
     405         217 :     nBit16 = nWwNext << 4;          // istdNext
     406         217 :     nBit16 |= (eType == STYLE_TYPE_PARA ? 2 : 1);      // cupx
     407         217 :     Set_UInt16( pData, nBit16 );
     408             : 
     409         217 :     pData += sizeof( sal_uInt16 );      // bchUpe
     410             : 
     411         217 :     if( m_rWW8Export.bWrtWW8 )
     412             :     {
     413         217 :         nBit16 = bAutoUpdate ? 1 : 0;  // fAutoRedef : 1
     414         217 :         Set_UInt16( pData, nBit16 );
     415             :         //-------- jetzt neu:
     416             :         // ab Ver8 gibts zwei Felder mehr:
     417             :         //sal_uInt16    fHidden : 1;       /* hidden from UI? */
     418             :         //sal_uInt16    : 14;              /* unused bits */
     419             :     }
     420             : 
     421         217 :     sal_uInt16 nLen = static_cast< sal_uInt16 >( ( pData - aWW8_STD ) + 1 +
     422         217 :                 ((m_rWW8Export.bWrtWW8 ? 2 : 1 ) * (rName.getLength() + 1)) );  // temporary
     423             : 
     424         217 :     nPOPosStdLen1 = m_rWW8Export.pO->size();        // Adr1 zum nachtragen der Laenge
     425             : 
     426         217 :     SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nLen );
     427         217 :     m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), aWW8_STD, pData );
     428             : 
     429         217 :     nPOPosStdLen2 = nPOPosStdLen1 + 8;  // Adr2 zum nachtragen von "end of upx"
     430             : 
     431             :     // write names
     432         217 :     if( m_rWW8Export.bWrtWW8 )
     433             :     {
     434         217 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, rName.getLength() ); // length
     435         217 :         SwWW8Writer::InsAsString16( *m_rWW8Export.pO, rName );
     436             :     }
     437             :     else
     438             :     {
     439           0 :         m_rWW8Export.pO->push_back( (sal_uInt8)rName.getLength() );       // length
     440           0 :         SwWW8Writer::InsAsString8( *m_rWW8Export.pO, rName, RTL_TEXTENCODING_MS_1252 );
     441             :     }
     442         217 :     m_rWW8Export.pO->push_back( (sal_uInt8)0 );             // Trotz P-String 0 am Ende!
     443         217 : }
     444             : 
     445        1042 : void MSWordStyles::SetStyleDefaults( const SwFmt& rFmt, bool bPap )
     446             : {
     447        1042 :     const SwModify* pOldMod = m_rExport.pOutFmtNode;
     448        1042 :     m_rExport.pOutFmtNode = &rFmt;
     449             :     bool aFlags[ static_cast< sal_uInt16 >(RES_FRMATR_END) - RES_CHRATR_BEGIN ];
     450             :     sal_uInt16 nStt, nEnd, n;
     451        1042 :     if( bPap )
     452         521 :        nStt = RES_PARATR_BEGIN, nEnd = RES_FRMATR_END;
     453             :     else
     454         521 :        nStt = RES_CHRATR_BEGIN, nEnd = RES_TXTATR_END;
     455             : 
     456             :     // dynamic defaults
     457        1042 :     const SfxItemPool& rPool = *rFmt.GetAttrSet().GetPool();
     458       68251 :     for( n = nStt; n < nEnd; ++n )
     459       67209 :         aFlags[ n - RES_CHRATR_BEGIN ] = 0 != rPool.GetPoolDefaultItem( n );
     460             : 
     461             :     // static defaults, that differs between WinWord and SO
     462        1042 :     if( bPap )
     463             :     {
     464         521 :         aFlags[ static_cast< sal_uInt16 >(RES_PARATR_WIDOWS) - RES_CHRATR_BEGIN ] = true;
     465         521 :         aFlags[ static_cast< sal_uInt16 >(RES_PARATR_HYPHENZONE) - RES_CHRATR_BEGIN ] = true;
     466             :     }
     467             :     else
     468             :     {
     469         521 :         aFlags[ RES_CHRATR_FONTSIZE - RES_CHRATR_BEGIN ] = true;
     470         521 :         aFlags[ RES_CHRATR_LANGUAGE - RES_CHRATR_BEGIN ] = true;
     471             :     }
     472             : 
     473        1042 :     const SfxItemSet* pOldI = m_rExport.GetCurItemSet();
     474        1042 :     m_rExport.SetCurItemSet( &rFmt.GetAttrSet() );
     475             : 
     476        1042 :     const bool* pFlags = aFlags + ( nStt - RES_CHRATR_BEGIN );
     477       68251 :     for ( n = nStt; n < nEnd; ++n, ++pFlags )
     478             :     {
     479       76442 :         if ( *pFlags && !m_rExport.ignoreAttributeForStyles( n )
     480       76014 :             && SFX_ITEM_SET != rFmt.GetItemState(n, false))
     481             :         {
     482             :             //If we are a character property then see if it is one of the
     483             :             //western/asian ones that must be collapsed together for export to
     484             :             //word. If so default to the western variant.
     485       11520 :             if ( bPap || m_rExport.CollapseScriptsforWordOk(
     486        4663 :                 i18n::ScriptType::LATIN, n) )
     487             :             {
     488        6515 :                 m_rExport.AttrOutput().OutputItem( rFmt.GetFmtAttr( n, true ) );
     489             :             }
     490             :         }
     491             :     }
     492             : 
     493        1042 :     m_rExport.SetCurItemSet( pOldI );
     494        1042 :     m_rExport.pOutFmtNode = pOldMod;
     495        1042 : }
     496             : 
     497         335 : void WW8AttributeOutput::StartStyleProperties( bool bParProp, sal_uInt16 nStyle )
     498             : {
     499         335 :     impl_SkipOdd( m_rWW8Export.pO, m_rWW8Export.pTableStrm->Tell() );
     500             : 
     501         335 :     sal_uInt16 nLen = ( bParProp ) ? 2 : 0;             // default length
     502         335 :     m_nStyleLenPos = m_rWW8Export.pO->size();               // Laenge zum Nachtragen
     503             :                                     // Keinen Pointer merken, da sich bei
     504             :                                     // _grow der Pointer aendert !
     505             : 
     506         335 :     SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nLen );        // Style-Len
     507             : 
     508         335 :     m_nStyleStartSize = m_rWW8Export.pO->size();
     509             : 
     510         335 :     if ( bParProp )
     511         118 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nStyle );     // Style-Nummer
     512         335 : }
     513             : 
     514        9299 : void MSWordStyles::WriteProperties( const SwFmt* pFmt, bool bParProp, sal_uInt16 nPos,
     515             :     bool bInsDefCharSiz )
     516             : {
     517        9299 :     m_rExport.AttrOutput().StartStyleProperties( bParProp, nPos );
     518             : 
     519             :     OSL_ENSURE( m_rExport.pCurrentStyle == NULL, "Current style not NULL" ); // set current style before calling out
     520        9299 :     m_rExport.pCurrentStyle = pFmt;
     521             : 
     522        9299 :     m_rExport.OutputFormat( *pFmt, bParProp, !bParProp );
     523             : 
     524             :     OSL_ENSURE( m_rExport.pCurrentStyle == pFmt, "current style was changed" );
     525             :     // reset current style...
     526        9299 :     m_rExport.pCurrentStyle = NULL;
     527             : 
     528        9299 :     if ( bInsDefCharSiz  )                   // not derived from other Style
     529        1042 :         SetStyleDefaults( *pFmt, bParProp );
     530             : 
     531        9299 :     m_rExport.AttrOutput().EndStyleProperties( bParProp );
     532        9299 : }
     533             : 
     534         335 : void WW8AttributeOutput::EndStyleProperties( bool /*bParProp*/ )
     535             : {
     536         335 :     sal_uInt16 nLen = m_rWW8Export.pO->size() - m_nStyleStartSize;
     537         335 :     sal_uInt8* pUpxLen = &m_rWW8Export.pO->front() + m_nStyleLenPos; // Laenge zum Nachtragen
     538         335 :     ShortToSVBT16( nLen, pUpxLen );                 // add default length
     539         335 : }
     540             : 
     541        5424 : void MSWordStyles::GetStyleData( SwFmt* pFmt, bool& bFmtColl, sal_uInt16& nBase, sal_uInt16& nNext )
     542             : {
     543        5424 :     bFmtColl = pFmt->Which() == RES_TXTFMTCOLL || pFmt->Which() == RES_CONDTXTFMTCOLL;
     544             : 
     545             :     // Default: none
     546        5424 :     nBase = 0xfff;
     547             : 
     548             :     // Derived from?
     549        5424 :     if ( !pFmt->IsDefault() )
     550        5424 :         nBase = GetSlot( *pFmt->DerivedFrom() );
     551             : 
     552             :     SwFmt* pNext;
     553        5424 :     if ( bFmtColl )
     554        3875 :         pNext = &((SwTxtFmtColl*)pFmt)->GetNextTxtFmtColl();
     555             :     else
     556        1549 :         pNext = pFmt; // CharFmt: next CharFmt == self
     557             : 
     558        5424 :     nNext = GetSlot( *pNext );
     559        5424 : }
     560             : 
     561         163 : void WW8AttributeOutput::DefaultStyle( sal_uInt16 nStyle )
     562             : {
     563         163 :     if ( nStyle == 10 )           // Default Char-Style ( only WW )
     564             :     {
     565          12 :         if ( m_rWW8Export.bWrtWW8 )
     566             :         {
     567          12 :             sal_uInt16 n = 0;
     568          12 :             m_rWW8Export.pTableStrm->Write( &n , 2 );   // empty Style
     569             :         }
     570             :         else
     571             :         {
     572             :             static sal_uInt8 aDefCharSty[] = {
     573             :                 0x26, 0x00,
     574             :                 0x41, 0x40, 0xF2, 0xFF, 0xA1, 0x00, 0x26, 0x00,
     575             :                 0x19, 0x41, 0x62, 0x73, 0x61, 0x74, 0x7A, 0x2D,
     576             :                 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64,
     577             :                 0x73, 0x63, 0x68, 0x72, 0x69, 0x66, 0x74, 0x61,
     578             :                 0x72, 0x74, 0x00, 0x00, 0x00, 0x00 };
     579           0 :             m_rWW8Export.pTableStrm->Write( &aDefCharSty, sizeof( aDefCharSty ) );
     580             :         }
     581             :     }
     582             :     else
     583             :     {
     584         151 :         sal_uInt16 n = 0;
     585         151 :         m_rWW8Export.pTableStrm->Write( &n , 2 );   // empty Style
     586             :     }
     587         163 : }
     588             : 
     589        4255 : void MSWordStyles::OutputStyle(const SwNumRule* pNumRule, sal_uInt16 nPos)
     590             : {
     591        4255 :     m_rExport.AttrOutput().StartStyle( pNumRule->GetName(), STYLE_TYPE_LIST,
     592             :             /*nBase =*/ 0, /*nWwNext =*/ 0, /*nWWId =*/ 0, nPos,
     593        8510 :             /*bAutoUpdateFmt =*/ false );
     594             : 
     595        4255 :     m_rExport.AttrOutput().EndStyle();
     596        4255 : }
     597             : 
     598             : // OutputStyle applies for TxtFmtColls and CharFmts
     599        9922 : void MSWordStyles::OutputStyle( SwFmt* pFmt, sal_uInt16 nPos )
     600             : {
     601        9922 :     if ( !pFmt )
     602        4498 :         m_rExport.AttrOutput().DefaultStyle( nPos );
     603             :     else
     604             :     {
     605             :         bool bFmtColl;
     606             :         sal_uInt16 nBase, nWwNext;
     607             : 
     608        5424 :         GetStyleData( pFmt, bFmtColl, nBase, nWwNext );
     609             : 
     610        5424 :         OUString aName = pFmt->GetName();
     611             :         // We want to map LO's default style to Word's "Normal" style.
     612             :         // Word looks for this specific style name when reading docx files.
     613             :         // (It must be the English word regardless of language settings)
     614        5424 :         if ( nPos == 0 )
     615             :         {
     616             :             assert( pFmt->GetPoolFmtId() == RES_POOLCOLL_STANDARD );
     617         340 :             aName = "Normal";
     618             :         }
     619        5084 :         else if (aName.equalsIgnoreAsciiCase("Normal"))
     620             :         {
     621             :             // If LO has a style named "Normal"(!) rename it to something unique
     622           0 :             const OUString aBaseName = "LO-" + aName;
     623           0 :             aName = aBaseName;
     624             :             // Check if we still have a clash, in which case we add a suffix
     625           0 :             for ( int nSuffix = 0; ; ++nSuffix ) {
     626           0 :                 bool clash=false;
     627           0 :                 for ( sal_uInt16 n = 1; n < nUsedSlots; ++n )
     628           0 :                     if ( pFmtA[n] &&
     629           0 :                          pFmtA[n]->GetName().equalsIgnoreAsciiCase(aName) )
     630             :                     {
     631           0 :                         clash = true;
     632           0 :                         break;
     633             :                     }
     634           0 :                 if (!clash)
     635           0 :                     break;
     636             :                 // TODO: verify if we really need to increment nSuffix in 2 places
     637           0 :                 aName = aBaseName + OUString::number(++nSuffix);
     638           0 :             }
     639             :         }
     640             : 
     641        5424 :         m_rExport.AttrOutput().StartStyle( aName, (bFmtColl ? STYLE_TYPE_PARA : STYLE_TYPE_CHAR),
     642        5424 :                 nBase, nWwNext, GetWWId( *pFmt ), nPos,
     643       16272 :                 pFmt->IsAutoUpdateFmt() );
     644             : 
     645        5424 :         if ( bFmtColl )
     646        3875 :             WriteProperties( pFmt, true, nPos, nBase==0xfff );           // UPX.papx
     647             : 
     648        5424 :         WriteProperties( pFmt, false, nPos, bFmtColl && nBase==0xfff );  // UPX.chpx
     649             : 
     650        5424 :         m_rExport.AttrOutput().EndStyle();
     651             :     }
     652        9922 : }
     653             : 
     654          12 : void WW8AttributeOutput::StartStyles()
     655             : {
     656          12 :     WW8Fib& rFib = *m_rWW8Export.pFib;
     657             : 
     658          12 :     sal_uLong nCurPos = m_rWW8Export.pTableStrm->Tell();
     659          12 :     if ( nCurPos & 1 )                   // Start auf gerader
     660             :     {
     661           0 :         m_rWW8Export.pTableStrm->WriteChar( (char)0 );        // Address
     662           0 :         ++nCurPos;
     663             :     }
     664          12 :     rFib.fcStshfOrig = rFib.fcStshf = nCurPos;
     665          12 :     m_nStyAnzPos = nCurPos + 2;     // Anzahl wird nachgetragen
     666             : 
     667          12 :     if ( m_rWW8Export.bWrtWW8 )
     668             :     {
     669             :         static sal_uInt8 aStShi[] = {
     670             :             0x12, 0x00,
     671             :             0x0F, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x5B, 0x00,
     672             :             0x0F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
     673             :             0x00, 0x00 };
     674             : 
     675          12 :         m_rWW8Export.pTableStrm->Write( &aStShi, sizeof( aStShi ) );
     676             :     }
     677             :     else
     678             :     {
     679             :         static sal_uInt8 aStShi[] = {
     680             :             0x0E, 0x00,
     681             :             0x0F, 0x00, 0x08, 0x00, 0x01, 0x00, 0x4B, 0x00,
     682             :             0x0F, 0x00, 0x00, 0x00, 0x00, 0x00 };
     683           0 :         m_rWW8Export.pTableStrm->Write( &aStShi, sizeof( aStShi ) );
     684             :     }
     685          12 : }
     686             : 
     687          12 : void WW8AttributeOutput::EndStyles( sal_uInt16 nNumberOfStyles )
     688             : {
     689          12 :     WW8Fib& rFib = *m_rWW8Export.pFib;
     690             : 
     691          12 :     rFib.lcbStshfOrig = rFib.lcbStshf = m_rWW8Export.pTableStrm->Tell() - rFib.fcStshf;
     692          12 :     SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, m_nStyAnzPos, nNumberOfStyles );
     693          12 : }
     694             : 
     695         340 : void MSWordStyles::OutputStylesTable()
     696             : {
     697         340 :     m_rExport.bStyDef = true;
     698             : 
     699         340 :     m_rExport.AttrOutput().StartStyles();
     700             : 
     701             :     sal_uInt16 n;
     702             :     // HACK
     703             :     // Ms Office seems to have an internal limitation of 4091 styles
     704             :     // and refuses to load .docx with more, even though the spec seems to allow that;
     705             :     // so simply if there are more styles, don't export those
     706             :     // Implementing check for all exports DOCX, DOC, RTF
     707         340 :     sal_uInt16 nLimit = MSWORD_MAX_STYLES_LIMIT;
     708         340 :     nUsedSlots = (nLimit > nUsedSlots)? nUsedSlots : nLimit;
     709             : 
     710       14517 :     for ( n = 0; n < nUsedSlots; n++ )
     711             :     {
     712       14177 :         if (m_aNumRules.find(n) != m_aNumRules.end())
     713        4255 :             OutputStyle(m_aNumRules[n], n);
     714             :         else
     715        9922 :             OutputStyle( pFmtA[n], n );
     716             :     }
     717             : 
     718         340 :     m_rExport.AttrOutput().EndStyles( nUsedSlots );
     719             : 
     720         340 :     m_rExport.bStyDef = false;
     721         340 : }
     722             : 
     723        4255 : const SwNumRule* MSWordStyles::GetSwNumRule(sal_uInt16 nId) const
     724             : {
     725        4255 :     std::map<sal_uInt16, const SwNumRule*>::const_iterator it = m_aNumRules.find(nId);
     726             :     assert(it != m_aNumRules.end());
     727        4255 :     return it->second;
     728             : }
     729             : 
     730             : //          Fonts
     731             : 
     732        9845 : wwFont::wwFont(const OUString &rFamilyName, FontPitch ePitch, FontFamily eFamily,
     733        9845 :     rtl_TextEncoding eChrSet, bool bWrtWW8) : mbAlt(false), mbWrtWW8(bWrtWW8), mePitch(ePitch), meFamily(eFamily), meChrSet(eChrSet)
     734             : {
     735        9845 :     FontMapExport aResult(rFamilyName);
     736        9845 :     msFamilyNm = aResult.msPrimary;
     737        9845 :     msAltNm = aResult.msSecondary;
     738       11525 :     if (!msAltNm.isEmpty() && msAltNm != msFamilyNm &&
     739        1680 :         (msFamilyNm.getLength() + msAltNm.getLength() + 2 <= 65) )
     740             :     {
     741             :         //max size of szFfn in 65 chars
     742        1680 :         mbAlt = true;
     743             :     }
     744             : 
     745        9845 :     memset(maWW8_FFN, 0, sizeof(maWW8_FFN));
     746             : 
     747        9845 :     if (bWrtWW8)
     748             :     {
     749        9845 :         maWW8_FFN[0] = (sal_uInt8)( 6 - 1 + 0x22 + ( 2 * ( 1 + msFamilyNm.getLength() ) ));
     750        9845 :         if (mbAlt)
     751        1680 :             maWW8_FFN[0] = static_cast< sal_uInt8 >(maWW8_FFN[0] + 2 * ( 1 + msAltNm.getLength()));
     752             :     }
     753             :     else
     754             :     {
     755           0 :         maWW8_FFN[0] = (sal_uInt8)( 6 - 1 + 1 + msFamilyNm.getLength() );
     756           0 :         if (mbAlt)
     757           0 :             maWW8_FFN[0] = static_cast< sal_uInt8 >(maWW8_FFN[0] + 1 + msAltNm.getLength());
     758             :     }
     759             : 
     760        9845 :     sal_uInt8 aB = 0;
     761        9845 :     switch(ePitch)
     762             :     {
     763             :         case PITCH_VARIABLE:
     764        9189 :             aB |= 2;    // aF.prg = 2
     765        9189 :             break;
     766             :         case PITCH_FIXED:
     767          91 :             aB |= 1;
     768          91 :             break;
     769             :         default:        // aF.prg = 0 : DEFAULT_PITCH (windows.h)
     770         565 :             break;
     771             :     }
     772        9845 :     aB |= 1 << 2;   // aF.fTrueType = 1; don't know any better;
     773             : 
     774        9845 :     switch(eFamily)
     775             :     {
     776             :         case FAMILY_ROMAN:
     777        7088 :             aB |= 1 << 4;   // aF.ff = 1;
     778        7088 :             break;
     779             :         case FAMILY_SWISS:
     780        1727 :             aB |= 2 << 4;   // aF.ff = 2;
     781        1727 :             break;
     782             :         case FAMILY_MODERN:
     783         115 :             aB |= 3 << 4;   // aF.ff = 3;
     784         115 :             break;
     785             :         case FAMILY_SCRIPT:
     786           0 :             aB |= 4 << 4;   // aF.ff = 4;
     787           0 :             break;
     788             :         case FAMILY_DECORATIVE:
     789           0 :             aB |= 5 << 4;   // aF.ff = 5;
     790           0 :             break;
     791             :         default:            // aF.ff = 0; FF_DONTCARE (windows.h)
     792         915 :             break;
     793             :     }
     794        9845 :     maWW8_FFN[1] = aB;
     795             : 
     796        9845 :     ShortToSVBT16( 400, &maWW8_FFN[2] );        // don't know any better
     797             :                                                 // 400 == FW_NORMAL (windows.h)
     798             : 
     799             :     //#i61927# For unicode fonts like Arial Unicode, Word 97+ sets the chs
     800             :     //to SHIFTJIS presumably to capture that it's a multi-byte encoding font
     801             :     //but Word95 doesn't do this, and sets it to 0 (ANSI), so we should do the
     802             :     //same
     803             :     maWW8_FFN[4] = bWrtWW8 ?
     804        9845 :         sw::ms::rtl_TextEncodingToWinCharset(eChrSet) :
     805       19690 :         rtl_getBestWindowsCharsetFromTextEncoding(eChrSet);
     806             : 
     807        9845 :     if (mbAlt)
     808        1680 :         maWW8_FFN[5] = static_cast< sal_uInt8 >(msFamilyNm.getLength() + 1);
     809        9845 : }
     810             : 
     811         120 : bool wwFont::Write(SvStream *pTableStrm) const
     812             : {
     813         120 :     pTableStrm->Write(maWW8_FFN, sizeof(maWW8_FFN));    // fixed part
     814         120 :     if (mbWrtWW8)
     815             :     {
     816             :         // ab Ver8 sind folgende beiden Felder eingeschoben,
     817             :         // werden von uns ignoriert.
     818             :         //char  panose[ 10 ];       //  0x6   PANOSE
     819             :         //char  fs[ 24     ];       //  0x10  FONTSIGNATURE
     820         120 :         SwWW8Writer::FillCount(*pTableStrm, 0x22);
     821         120 :         SwWW8Writer::WriteString16(*pTableStrm, msFamilyNm, true);
     822         120 :         if (mbAlt)
     823          22 :             SwWW8Writer::WriteString16(*pTableStrm, msAltNm, true);
     824             :     }
     825             :     else
     826             :     {
     827             :         SwWW8Writer::WriteString8(*pTableStrm, msFamilyNm, true,
     828           0 :             RTL_TEXTENCODING_MS_1252);
     829           0 :         if (mbAlt)
     830             :         {
     831             :             SwWW8Writer::WriteString8( *pTableStrm, msAltNm, true,
     832           0 :                 RTL_TEXTENCODING_MS_1252);
     833             :         }
     834             :     }
     835         120 :     return true;
     836             : }
     837             : 
     838        2028 : void wwFont::WriteDocx( DocxAttributeOutput* rAttrOutput ) const
     839             : {
     840             :     // no font embedding, panose id, subsetting, ... implemented
     841             : 
     842        2028 :     if (!msFamilyNm.isEmpty())
     843             :     {
     844        2026 :         rAttrOutput->StartFont( msFamilyNm );
     845             : 
     846        2026 :         if ( mbAlt )
     847         542 :             rAttrOutput->FontAlternateName( msAltNm );
     848        2026 :         rAttrOutput->FontCharset( sw::ms::rtl_TextEncodingToWinCharset( meChrSet ), meChrSet );
     849        2026 :         rAttrOutput->FontFamilyType( meFamily );
     850        2026 :         rAttrOutput->FontPitchType( mePitch );
     851        2026 :         rAttrOutput->EmbedFont( msFamilyNm, meFamily, mePitch, meChrSet );
     852             : 
     853        2026 :         rAttrOutput->EndFont();
     854             :     }
     855        2028 : }
     856             : 
     857         481 : void wwFont::WriteRtf( const RtfAttributeOutput* rAttrOutput ) const
     858             : {
     859         481 :     rAttrOutput->FontFamilyType( meFamily, *this );
     860         481 :     rAttrOutput->FontPitchType( mePitch );
     861         481 :     rAttrOutput->FontCharset( rtl_getBestWindowsCharsetFromTextEncoding( meChrSet ) );
     862         481 :     rAttrOutput->StartFont( msFamilyNm );
     863         481 :     if ( mbAlt )
     864         108 :         rAttrOutput->FontAlternateName( msAltNm );
     865         481 :     rAttrOutput->EndFont();
     866         481 : }
     867             : 
     868       54507 : bool operator<(const wwFont &r1, const wwFont &r2)
     869             : {
     870       54507 :     int nRet = memcmp(r1.maWW8_FFN, r2.maWW8_FFN, sizeof(r1.maWW8_FFN));
     871       54507 :     if (nRet == 0)
     872             :     {
     873       16264 :         nRet = r1.msFamilyNm.compareTo(r2.msFamilyNm);
     874       16264 :         if (nRet == 0)
     875       15382 :             nRet = r1.msAltNm.compareTo(r2.msAltNm);
     876             :     }
     877       54507 :     return nRet < 0;
     878             : }
     879             : 
     880       10326 : sal_uInt16 wwFontHelper::GetId(const wwFont &rFont)
     881             : {
     882             :     sal_uInt16 nRet;
     883       10326 :     ::std::map<wwFont, sal_uInt16>::const_iterator aIter = maFonts.find(rFont);
     884       10326 :     if (aIter != maFonts.end())
     885        7691 :         nRet = aIter->second;
     886             :     else
     887             :     {
     888        2635 :         nRet = static_cast< sal_uInt16 >(maFonts.size());
     889        2635 :         maFonts[rFont] = nRet;
     890             :     }
     891       10326 :     return nRet;
     892             : }
     893             : 
     894         340 : void wwFontHelper::InitFontTable(bool bWrtWW8,const SwDoc& rDoc)
     895             : {
     896         340 :     mbWrtWW8 = bWrtWW8;
     897             : 
     898             :     GetId(wwFont(OUString("Times New Roman"), PITCH_VARIABLE,
     899         340 :         FAMILY_ROMAN, RTL_TEXTENCODING_MS_1252,bWrtWW8));
     900             : 
     901             :     GetId(wwFont(OUString("Symbol"), PITCH_VARIABLE, FAMILY_ROMAN,
     902         340 :         RTL_TEXTENCODING_SYMBOL,bWrtWW8));
     903             : 
     904             :     GetId(wwFont(OUString("Arial"), PITCH_VARIABLE, FAMILY_SWISS,
     905         340 :         RTL_TEXTENCODING_MS_1252,bWrtWW8));
     906             : 
     907         340 :     const SvxFontItem* pFont = (const SvxFontItem*)GetDfltAttr(RES_CHRATR_FONT);
     908             : 
     909         340 :     GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
     910         680 :         pFont->GetFamily(), pFont->GetCharSet(),bWrtWW8));
     911             : 
     912         340 :     const SfxItemPool& rPool = rDoc.GetAttrPool();
     913         340 :     if (0 != (pFont = (const SvxFontItem*)rPool.GetPoolDefaultItem(RES_CHRATR_FONT)))
     914             :     {
     915         339 :         GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
     916         678 :             pFont->GetFamily(), pFont->GetCharSet(),bWrtWW8));
     917             :     }
     918             : 
     919         340 :     if (!bLoadAllFonts)
     920         624 :         return;
     921             : 
     922          56 :     const sal_uInt16 aTypes[] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT, 0 };
     923         224 :     for (const sal_uInt16* pId = aTypes; *pId; ++pId)
     924             :     {
     925         168 :         sal_uInt32 const nMaxItem = rPool.GetItemCount2( *pId );
     926         522 :         for (sal_uInt32 nGet = 0; nGet < nMaxItem; ++nGet)
     927             :         {
     928         354 :             pFont = (const SvxFontItem*)rPool.GetItem2( *pId, nGet );
     929         354 :             if (0 != pFont)
     930             :             {
     931         276 :                 GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
     932         552 :                             pFont->GetFamily(), pFont->GetCharSet(),bWrtWW8));
     933             :             }
     934             :         }
     935             :     }
     936             : }
     937             : 
     938           0 : sal_uInt16 wwFontHelper::GetId(const Font& rFont)
     939             : {
     940           0 :     wwFont aFont(rFont.GetName(), rFont.GetPitch(), rFont.GetFamily(),
     941           0 :         rFont.GetCharSet(), mbWrtWW8);
     942           0 :     return GetId(aFont);
     943             : }
     944             : 
     945        7571 : sal_uInt16 wwFontHelper::GetId(const SvxFontItem& rFont)
     946             : {
     947        7571 :     wwFont aFont(rFont.GetFamilyName(), rFont.GetPitch(), rFont.GetFamily(),
     948       15142 :         rFont.GetCharSet(), mbWrtWW8);
     949        7571 :     return GetId(aFont);
     950             : }
     951             : 
     952         340 : ::std::vector< const wwFont* > wwFontHelper::AsVector() const
     953             : {
     954         340 :     ::std::vector<const wwFont *> aFontList( maFonts.size() );
     955             : 
     956             :     typedef ::std::map<wwFont, sal_uInt16>::const_iterator myiter;
     957         340 :     myiter aEnd = maFonts.end();
     958        2969 :     for ( myiter aIter = maFonts.begin(); aIter != aEnd; ++aIter )
     959        2629 :         aFontList[aIter->second] = &aIter->first;
     960             : 
     961         340 :     return aFontList;
     962             : }
     963             : 
     964          12 : void wwFontHelper::WriteFontTable(SvStream *pTableStream, WW8Fib& rFib)
     965             : {
     966          12 :     rFib.fcSttbfffn = pTableStream->Tell();
     967             :     /*
     968             :      * Reserve some space to fill in the len after we know how big it is
     969             :      */
     970          12 :     if (mbWrtWW8)
     971          12 :         SwWW8Writer::WriteLong(*pTableStream, 0);
     972             :     else
     973           0 :         SwWW8Writer::WriteShort(*pTableStream, 0);
     974             : 
     975             :     /*
     976             :      * Convert from fast insertion map to linear vector in the order that we
     977             :      * want to write.
     978             :      */
     979          12 :     ::std::vector<const wwFont *> aFontList( AsVector() );
     980             : 
     981             :     /*
     982             :      * Write them all to pTableStream
     983             :      */
     984             :     ::std::for_each(aFontList.begin(), aFontList.end(),
     985          12 :         ::std::bind2nd(::std::mem_fun(&wwFont::Write),pTableStream));
     986             : 
     987             :     /*
     988             :      * Write the position and len in the FIB
     989             :      */
     990          12 :     rFib.lcbSttbfffn = pTableStream->Tell() - rFib.fcSttbfffn;
     991          12 :     if (mbWrtWW8)
     992          12 :         SwWW8Writer::WriteLong( *pTableStream, rFib.fcSttbfffn, maFonts.size());
     993             :     else
     994             :     {
     995             :         SwWW8Writer::WriteShort( *pTableStream, rFib.fcSttbfffn,
     996           0 :             (sal_Int16)rFib.lcbSttbfffn );
     997          12 :     }
     998          12 : }
     999             : 
    1000         272 : void wwFontHelper::WriteFontTable( DocxAttributeOutput& rAttrOutput )
    1001             : {
    1002         272 :     ::std::vector<const wwFont *> aFontList( AsVector() );
    1003             : 
    1004             :     ::std::for_each( aFontList.begin(), aFontList.end(),
    1005         272 :         ::std::bind2nd( ::std::mem_fun( &wwFont::WriteDocx ), &rAttrOutput ) );
    1006         272 : }
    1007             : 
    1008          56 : void wwFontHelper::WriteFontTable( const RtfAttributeOutput& rAttrOutput )
    1009             : {
    1010          56 :     ::std::vector<const wwFont *> aFontList( AsVector() );
    1011             : 
    1012             :     ::std::for_each( aFontList.begin(), aFontList.end(),
    1013          56 :         ::std::bind2nd( ::std::mem_fun( &wwFont::WriteRtf ), &rAttrOutput ) );
    1014          56 : }
    1015             : 
    1016          17 : WW8_WrPlc0::WW8_WrPlc0( sal_uLong nOffset )
    1017          17 :     : nOfs( nOffset )
    1018             : {
    1019          17 : }
    1020             : 
    1021         197 : void WW8_WrPlc0::Append( sal_uLong nStartCpOrFc )
    1022             : {
    1023         197 :     aPos.push_back( nStartCpOrFc - nOfs );
    1024         197 : }
    1025             : 
    1026          12 : void WW8_WrPlc0::Write( SvStream& rStrm )
    1027             : {
    1028          12 :     std::vector<sal_uLong>::const_iterator iter;
    1029         124 :     for( iter = aPos.begin(); iter != aPos.end(); ++iter )
    1030             :     {
    1031             :         SVBT32 nP;
    1032         112 :         UInt32ToSVBT32( *iter, nP );
    1033         112 :         rStrm.Write( nP, 4 );
    1034             :     }
    1035          12 : }
    1036             : 
    1037             : // class MSWordSections : translate PageDescs into Sections
    1038             : //      also deals with header and footer
    1039             : 
    1040         340 : MSWordSections::MSWordSections( MSWordExportBase& rExport )
    1041         340 :     : mbDocumentIsProtected( false )
    1042             : {
    1043         340 :     const SwSectionFmt *pFmt = 0;
    1044         340 :     rExport.pAktPageDesc = &rExport.pDoc->GetPageDesc( 0 );
    1045             : 
    1046             :     const SfxPoolItem* pI;
    1047         340 :     const SwNode* pNd = rExport.pCurPam->GetCntntNode();
    1048         340 :     const SfxItemSet* pSet = pNd ? &((SwCntntNode*)pNd)->GetSwAttrSet() : 0;
    1049             : 
    1050         340 :     sal_uLong nRstLnNum =  pSet ? ((SwFmtLineNumber&)pSet->Get( RES_LINENUMBER )).GetStartValue() : 0;
    1051             : 
    1052         340 :     const SwTableNode* pTblNd = rExport.pCurPam->GetNode()->FindTableNode();
    1053             :     const SwSectionNode* pSectNd;
    1054         340 :     if ( pTblNd )
    1055             :     {
    1056          27 :         pSet = &pTblNd->GetTable().GetFrmFmt()->GetAttrSet();
    1057          27 :         pNd = pTblNd;
    1058             :     }
    1059         313 :     else if (pNd && 0 != ( pSectNd = pNd->FindSectionNode() ))
    1060             :     {
    1061           7 :         if ( TOX_HEADER_SECTION == pSectNd->GetSection().GetType() &&
    1062           0 :              pSectNd->StartOfSectionNode()->IsSectionNode() )
    1063             :         {
    1064           0 :             pSectNd = pSectNd->StartOfSectionNode()->GetSectionNode();
    1065             :         }
    1066             : 
    1067           7 :         if ( TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() )
    1068             :         {
    1069           0 :             pNd = pSectNd;
    1070           0 :             rExport.pCurPam->GetPoint()->nNode = *pNd;
    1071             :         }
    1072             : 
    1073           7 :         if ( CONTENT_SECTION == pSectNd->GetSection().GetType() )
    1074           7 :             pFmt = pSectNd->GetSection().GetFmt();
    1075             :     }
    1076             : 
    1077             :     // Hole evtl. Pagedesc des 1. Nodes
    1078         680 :     if ( pSet &&
    1079         648 :          SFX_ITEM_ON == pSet->GetItemState( RES_PAGEDESC, true, &pI ) &&
    1080         308 :          ( (SwFmtPageDesc*)pI )->GetPageDesc() )
    1081             :     {
    1082         308 :         AppendSection( *(SwFmtPageDesc*)pI, *pNd, pFmt, nRstLnNum );
    1083             :     }
    1084             :     else
    1085          32 :         AppendSection( rExport.pAktPageDesc, pFmt, nRstLnNum );
    1086         340 : }
    1087             : 
    1088          12 : WW8_WrPlcSepx::WW8_WrPlcSepx( MSWordExportBase& rExport )
    1089             :     : MSWordSections( rExport )
    1090             :     , m_bHeaderFooterWritten( false )
    1091          12 :     , pTxtPos( 0 )
    1092             : {
    1093             :     // to be in sync with the AppendSection() call in the MSWordSections
    1094             :     // constructor
    1095          12 :     aCps.push_back( 0 );
    1096          12 : }
    1097             : 
    1098         556 : MSWordSections::~MSWordSections()
    1099             : {
    1100         556 : }
    1101             : 
    1102          36 : WW8_WrPlcSepx::~WW8_WrPlcSepx()
    1103             : {
    1104          12 :     delete pTxtPos;
    1105          24 : }
    1106             : 
    1107         376 : bool MSWordSections::HeaderFooterWritten()
    1108             : {
    1109         376 :     return false; // only relevant for WW8
    1110             : }
    1111             : 
    1112           6 : bool WW8_WrPlcSepx::HeaderFooterWritten()
    1113             : {
    1114           6 :     return m_bHeaderFooterWritten;
    1115             : }
    1116             : 
    1117          20 : sal_uInt16 MSWordSections::CurrentNumberOfColumns( const SwDoc &rDoc ) const
    1118             : {
    1119             :     OSL_ENSURE( !aSects.empty(), "no segement inserted yet" );
    1120          20 :     if ( aSects.empty() )
    1121           0 :         return 1;
    1122             : 
    1123          20 :     return NumberOfColumns( rDoc, aSects.back() );
    1124             : }
    1125             : 
    1126          20 : sal_uInt16 MSWordSections::NumberOfColumns( const SwDoc &rDoc, const WW8_SepInfo& rInfo ) const
    1127             : {
    1128          20 :     const SwPageDesc* pPd = rInfo.pPageDesc;
    1129          20 :     if ( !pPd )
    1130           0 :         pPd = &rDoc.GetPageDesc( 0 );
    1131             : 
    1132          20 :     if ( !pPd )
    1133             :     {
    1134             :         OSL_ENSURE( pPd, "totally impossible" );
    1135           0 :         return 1;
    1136             :     }
    1137             : 
    1138          20 :     const SfxItemSet &rSet = pPd->GetMaster().GetAttrSet();
    1139          20 :     SfxItemSet aSet( *rSet.GetPool(), RES_COL, RES_COL );
    1140          20 :     aSet.SetParent( &rSet );
    1141             : 
    1142             :     //0xffffffff, what the hell is going on with that!, fixme most terribly
    1143          20 :     if ( rInfo.pSectionFmt && (SwSectionFmt*)0xFFFFFFFF != rInfo.pSectionFmt )
    1144           2 :         aSet.Put( rInfo.pSectionFmt->GetFmtAttr( RES_COL ) );
    1145             : 
    1146          20 :     const SwFmtCol& rCol = (const SwFmtCol&)aSet.Get( RES_COL );
    1147          20 :     const SwColumns& rColumns = rCol.GetColumns();
    1148          20 :     return rColumns.size();
    1149             : }
    1150             : 
    1151         305 : const WW8_SepInfo* MSWordSections::CurrentSectionInfo()
    1152             : {
    1153         305 :     if ( !aSects.empty() )
    1154         305 :         return &aSects.back();
    1155             : 
    1156           0 :     return NULL;
    1157             : }
    1158             : 
    1159          49 : void MSWordSections::AppendSection( const SwPageDesc* pPd,
    1160             :     const SwSectionFmt* pSectionFmt, sal_uLong nLnNumRestartNo )
    1161             : {
    1162          49 :     if (HeaderFooterWritten()) {
    1163          49 :         return; // #i117955# prevent new sections in endnotes
    1164             :     }
    1165          49 :     aSects.push_back( WW8_SepInfo( pPd, pSectionFmt, nLnNumRestartNo ) );
    1166          49 :     NeedsDocumentProtected( aSects.back() );
    1167             : }
    1168             : 
    1169           0 : void WW8_WrPlcSepx::AppendSep( WW8_CP nStartCp, const SwPageDesc* pPd,
    1170             :     const SwSectionFmt* pSectionFmt, sal_uLong nLnNumRestartNo )
    1171             : {
    1172           0 :     if (HeaderFooterWritten()) {
    1173           0 :         return; // #i117955# prevent new sections in endnotes
    1174             :     }
    1175           0 :     aCps.push_back( nStartCp );
    1176           0 :     AppendSection( pPd, pSectionFmt, nLnNumRestartNo );
    1177             : }
    1178             : 
    1179         330 : void MSWordSections::AppendSection( const SwFmtPageDesc& rPD,
    1180             :     const SwNode& rNd, const SwSectionFmt* pSectionFmt, sal_uLong nLnNumRestartNo )
    1181             : {
    1182         330 :     if (HeaderFooterWritten()) {
    1183         330 :         return; // #i117955# prevent new sections in endnotes
    1184             :     }
    1185             : 
    1186         330 :     WW8_SepInfo aI( rPD.GetPageDesc(), pSectionFmt, nLnNumRestartNo, rPD.GetNumOffset(), &rNd );
    1187             : 
    1188         330 :     aSects.push_back( aI );
    1189         330 :     NeedsDocumentProtected( aI );
    1190             : }
    1191             : 
    1192           3 : void WW8_WrPlcSepx::AppendSep( WW8_CP nStartCp, const SwFmtPageDesc& rPD,
    1193             :     const SwNode& rNd, const SwSectionFmt* pSectionFmt, sal_uLong nLnNumRestartNo )
    1194             : {
    1195           3 :     if (HeaderFooterWritten()) {
    1196           3 :         return; // #i117955# prevent new sections in endnotes
    1197             :     }
    1198           3 :     aCps.push_back( nStartCp );
    1199           3 :     AppendSection( rPD, rNd, pSectionFmt, nLnNumRestartNo );
    1200             : }
    1201             : 
    1202             : // MSWordSections::SetNum() sets in each section the Num-pointers for the first call.
    1203             : // All subsequent calls will be ignored.
    1204             : // Thus, the first list of the section will be adopted.
    1205             : 
    1206           0 : void MSWordSections::SetNum( const SwTxtNode* pNumNd )
    1207             : {
    1208           0 :     WW8_SepInfo& rInfo = aSects.back();
    1209           0 :     if ( !rInfo.pNumNd ) // not yet assigned
    1210           0 :         rInfo.pNumNd = pNumNd;
    1211           0 : }
    1212             : 
    1213          12 : void WW8_WrPlcSepx::WriteFtnEndTxt( WW8Export& rWrt, sal_uLong nCpStt )
    1214             : {
    1215          12 :     sal_uInt8 nInfoFlags = 0;
    1216          12 :     const SwFtnInfo& rInfo = rWrt.pDoc->GetFtnInfo();
    1217          12 :     if( !rInfo.aErgoSum.isEmpty() )  nInfoFlags |= 0x02;
    1218          12 :     if( !rInfo.aQuoVadis.isEmpty() ) nInfoFlags |= 0x04;
    1219             : 
    1220          12 :     sal_uInt8 nEmptyStt = rWrt.bWrtWW8 ? 0 : 6;
    1221          12 :     if( nInfoFlags )
    1222             :     {
    1223           0 :         if( rWrt.bWrtWW8 )
    1224           0 :             pTxtPos->Append( nCpStt );  // empty footnote separator
    1225             : 
    1226           0 :         if( 0x02 & nInfoFlags )         // Footnote continuation separator
    1227             :         {
    1228           0 :             pTxtPos->Append( nCpStt );
    1229           0 :             rWrt.WriteStringAsPara( rInfo.aErgoSum );
    1230           0 :             rWrt.WriteStringAsPara( OUString() );
    1231           0 :             nCpStt = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1232             :         }
    1233           0 :         else if( rWrt.bWrtWW8 )
    1234           0 :             pTxtPos->Append( nCpStt );
    1235             : 
    1236           0 :         if( 0x04 & nInfoFlags )         // Footnote continuation notice
    1237             :         {
    1238           0 :             pTxtPos->Append( nCpStt );
    1239           0 :             rWrt.WriteStringAsPara( rInfo.aQuoVadis );
    1240           0 :             rWrt.WriteStringAsPara( OUString() );
    1241           0 :             nCpStt = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1242             :         }
    1243           0 :         else if( rWrt.bWrtWW8 )
    1244           0 :             pTxtPos->Append( nCpStt );
    1245             : 
    1246           0 :         if( rWrt.bWrtWW8 )
    1247           0 :             nEmptyStt = 3;
    1248             :         else
    1249           0 :             rWrt.pDop->grpfIhdt = nInfoFlags;
    1250             :     }
    1251             : 
    1252          96 :     while( 6 > nEmptyStt++ )
    1253          72 :         pTxtPos->Append( nCpStt );
    1254             : 
    1255             :     // gleich die Flags am Dop setzen
    1256          12 :     WW8Dop& rDop = *rWrt.pDop;
    1257             :     // Footnote Info
    1258          12 :     switch( rInfo.eNum )
    1259             :     {
    1260           0 :     case FTNNUM_PAGE:       rDop.rncFtn = 2; break;
    1261           0 :     case FTNNUM_CHAPTER:    rDop.rncFtn  = 1; break;
    1262          12 :     default: rDop.rncFtn  = 0; break;
    1263             :     }                                   // rncFtn
    1264          12 :     rDop.nfcFtnRef = WW8Export::GetNumId( rInfo.aFmt.GetNumberingType() );
    1265          12 :     rDop.nFtn = rInfo.nFtnOffset + 1;
    1266          12 :     rDop.fpc = rWrt.bFtnAtTxtEnd ? 2 : 1;
    1267             : 
    1268             :     // Endnote Info
    1269          12 :     rDop.rncEdn = 0;                        // rncEdn: Don't Restart
    1270          12 :     const SwEndNoteInfo& rEndInfo = rWrt.pDoc->GetEndNoteInfo();
    1271          12 :     rDop.nfcEdnRef = WW8Export::GetNumId( rEndInfo.aFmt.GetNumberingType() );
    1272          12 :     rDop.nEdn = rEndInfo.nFtnOffset + 1;
    1273          12 :     rDop.epc = rWrt.bEndAtTxtEnd ? 3 : 0;
    1274          12 : }
    1275             : 
    1276         334 : void MSWordSections::SetHeaderFlag( sal_uInt8& rHeadFootFlags, const SwFmt& rFmt,
    1277             :     sal_uInt8 nFlag )
    1278             : {
    1279             :     const SfxPoolItem* pItem;
    1280         668 :     if( SFX_ITEM_SET == rFmt.GetItemState(RES_HEADER, true, &pItem)
    1281         427 :         && ((SwFmtHeader*)pItem)->IsActive() &&
    1282          93 :         ((SwFmtHeader*)pItem)->GetHeaderFmt() )
    1283          93 :         rHeadFootFlags |= nFlag;
    1284         334 : }
    1285             : 
    1286         334 : void MSWordSections::SetFooterFlag( sal_uInt8& rHeadFootFlags, const SwFmt& rFmt,
    1287             :     sal_uInt8 nFlag )
    1288             : {
    1289             :     const SfxPoolItem* pItem;
    1290         668 :     if( SFX_ITEM_SET == rFmt.GetItemState(RES_FOOTER, true, &pItem)
    1291         432 :         && ((SwFmtFooter*)pItem)->IsActive() &&
    1292          98 :         ((SwFmtFooter*)pItem)->GetFooterFmt() )
    1293          98 :         rHeadFootFlags |= nFlag;
    1294         334 : }
    1295             : 
    1296          90 : void WW8_WrPlcSepx::OutHeaderFooter( WW8Export& rWrt, bool bHeader,
    1297             :                      const SwFmt& rFmt, sal_uLong& rCpPos, sal_uInt8 nHFFlags,
    1298             :                      sal_uInt8 nFlag,  sal_uInt8 nBreakCode)
    1299             : {
    1300          90 :     if ( nFlag & nHFFlags )
    1301             :     {
    1302          29 :         pTxtPos->Append( rCpPos );
    1303          29 :         rWrt.WriteHeaderFooterText( rFmt, bHeader);
    1304          29 :         rWrt.WriteStringAsPara( OUString() ); // CR ans Ende ( sonst mault WW )
    1305          29 :         rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1306             :     }
    1307          61 :     else if ( rWrt.bWrtWW8 )
    1308             :     {
    1309          61 :         pTxtPos->Append( rCpPos );
    1310          61 :         if ((bHeader? rWrt.bHasHdr : rWrt.bHasFtr) && nBreakCode!=0)
    1311             :         {
    1312          11 :             rWrt.WriteStringAsPara( OUString() ); // Empty paragraph for empty header/footer
    1313          11 :             rWrt.WriteStringAsPara( OUString() ); // a CR that WW8 needs for end of the stream
    1314          11 :             rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1315             :         }
    1316             :     }
    1317          90 : }
    1318             : 
    1319         379 : void MSWordSections::NeedsDocumentProtected(const WW8_SepInfo &rInfo)
    1320             : {
    1321         379 :     if (rInfo.IsProtected())
    1322           0 :         mbDocumentIsProtected = true;
    1323         379 : }
    1324             : 
    1325         697 : bool WW8_SepInfo::IsProtected() const
    1326             : {
    1327         697 :     bool bRet = false;
    1328         697 :     if (
    1329          47 :          pSectionFmt &&
    1330          47 :          ((SwSectionFmt*)0xFFFFFFFF != pSectionFmt)
    1331             :        )
    1332             :     {
    1333          31 :         const SwSection *pSection = pSectionFmt->GetSection();
    1334          31 :         if (pSection && pSection->IsProtect())
    1335             :         {
    1336           0 :             bRet = true;
    1337             :         }
    1338             :     }
    1339         697 :     return bRet;
    1340             : }
    1341             : 
    1342          12 : void MSWordSections::CheckForFacinPg( WW8Export& rWrt ) const
    1343             : {
    1344             :     // 2 values getting set
    1345             :     //      Dop.fFacingPages            == Header and Footer different
    1346             :     //      Dop.fSwapBordersFacingPgs   == mirrored borders
    1347          12 :     std::vector<WW8_SepInfo>::const_iterator iter = aSects.begin();
    1348          27 :     for( sal_uInt16 nEnde = 0; iter != aSects.end(); ++iter )
    1349             :     {
    1350          15 :         const WW8_SepInfo& rSepInfo = *iter;
    1351          15 :         if( !rSepInfo.pSectionFmt )
    1352             :         {
    1353          15 :             const SwPageDesc* pPd = rSepInfo.pPageDesc;
    1354          45 :             if( pPd->GetFollow() && pPd != pPd->GetFollow() &&
    1355           0 :                 pPd->GetFollow()->GetFollow() == pPd->GetFollow() &&
    1356          15 :                 rSepInfo.pPDNd &&
    1357           0 :                 pPd->IsFollowNextPageOfNode( *rSepInfo.pPDNd ) )
    1358             :                 // das ist also 1.Seite und nachfolgende, also nur den
    1359             :                 // follow beachten
    1360           0 :                 pPd = pPd->GetFollow();
    1361             : 
    1362             :             // left-/right chain of pagedescs ?
    1363          43 :             else if( !( 1 & nEnde ) &&
    1364          26 :                 pPd->GetFollow() && pPd != pPd->GetFollow() &&
    1365          15 :                 pPd->GetFollow()->GetFollow() == pPd &&
    1366           0 :                 (( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
    1367           0 :                    nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ||
    1368           0 :                  ( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
    1369           0 :                    nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ))
    1370             :             {
    1371           0 :                 rWrt.pDop->fFacingPages = rWrt.pDop->fMirrorMargins = true;
    1372           0 :                 nEnde |= 1;
    1373             :             }
    1374             : 
    1375          30 :             if( !( 1 & nEnde ) &&
    1376          24 :                 ( !pPd->IsHeaderShared() || !pPd->IsFooterShared() ))
    1377             :             {
    1378           2 :                 rWrt.pDop->fFacingPages = true;
    1379           2 :                 nEnde |= 1;
    1380             :             }
    1381          30 :             if( !( 2 & nEnde ) &&
    1382          15 :                 nsUseOnPage::PD_MIRROR == ( nsUseOnPage::PD_MIRROR & pPd->ReadUseOn() ))
    1383             :             {
    1384             :                 rWrt.pDop->fSwapBordersFacingPgs =
    1385           1 :                     rWrt.pDop->fMirrorMargins = true;
    1386           1 :                 nEnde |= 2;
    1387             :             }
    1388             : 
    1389          15 :             if( 3 == nEnde )
    1390           0 :                 break;      // We do not need to go any further
    1391             :         }
    1392             :     }
    1393          12 : }
    1394             : 
    1395          30 : bool MSWordSections::HasBorderItem( const SwFmt& rFmt )
    1396             : {
    1397             :     const SfxPoolItem* pItem;
    1398          34 :     return SFX_ITEM_SET == rFmt.GetItemState(RES_BOX, true, &pItem) &&
    1399           2 :             (   ((SvxBoxItem*)pItem)->GetTop() ||
    1400           0 :                 ((SvxBoxItem*)pItem)->GetBottom()  ||
    1401           0 :                 ((SvxBoxItem*)pItem)->GetLeft()  ||
    1402          30 :                 ((SvxBoxItem*)pItem)->GetRight() );
    1403             : }
    1404             : 
    1405          15 : void WW8AttributeOutput::StartSection()
    1406             : {
    1407          15 :     m_rWW8Export.pO->clear();
    1408          15 : }
    1409             : 
    1410          15 : void WW8AttributeOutput::SectionFormProtection( bool bProtected )
    1411             : {
    1412             :     //If the document is to be exported as protected, then if a segment
    1413             :     //is not protected, set the unlocked flag
    1414          15 :     if ( m_rWW8Export.pSepx->DocumentIsProtected() && !bProtected )
    1415             :     {
    1416           0 :         if ( m_rWW8Export.bWrtWW8 )
    1417           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFProtected );
    1418             :         else
    1419           0 :             m_rWW8Export.pO->push_back( 139 );
    1420           0 :         m_rWW8Export.pO->push_back( 1 );
    1421             :     }
    1422          15 : }
    1423             : 
    1424           0 : void WW8AttributeOutput::SectionLineNumbering( sal_uLong nRestartNo, const SwLineNumberInfo& rLnNumInfo )
    1425             : {
    1426             :     // sprmSNLnnMod - activate Line Numbering and define Modulo
    1427           0 :     if ( m_rWW8Export.bWrtWW8 )
    1428           0 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SNLnnMod );
    1429             :     else
    1430           0 :         m_rWW8Export.pO->push_back( 154 );
    1431           0 :     SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (sal_uInt16)rLnNumInfo.GetCountBy() );
    1432             : 
    1433             :     // sprmSDxaLnn - xPosition of Line Number
    1434           0 :     if ( m_rWW8Export.bWrtWW8 )
    1435           0 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SDxaLnn );
    1436             :     else
    1437           0 :         m_rWW8Export.pO->push_back( 155 );
    1438           0 :     SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (sal_uInt16)rLnNumInfo.GetPosFromLeft() );
    1439             : 
    1440             :     // sprmSLnc - restart number: 0 per page, 1 per section, 2 never restart
    1441           0 :     if ( nRestartNo || !rLnNumInfo.IsRestartEachPage() )
    1442             :     {
    1443           0 :         if ( m_rWW8Export.bWrtWW8 )
    1444           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SLnc );
    1445             :         else
    1446           0 :             m_rWW8Export.pO->push_back( 152 );
    1447           0 :         m_rWW8Export.pO->push_back( nRestartNo ? 1 : 2 );
    1448             :     }
    1449             : 
    1450             :     // sprmSLnnMin - Restart the Line Number with given value
    1451           0 :     if ( nRestartNo )
    1452             :     {
    1453           0 :         if ( m_rWW8Export.bWrtWW8 )
    1454           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SLnnMin );
    1455             :         else
    1456           0 :             m_rWW8Export.pO->push_back( 160 );
    1457           0 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (sal_uInt16)nRestartNo - 1 );
    1458             :     }
    1459           0 : }
    1460             : 
    1461           3 : void WW8AttributeOutput::SectionTitlePage()
    1462             : {
    1463             :     // sprmSFTitlePage
    1464           3 :     if ( m_rWW8Export.bWrtWW8 )
    1465           3 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFTitlePage );
    1466             :     else
    1467           0 :         m_rWW8Export.pO->push_back( 143 );
    1468           3 :     m_rWW8Export.pO->push_back( 1 );
    1469           3 : }
    1470             : 
    1471          15 : void WW8AttributeOutput::SectionPageBorders( const SwFrmFmt* pPdFmt, const SwFrmFmt* pPdFirstPgFmt )
    1472             : {
    1473          15 :     if ( m_rWW8Export.bWrtWW8 )              // write border of page
    1474             :     {
    1475          15 :         sal_uInt16 nPgBorder = MSWordSections::HasBorderItem( *pPdFmt ) ? 0 : USHRT_MAX;
    1476          15 :         if ( pPdFmt != pPdFirstPgFmt )
    1477             :         {
    1478          15 :             if ( MSWordSections::HasBorderItem( *pPdFirstPgFmt ) )
    1479             :             {
    1480           1 :                 if ( USHRT_MAX == nPgBorder )
    1481             :                 {
    1482           0 :                     nPgBorder = 1;
    1483             :                     // only the first page outlined -> Get the BoxItem from the correct format
    1484           0 :                     m_rWW8Export.pISet = &pPdFirstPgFmt->GetAttrSet();
    1485           0 :                     OutputItem( pPdFirstPgFmt->GetFmtAttr( RES_BOX ) );
    1486             :                 }
    1487             :             }
    1488          14 :             else if ( !nPgBorder )
    1489           0 :                 nPgBorder = 2;
    1490             :         }
    1491             : 
    1492          15 :         if ( USHRT_MAX != nPgBorder )
    1493             :         {
    1494             :             // write the Flag and Border Attribute
    1495           1 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SPgbProp );
    1496           1 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nPgBorder );
    1497             :         }
    1498             :     }
    1499          15 : }
    1500             : 
    1501           0 : void WW8AttributeOutput::SectionBiDi( bool bBiDi )
    1502             : {
    1503           0 :     if ( m_rWW8Export.bWrtWW8 )
    1504             :     {
    1505           0 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFBiDi );
    1506           0 :         m_rWW8Export.pO->push_back( bBiDi? 1: 0 );
    1507             :     }
    1508           0 : }
    1509             : 
    1510          15 : void WW8AttributeOutput::SectionPageNumbering( sal_uInt16 nNumType, ::boost::optional<sal_uInt16> oPageRestartNumber )
    1511             : {
    1512             :     // sprmSNfcPgn
    1513          15 :     sal_uInt8 nb = WW8Export::GetNumId( nNumType );
    1514          15 :     if ( m_rWW8Export.bWrtWW8 )
    1515          15 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SNfcPgn );
    1516             :     else
    1517           0 :         m_rWW8Export.pO->push_back( 147 );
    1518          15 :     m_rWW8Export.pO->push_back( nb );
    1519             : 
    1520          15 :     if ( oPageRestartNumber )
    1521             :     {
    1522             :         // sprmSFPgnRestart
    1523           0 :         if ( m_rWW8Export.bWrtWW8 )
    1524           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFPgnRestart );
    1525             :         else
    1526           0 :             m_rWW8Export.pO->push_back( 150 );
    1527           0 :         m_rWW8Export.pO->push_back( 1 );
    1528             : 
    1529             :         // sprmSPgnStart
    1530           0 :         if ( m_rWW8Export.bWrtWW8 )
    1531           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SPgnStart );
    1532             :         else
    1533           0 :             m_rWW8Export.pO->push_back( 161 );
    1534           0 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, oPageRestartNumber.get() );
    1535             :     }
    1536          15 : }
    1537             : 
    1538          15 : void WW8AttributeOutput::SectionType( sal_uInt8 nBreakCode )
    1539             : {
    1540          15 :     if ( 2 != nBreakCode ) // new page is the default
    1541             :     {
    1542           0 :         if ( m_rWW8Export.bWrtWW8 )
    1543           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SBkc );
    1544             :         else
    1545           0 :             m_rWW8Export.pO->push_back( 142 );
    1546           0 :         m_rWW8Export.pO->push_back( nBreakCode );
    1547             :     }
    1548          15 : }
    1549             : 
    1550          15 : void WW8AttributeOutput::SectionWW6HeaderFooterFlags( sal_uInt8 nHeadFootFlags )
    1551             : {
    1552          15 :     if ( nHeadFootFlags && !m_rWW8Export.bWrtWW8 )
    1553             :     {
    1554           0 :         sal_uInt8 nTmpFlags = nHeadFootFlags;
    1555           0 :         if ( m_rWW8Export.pDop->fFacingPages )
    1556             :         {
    1557           0 :             if ( !(nTmpFlags & WW8_FOOTER_EVEN) && (nTmpFlags & WW8_FOOTER_ODD ) )
    1558           0 :                 nTmpFlags |= WW8_FOOTER_EVEN;
    1559             : 
    1560           0 :             if ( !(nTmpFlags & WW8_HEADER_EVEN) && (nTmpFlags & WW8_HEADER_ODD ) )
    1561           0 :                 nTmpFlags |= WW8_HEADER_EVEN;
    1562             :         }
    1563             : 
    1564             :         // sprmSGprfIhdt, is only needed in WW95
    1565           0 :         m_rWW8Export.pO->push_back( 153 );
    1566           0 :         m_rWW8Export.pO->push_back( nTmpFlags );
    1567             :     }
    1568          15 : }
    1569             : 
    1570          15 : void WW8Export::SetupSectionPositions( WW8_PdAttrDesc* pA )
    1571             : {
    1572          15 :     if ( !pA )
    1573          15 :         return;
    1574             : 
    1575          15 :     if ( !pO->empty() ) // are there attributes ?
    1576             :     {
    1577          15 :         pA->m_nLen = pO->size();
    1578          15 :         pA->m_pData.reset(new sal_uInt8 [pO->size()]);
    1579             :         // store for later
    1580          15 :         memcpy( pA->m_pData.get(), pO->data(), pO->size() );
    1581          15 :         pO->clear(); // clear HdFt-Text
    1582             :     }
    1583             :     else // no attributes there
    1584             :     {
    1585           0 :         pA->m_pData.reset();
    1586           0 :         pA->m_nLen = 0;
    1587             :     }
    1588             : }
    1589             : 
    1590          15 : void WW8Export::WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
    1591             :         const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt, sal_uInt8 nBreakCode )
    1592             : {
    1593          15 :     sal_uLong nCpPos = Fc2Cp( Strm().Tell() );
    1594             : 
    1595          15 :     IncrementHdFtIndex();
    1596          15 :     if ( !(nHeadFootFlags & WW8_HEADER_EVEN) && pDop->fFacingPages )
    1597           0 :         pSepx->OutHeaderFooter( *this, true, rFmt, nCpPos, nHeadFootFlags, WW8_HEADER_ODD, nBreakCode );
    1598             :     else
    1599          15 :         pSepx->OutHeaderFooter( *this, true, rLeftFmt, nCpPos, nHeadFootFlags, WW8_HEADER_EVEN, nBreakCode );
    1600          15 :     IncrementHdFtIndex();
    1601          15 :     pSepx->OutHeaderFooter( *this, true, rFmt, nCpPos, nHeadFootFlags, WW8_HEADER_ODD, nBreakCode );
    1602             : 
    1603          15 :     IncrementHdFtIndex();
    1604          15 :     if ( !(nHeadFootFlags & WW8_FOOTER_EVEN) && pDop->fFacingPages )
    1605           0 :         pSepx->OutHeaderFooter( *this, false, rFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD, nBreakCode );
    1606             :     else
    1607          15 :         pSepx->OutHeaderFooter( *this, false, rLeftFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_EVEN, nBreakCode );
    1608          15 :     IncrementHdFtIndex();
    1609          15 :     pSepx->OutHeaderFooter( *this, false, rFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD, nBreakCode );
    1610             : 
    1611             :     //#i24344# Drawing objects cannot be directly shared between main hd/ft
    1612             :     //and title hd/ft so we need to differenciate them
    1613          15 :     IncrementHdFtIndex();
    1614          15 :     pSepx->OutHeaderFooter( *this, true, rFirstPageFmt, nCpPos, nHeadFootFlags, WW8_HEADER_FIRST, nBreakCode );
    1615          15 :     pSepx->OutHeaderFooter( *this, false, rFirstPageFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_FIRST, nBreakCode );
    1616          15 : }
    1617             : 
    1618         318 : void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAttrDesc* pA )
    1619             : {
    1620         318 :     const SwPageDesc* pPd = rSepInfo.pPageDesc;
    1621             : 
    1622         318 :     if ( rSepInfo.pSectionFmt && !pPd )
    1623           0 :         pPd = &pDoc->GetPageDesc( 0 );
    1624             : 
    1625         318 :     pAktPageDesc = pPd;
    1626             : 
    1627         318 :     if ( !pPd )
    1628         318 :         return;
    1629             : 
    1630         318 :     bool bOldPg = bOutPageDescs;
    1631         318 :     bOutPageDescs = true;
    1632             : 
    1633         318 :     AttrOutput().StartSection();
    1634             : 
    1635         318 :     AttrOutput().SectFootnoteEndnotePr();
    1636             : 
    1637             :     // forms
    1638         318 :     AttrOutput().SectionFormProtection( rSepInfo.IsProtected() );
    1639             : 
    1640             :     // line numbers
    1641         318 :     const SwLineNumberInfo& rLnNumInfo = pDoc->GetLineNumberInfo();
    1642         318 :     if ( rLnNumInfo.IsPaintLineNumbers() )
    1643           1 :         AttrOutput().SectionLineNumbering( rSepInfo.nLnNumRestartNo, rLnNumInfo );
    1644             : 
    1645             :     /*  sprmSBkc, break code:   0 No break, 1 New column
    1646             :         2 New page, 3 Even page, 4 Odd page
    1647             :         */
    1648         318 :     sal_uInt8 nBreakCode = 2;            // default neue Seite beginnen
    1649         318 :     bool bOutPgDscSet = true, bLeftRightPgChain = false, bOutputStyleItemSet = false;
    1650         318 :     const SwFrmFmt* pPdFmt = &pPd->GetMaster();
    1651         318 :     if ( rSepInfo.pSectionFmt )
    1652             :     {
    1653             :         // if pSectionFmt is set, then there is a SectionNode
    1654             :         //  valid pointer -> start Section ,
    1655             :         //  0xfff -> Section terminated
    1656          23 :         nBreakCode = 0;         // fortlaufender Abschnitt
    1657             : 
    1658          23 :         if ( rSepInfo.pPDNd && rSepInfo.pPDNd->IsCntntNode() )
    1659             :         {
    1660           0 :             if ( !NoPageBreakSection( &rSepInfo.pPDNd->GetCntntNode()->GetSwAttrSet() ) )
    1661             :             {
    1662           0 :                 nBreakCode = 2;
    1663             :             }
    1664             :         }
    1665             : 
    1666          23 :         if ( (SwSectionFmt*)0xFFFFFFFF != rSepInfo.pSectionFmt )
    1667             :         {
    1668          15 :             if ( nBreakCode == 0 )
    1669          15 :                 bOutPgDscSet = false;
    1670             : 
    1671             :             // produce Itemset, which inherits PgDesk-Attr-Set:
    1672             :             // als Nachkomme wird bei 'deep'-OutputItemSet
    1673             :             // auch der Vorfahr abgeklappert
    1674          15 :             const SfxItemSet* pPdSet = &pPdFmt->GetAttrSet();
    1675          15 :             SfxItemSet aSet( *pPdSet->GetPool(), pPdSet->GetRanges() );
    1676          15 :             aSet.SetParent( pPdSet );
    1677             : 
    1678             :             // am Nachkommen NUR  die Spaltigkeit gemaess Sect-Attr.
    1679             :             // umsetzen
    1680             : 
    1681             :             const SvxLRSpaceItem &rSectionLR =
    1682          15 :                 ItemGet<SvxLRSpaceItem>( *(rSepInfo.pSectionFmt), RES_LR_SPACE );
    1683             :             const SvxLRSpaceItem &rPageLR =
    1684          15 :                 ItemGet<SvxLRSpaceItem>( *pPdFmt, RES_LR_SPACE );
    1685             : 
    1686          15 :             SvxLRSpaceItem aResultLR( rPageLR.GetLeft() +
    1687          30 :                     rSectionLR.GetLeft(), rPageLR.GetRight() +
    1688          45 :                     rSectionLR.GetRight(), 0, 0, RES_LR_SPACE );
    1689             :             //i120133: The Section width should consider section indent value.
    1690          15 :             if (rSectionLR.GetLeft()+rSectionLR.GetRight()!=0)
    1691             :             {
    1692           0 :                 const SwFmtCol& rCol = dynamic_cast<const SwFmtCol&>(rSepInfo.pSectionFmt->GetFmtAttr(RES_COL));
    1693           0 :                 SwFmtCol aCol(rCol);
    1694           0 :                 aCol.SetAdjustValue(rSectionLR.GetLeft()+rSectionLR.GetRight());
    1695           0 :                 aSet.Put(aCol);
    1696             :             }
    1697             :             else
    1698          15 :                 aSet.Put(rSepInfo.pSectionFmt->GetFmtAttr(RES_COL));
    1699             : 
    1700          15 :             aSet.Put( aResultLR );
    1701             : 
    1702             :             // und raus damit ins WW-File
    1703          15 :             const SfxItemSet* pOldI = pISet;
    1704          15 :             pISet = &aSet;
    1705             : 
    1706             :             // Switch off test on default item values, if page description
    1707             :             // set (value of <bOutPgDscSet>) isn't written.
    1708          15 :             AttrOutput().OutputStyleItemSet( aSet, true, bOutPgDscSet );
    1709          15 :             bOutputStyleItemSet = true;
    1710             : 
    1711             :             //Cannot export as normal page framedir, as continuous sections
    1712             :             //cannot contain any grid settings like proper sections
    1713          15 :             AttrOutput().SectionBiDi( FRMDIR_HORI_RIGHT_TOP == TrueFrameDirection( *rSepInfo.pSectionFmt ) );
    1714             : 
    1715          30 :             pISet = pOldI;
    1716             :         }
    1717             :     }
    1718             : 
    1719             :     // Libreoffice 4.0 introduces support for page styles (SwPageDesc) with
    1720             :     // a different header/footer for the first page.  The same effect can be
    1721             :     // achieved by chaining two page styles together (SwPageDesc::GetFollow)
    1722             :     // which are identical except for header/footer.
    1723             :     // The latter method was previously used by the doc/docx import filter.
    1724             :     // In both of these cases, we emit a single Word section with different
    1725             :     // first page header/footer.
    1726         318 :     const SwFrmFmt* pPdFirstPgFmt = &pPd->GetFirstMaster();
    1727         318 :     bool titlePage = !pPd->IsFirstShared();
    1728         318 :     if ( bOutPgDscSet )
    1729             :     {
    1730             :         // if a Follow is set and it does not point to itself,
    1731             :         // then there is a page chain.
    1732             :         // Falls damit eine "Erste Seite" simuliert werden soll, so
    1733             :         // koennen wir das auch als solches schreiben.
    1734             :         // Anders sieht es mit Links/Rechts wechseln aus. Dafuer muss
    1735             :         // erkannt werden, wo der Seitenwechsel statt findet. Hier ist
    1736             :         // es aber dafuer zuspaet!
    1737         933 :         if ( pPd->GetFollow() && pPd != pPd->GetFollow() &&
    1738         375 :              pPd->GetFollow()->GetFollow() == pPd->GetFollow() &&
    1739          48 :              ( !rSepInfo.pPDNd || pPd->IsFollowNextPageOfNode( *rSepInfo.pPDNd ) ) )
    1740             :         {
    1741          24 :             const SwPageDesc *pFollow = pPd->GetFollow();
    1742          24 :             const SwFrmFmt& rFollowFmt = pFollow->GetMaster();
    1743          24 :             if ( sw::util::IsPlausableSingleWordSection( *pPdFirstPgFmt, rFollowFmt ) || titlePage )
    1744             :             {
    1745          24 :                 if (rSepInfo.pPDNd)
    1746          24 :                     pPdFirstPgFmt = pPd->GetPageFmtOfNode( *rSepInfo.pPDNd );
    1747             :                 else
    1748           0 :                     pPdFirstPgFmt = &pPd->GetMaster();
    1749             : 
    1750          24 :                 pAktPageDesc = pPd = pFollow;
    1751          24 :                 pPdFmt = &rFollowFmt;
    1752             : 
    1753             :                 // has different headers/footers for the title page
    1754          24 :                 titlePage = true;
    1755             :             }
    1756             :         }
    1757             : 
    1758         303 :         if( titlePage )
    1759          31 :             AttrOutput().SectionTitlePage();
    1760             : 
    1761         303 :         const SfxItemSet* pOldI = pISet;
    1762             : 
    1763             :         const SfxPoolItem* pItem;
    1764         334 :         if ( titlePage && SFX_ITEM_SET ==
    1765          31 :                 pPdFirstPgFmt->GetItemState( RES_PAPER_BIN, true, &pItem ) )
    1766             :         {
    1767           0 :             pISet = &pPdFirstPgFmt->GetAttrSet();
    1768           0 :             bOutFirstPage = true;
    1769           0 :             AttrOutput().OutputItem( *pItem );
    1770           0 :             bOutFirstPage = false;
    1771             :         }
    1772             : 
    1773             :         // left-/right chain of pagedescs ?
    1774         909 :         if ( pPd->GetFollow() && pPd != pPd->GetFollow() &&
    1775         303 :                 pPd->GetFollow()->GetFollow() == pPd &&
    1776           0 :                 (( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
    1777           0 :                    nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ||
    1778           0 :                  ( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
    1779           0 :                    nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ))
    1780             :         {
    1781           0 :             bLeftRightPgChain = true;
    1782             : 
    1783             :             // which is the reference point? (left or right?)
    1784             :             // assume it is on the right side!
    1785           0 :             if ( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) )
    1786             :             {
    1787           0 :                 nBreakCode = 3;
    1788           0 :                 pPd = pPd->GetFollow();
    1789           0 :                 pPdFmt = &pPd->GetMaster();
    1790             :             }
    1791             :             else
    1792           0 :                 nBreakCode = 4;
    1793             :         }
    1794             : 
    1795         303 :         pISet = &pPdFmt->GetAttrSet();
    1796         303 :         if (!bOutputStyleItemSet)
    1797         303 :             AttrOutput().OutputStyleItemSet( pPdFmt->GetAttrSet(), true, false );
    1798         303 :         AttrOutput().SectionPageBorders( pPdFmt, pPdFirstPgFmt );
    1799         303 :         pISet = pOldI;
    1800             : 
    1801             :         // then the rest of the settings from PageDesc
    1802         303 :         AttrOutput().SectionPageNumbering( pPd->GetNumType().GetNumberingType(), rSepInfo.oPgRestartNo );
    1803             : 
    1804             :         // werden es nur linke oder nur rechte Seiten?
    1805         303 :         if ( 2 == nBreakCode )
    1806             :         {
    1807         295 :             if ( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) )
    1808           0 :                 nBreakCode = 3;
    1809         295 :             else if ( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) )
    1810           0 :                 nBreakCode = 4;
    1811             :         }
    1812             :     }
    1813             : 
    1814         318 :     AttrOutput().SectionType( nBreakCode );
    1815             : 
    1816         318 :     const SwTxtNode* pNd = rSepInfo.pNumNd;
    1817         318 :     if ( pNd )
    1818             :     {
    1819           0 :         const SwNumRule* pRule = pNd->GetNumRule();
    1820           0 :         if ( pRule )
    1821           0 :             OutputOlst( *pRule );
    1822             :     }
    1823             : 
    1824             :     // Header or Footer
    1825         318 :     sal_uInt8 nHeadFootFlags = 0;
    1826             : 
    1827             :     const SwFrmFmt* pPdLeftFmt = bLeftRightPgChain
    1828           0 :         ? &pPd->GetFollow()->GetMaster()
    1829         318 :         : &pPd->GetLeft();
    1830             : 
    1831         318 :     if ( nBreakCode != 0 )
    1832             :     {
    1833         295 :         if ( titlePage )
    1834             :         {
    1835             :             // there is a First Page:
    1836          31 :             MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFirstPgFmt, WW8_HEADER_FIRST );
    1837          31 :             MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFirstPgFmt, WW8_FOOTER_FIRST );
    1838             :         }
    1839         295 :         MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFmt, WW8_HEADER_ODD );
    1840         295 :         MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFmt, WW8_FOOTER_ODD );
    1841             : 
    1842         295 :         if ( !pPd->IsHeaderShared() || bLeftRightPgChain )
    1843           8 :             MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdLeftFmt, WW8_HEADER_EVEN );
    1844             : 
    1845         295 :         if ( !pPd->IsFooterShared() || bLeftRightPgChain )
    1846           8 :             MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdLeftFmt, WW8_FOOTER_EVEN );
    1847         295 :         AttrOutput().SectionWW6HeaderFooterFlags( nHeadFootFlags );
    1848             :     }
    1849             : 
    1850             :     // binary filters only
    1851         318 :     SetupSectionPositions( pA );
    1852             : 
    1853             :     /*
    1854             :        !!!!!!!!!!!
    1855             :     // Umrandungen an Kopf- und Fusstexten muessten etwa so gehen:
    1856             :     // Dabei muss etwas wie pOut eingebaut werden,
    1857             :     // das bei jeder Spezialtext-Zeile wiederholt wird.
    1858             :     const SwFrmFmt* pFFmt = rFt.GetFooterFmt();
    1859             :     const SvxBoxItem& rBox = pFFmt->GetBox(false);
    1860             :     OutWW8_SwFmtBox1( m_rWW8Export.pOut, rBox, false);
    1861             :     !!!!!!!!!!!
    1862             :     You can turn this into paragraph attributes, which are then observed in each paragraph.
    1863             :     Applies to background / border.
    1864             :     !!!!!!!!!!!
    1865             :     */
    1866             : 
    1867         318 :     const SwTxtNode *pOldPageRoot = GetHdFtPageRoot();
    1868         318 :     SetHdFtPageRoot( rSepInfo.pPDNd ? rSepInfo.pPDNd->GetTxtNode() : 0 );
    1869             : 
    1870         318 :     WriteHeadersFooters( nHeadFootFlags, *pPdFmt, *pPdLeftFmt, *pPdFirstPgFmt, nBreakCode );
    1871             : 
    1872         318 :     SetHdFtPageRoot( pOldPageRoot );
    1873             : 
    1874         318 :     AttrOutput().EndSection();
    1875             : 
    1876             :     // outside of the section properties again
    1877         318 :     bOutPageDescs = bOldPg;
    1878             : }
    1879             : 
    1880          12 : bool WW8_WrPlcSepx::WriteKFTxt( WW8Export& rWrt )
    1881             : {
    1882          12 :     sal_uLong nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1883             : 
    1884             :     OSL_ENSURE( !pTxtPos, "who set the pointer?" );
    1885          12 :     pTxtPos = new WW8_WrPlc0( nCpStart );
    1886             : 
    1887          12 :     WriteFtnEndTxt( rWrt, nCpStart );
    1888          12 :     CheckForFacinPg( rWrt );
    1889             : 
    1890          12 :     unsigned int nOldIndex = rWrt.GetHdFtIndex();
    1891          12 :     rWrt.SetHdFtIndex( 0 );
    1892             : 
    1893          27 :     for ( sal_uInt16 i = 0; i < aSects.size(); ++i )
    1894             :     {
    1895          15 :         ::boost::shared_ptr<WW8_PdAttrDesc> const pAttrDesc(new WW8_PdAttrDesc);
    1896          15 :         m_SectionAttributes.push_back(pAttrDesc);
    1897             : 
    1898          15 :         WW8_SepInfo& rSepInfo = aSects[i];
    1899          15 :         rWrt.SectionProperties( rSepInfo, pAttrDesc.get() );
    1900             : 
    1901             :         // FIXME: this writes the section properties, but not of all sections;
    1902             :         // it's possible that later in the document (e.g. in endnotes) sections
    1903             :         // are added, but they won't have their properties written here!
    1904          15 :         m_bHeaderFooterWritten = true;
    1905          15 :     }
    1906          12 :     rWrt.SetHdFtIndex( nOldIndex ); //0
    1907             : 
    1908          12 :     if ( pTxtPos->Count() )
    1909             :     {
    1910             :         // HdFt available?
    1911          12 :         sal_uLong nCpEnd = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1912          12 :         pTxtPos->Append( nCpEnd );  // End of last Header/Footer for PlcfHdd
    1913             : 
    1914          12 :         if ( nCpEnd > nCpStart )
    1915             :         {
    1916           5 :             ++nCpEnd;
    1917           5 :             pTxtPos->Append( nCpEnd + 1 );  // End of last Header/Footer for PlcfHdd
    1918             : 
    1919           5 :             rWrt.WriteStringAsPara( OUString() ); // CR ans Ende ( sonst mault WW )
    1920             :         }
    1921          12 :         rWrt.pFldHdFt->Finish( nCpEnd, rWrt.pFib->ccpText + rWrt.pFib->ccpFtn );
    1922          12 :         rWrt.pFib->ccpHdr = nCpEnd - nCpStart;
    1923             :     }
    1924             :     else
    1925           0 :         delete pTxtPos, pTxtPos = 0;
    1926             : 
    1927          12 :     return rWrt.pFib->ccpHdr != 0;
    1928             : }
    1929             : 
    1930          12 : void WW8_WrPlcSepx::WriteSepx( SvStream& rStrm ) const
    1931             : {
    1932             :     OSL_ENSURE(m_SectionAttributes.size() == static_cast<size_t>(aSects.size())
    1933             :         , "WriteSepx(): arrays out of sync!");
    1934          27 :     for (size_t i = 0; i < m_SectionAttributes.size(); i++) // all sections
    1935             :     {
    1936          15 :         WW8_PdAttrDesc *const pA = m_SectionAttributes[i].get();
    1937          15 :         if (pA->m_nLen && pA->m_pData != 0)
    1938             :         {
    1939             :             SVBT16 nL;
    1940          15 :             pA->m_nSepxFcPos = rStrm.Tell();
    1941          15 :             ShortToSVBT16( pA->m_nLen, nL );
    1942          15 :             rStrm.Write( nL, 2 );
    1943          15 :             rStrm.Write( pA->m_pData.get(), pA->m_nLen );
    1944             :         }
    1945             :     }
    1946          12 : }
    1947             : 
    1948          12 : void WW8_WrPlcSepx::WritePlcSed( WW8Export& rWrt ) const
    1949             : {
    1950             :     OSL_ENSURE(m_SectionAttributes.size() == static_cast<size_t>(aSects.size())
    1951             :         , "WritePlcSed(): arrays out of sync!");
    1952             :     OSL_ENSURE( aCps.size() == aSects.size() + 1, "WrPlcSepx: DeSync" );
    1953          12 :     sal_uLong nFcStart = rWrt.pTableStrm->Tell();
    1954             : 
    1955             :     sal_uInt16 i;
    1956          39 :     for( i = 0; i <= aSects.size(); i++ )
    1957             :     {
    1958          27 :         sal_uInt32 nP = aCps[i];
    1959             :         SVBT32 nPos;
    1960          27 :         UInt32ToSVBT32( nP, nPos );
    1961          27 :         rWrt.pTableStrm->Write( nPos, 4 );
    1962             :     }
    1963             : 
    1964             :     static WW8_SED aSed = {{4, 0},{0, 0, 0, 0},{0, 0},{0xff, 0xff, 0xff, 0xff}};
    1965             : 
    1966          27 :     for (size_t j = 0; j < m_SectionAttributes.size(); j++ )
    1967             :     {
    1968             :         // Sepx-Pos
    1969          15 :         UInt32ToSVBT32( m_SectionAttributes[j]->m_nSepxFcPos, aSed.fcSepx );
    1970          15 :         rWrt.pTableStrm->Write( &aSed, sizeof( aSed ) );
    1971             :     }
    1972          12 :     rWrt.pFib->fcPlcfsed = nFcStart;
    1973          12 :     rWrt.pFib->lcbPlcfsed = rWrt.pTableStrm->Tell() - nFcStart;
    1974          12 : }
    1975             : 
    1976          12 : void WW8_WrPlcSepx::WritePlcHdd( WW8Export& rWrt ) const
    1977             : {
    1978             :     // Don't write out the PlcfHdd if ccpHdd is 0: it's a validation failure case.
    1979          12 :     if( rWrt.pFib->ccpHdr != 0 && pTxtPos && pTxtPos->Count() )
    1980             :     {
    1981           5 :         rWrt.pFib->fcPlcfhdd = rWrt.pTableStrm->Tell();
    1982           5 :         pTxtPos->Write( *rWrt.pTableStrm );             // Plc0
    1983           5 :         rWrt.pFib->lcbPlcfhdd = rWrt.pTableStrm->Tell() -
    1984          10 :                                 rWrt.pFib->fcPlcfhdd;
    1985             :     }
    1986          12 : }
    1987             : 
    1988         203 : void MSWordExportBase::WriteHeaderFooterText( const SwFmt& rFmt, bool bHeader )
    1989             : {
    1990             :     const SwFmtCntnt *pCntnt;
    1991         203 :     if ( bHeader )
    1992             :     {
    1993          98 :         bHasHdr = true;
    1994          98 :         const SwFmtHeader& rHd = rFmt.GetHeader();
    1995             :         OSL_ENSURE( rHd.GetHeaderFmt(), "Header text is not here" );
    1996          98 :         pCntnt = &rHd.GetHeaderFmt()->GetCntnt();
    1997             :     }
    1998             :     else
    1999             :     {
    2000         105 :         bHasFtr = true;
    2001         105 :         const SwFmtFooter& rFt = rFmt.GetFooter();
    2002             :         OSL_ENSURE( rFt.GetFooterFmt(), "Footer text is not here" );
    2003         105 :         pCntnt = &rFt.GetFooterFmt()->GetCntnt();
    2004             :     }
    2005             : 
    2006         203 :     const SwNodeIndex* pSttIdx = pCntnt->GetCntntIdx();
    2007             : 
    2008         203 :     if ( pSttIdx )
    2009             :     {
    2010         203 :         SwNodeIndex aIdx( *pSttIdx, 1 ),
    2011         406 :         aEnd( *pSttIdx->GetNode().EndOfSectionNode() );
    2012         203 :         sal_uLong nStart = aIdx.GetIndex();
    2013         203 :         sal_uLong nEnd = aEnd.GetIndex();
    2014             : 
    2015             :         // Bereich also gueltiger Node
    2016         203 :         if ( nStart < nEnd )
    2017             :         {
    2018         203 :             bool bOldKF = bOutKF;
    2019         203 :             bOutKF = true;
    2020         203 :             WriteSpecialText( nStart, nEnd, TXT_HDFT );
    2021         203 :             bOutKF = bOldKF;
    2022             :         }
    2023             :         else
    2024         203 :             pSttIdx = 0;
    2025             :     }
    2026             : 
    2027         203 :     if ( !pSttIdx )
    2028             :     {
    2029             :         // there is no Header/Footer, but a CR is still necessary
    2030             :         OSL_ENSURE( pSttIdx, "Header/Footer text is not really present" );
    2031           0 :         AttrOutput().EmptyParagraph(); // CR ans Ende ( sonst mault WW )
    2032             :     }
    2033         203 : }
    2034             : 
    2035             : // class WW8_WrPlcFtnEdn : Collect the Footnotes and Endnotes and output their text
    2036             : // and Plcs at the end of the document.
    2037             : // WW8_WrPlcFtnEdn is the class for Footnotes and Endnotes
    2038             : 
    2039          60 : WW8_WrPlcSubDoc::WW8_WrPlcSubDoc()
    2040          60 :     : pTxtPos( 0 )
    2041             : {
    2042          60 : }
    2043             : 
    2044         120 : WW8_WrPlcSubDoc::~WW8_WrPlcSubDoc()
    2045             : {
    2046          60 :     delete pTxtPos;
    2047          60 : }
    2048             : 
    2049           1 : void WW8_WrPlcFtnEdn::Append( WW8_CP nCp, const SwFmtFtn& rFtn )
    2050             : {
    2051           1 :     aCps.push_back( nCp );
    2052           1 :     aCntnt.push_back( &rFtn );
    2053           1 : }
    2054             : 
    2055           5 : WW8_Annotation::WW8_Annotation(const SwPostItField* pPostIt, WW8_CP nRangeStart, WW8_CP nRangeEnd)
    2056             :     :
    2057             :         maDateTime( DateTime::EMPTY ),
    2058             :         m_nRangeStart(nRangeStart),
    2059           5 :         m_nRangeEnd(nRangeEnd)
    2060             : {
    2061           5 :     mpRichText = pPostIt->GetTextObject();
    2062           5 :     if (!mpRichText)
    2063           0 :         msSimpleText = pPostIt->GetTxt();
    2064           5 :     msOwner = pPostIt->GetPar1();
    2065           5 :     m_sInitials = pPostIt->GetInitials();
    2066           5 :     maDateTime = DateTime(pPostIt->GetDate(), pPostIt->GetTime());
    2067           5 : }
    2068             : 
    2069           0 : WW8_Annotation::WW8_Annotation(const SwRedlineData* pRedline)
    2070             :     :
    2071             :         mpRichText(0),
    2072             :         maDateTime( DateTime::EMPTY ),
    2073             :         m_nRangeStart(0),
    2074           0 :         m_nRangeEnd(0)
    2075             : {
    2076           0 :     msSimpleText = pRedline->GetComment();
    2077           0 :     msOwner = SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor());
    2078           0 :     maDateTime = pRedline->GetTimeStamp();
    2079           0 : }
    2080             : 
    2081           4 : void WW8_WrPlcAnnotations::AddRangeStartPosition(const OUString& rName, WW8_CP nStartCp)
    2082             : {
    2083           4 :     m_aRangeStartPositions[rName] = nStartCp;
    2084           4 : }
    2085             : 
    2086           5 : void WW8_WrPlcAnnotations::Append( WW8_CP nCp, const SwPostItField *pPostIt )
    2087             : {
    2088           5 :     aCps.push_back( nCp );
    2089             :     WW8_Annotation* p;
    2090           5 :     if( m_aRangeStartPositions.find(pPostIt->GetName()) != m_aRangeStartPositions.end() )
    2091             :     {
    2092           4 :         p = new WW8_Annotation(pPostIt, m_aRangeStartPositions[pPostIt->GetName()], nCp);
    2093           4 :         m_aRangeStartPositions.erase(pPostIt->GetName());
    2094             :     }
    2095             :     else
    2096             :     {
    2097           1 :         p = new WW8_Annotation(pPostIt, nCp, nCp);
    2098             :     }
    2099           5 :     aCntnt.push_back( p );
    2100           5 : }
    2101             : 
    2102           0 : void WW8_WrPlcAnnotations::Append( WW8_CP nCp, const SwRedlineData *pRedline )
    2103             : {
    2104           0 :     maProcessedRedlines.insert(pRedline);
    2105           0 :     aCps.push_back( nCp );
    2106           0 :     WW8_Annotation* p = new WW8_Annotation(pRedline);
    2107           0 :     aCntnt.push_back( p );
    2108           0 : }
    2109             : 
    2110           0 : bool WW8_WrPlcAnnotations::IsNewRedlineComment( const SwRedlineData *pRedline )
    2111             : {
    2112           0 :     return maProcessedRedlines.find(pRedline) == maProcessedRedlines.end();
    2113             : }
    2114             : 
    2115          36 : WW8_WrPlcAnnotations::~WW8_WrPlcAnnotations()
    2116             : {
    2117          17 :     for( sal_uInt16 n=0; n < aCntnt.size(); n++ )
    2118           5 :         delete (WW8_Annotation*)aCntnt[n];
    2119          24 : }
    2120             : 
    2121          60 : bool WW8_WrPlcSubDoc::WriteGenericTxt( WW8Export& rWrt, sal_uInt8 nTTyp,
    2122             :     WW8_CP& rCount )
    2123             : {
    2124          60 :     sal_uInt16 nLen = aCntnt.size();
    2125          60 :     if ( !nLen )
    2126          55 :         return false;
    2127             : 
    2128           5 :     sal_uLong nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    2129           5 :     pTxtPos = new WW8_WrPlc0( nCpStart );
    2130             :     sal_uInt16 i;
    2131             : 
    2132           5 :     switch ( nTTyp )
    2133             :     {
    2134             :         case TXT_ATN:
    2135           7 :             for ( i = 0; i < nLen; i++ )
    2136             :             {
    2137             :                 // beginning for PlcfAtnTxt
    2138           5 :                 pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
    2139             : 
    2140           5 :                 rWrt.WritePostItBegin();
    2141           5 :                 const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
    2142           5 :                 if (rAtn.mpRichText)
    2143           5 :                     rWrt.WriteOutliner(*rAtn.mpRichText, nTTyp);
    2144             :                 else
    2145             :                 {
    2146           0 :                     OUString sTxt(rAtn.msSimpleText);
    2147           0 :                     rWrt.WriteStringAsPara(sTxt.replace(0x0A, 0x0B));
    2148             :                 }
    2149             :             }
    2150           2 :             break;
    2151             : 
    2152             :         case TXT_TXTBOX:
    2153             :         case TXT_HFTXTBOX:
    2154           4 :             for ( i = 0; i < nLen; i++ )
    2155             :             {
    2156             :                 // textbox content
    2157           2 :                 WW8_CP nCP = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    2158           2 :                 aCps.insert( aCps.begin()+i, nCP );
    2159           2 :                 pTxtPos->Append( nCP );
    2160             : 
    2161           2 :                 if( aCntnt[ i ] != NULL )
    2162             :                 {
    2163             :                 // is it an writer or sdr - textbox?
    2164           2 :                 const SdrObject& rObj = *(SdrObject*)aCntnt[ i ];
    2165           2 :                 if (rObj.GetObjInventor() == FmFormInventor)
    2166             :                 {
    2167           1 :                     sal_uInt8 nOldTyp = rWrt.nTxtTyp;
    2168           1 :                     rWrt.nTxtTyp = nTTyp;
    2169           1 :                     rWrt.GetOCXExp().ExportControl(rWrt,&rObj);
    2170           1 :                     rWrt.nTxtTyp = nOldTyp;
    2171             :                 }
    2172           1 :                 else if( rObj.ISA( SdrTextObj ) )
    2173           0 :                     rWrt.WriteSdrTextObj(rObj, nTTyp);
    2174             :                 else
    2175             :                 {
    2176           1 :                     const SwFrmFmt* pFmt = ::FindFrmFmt( &rObj );
    2177             :                     OSL_ENSURE( pFmt, "where is the format?" );
    2178             : 
    2179           1 :                     const SwNodeIndex* pNdIdx = pFmt->GetCntnt().GetCntntIdx();
    2180             :                     OSL_ENSURE( pNdIdx, "where is the StartNode of the Textbox?" );
    2181           1 :                     rWrt.WriteSpecialText( pNdIdx->GetIndex() + 1,
    2182           1 :                                            pNdIdx->GetNode().EndOfSectionIndex(),
    2183           3 :                                            nTTyp );
    2184             :                     {
    2185           1 :                         SwNodeIndex aContentIdx = *pNdIdx;
    2186           1 :                         ++aContentIdx;
    2187           1 :                         if ( aContentIdx.GetNode().IsTableNode() )
    2188             :                         {
    2189           1 :                             bool bContainsOnlyTables = true;
    2190           1 :                             do {
    2191           1 :                                 aContentIdx = *(aContentIdx.GetNode().EndOfSectionNode());
    2192           1 :                                 ++aContentIdx;
    2193           2 :                                 if ( !aContentIdx.GetNode().IsTableNode() &&
    2194           1 :                                      aContentIdx.GetIndex() != pNdIdx->GetNode().EndOfSectionIndex() )
    2195             :                                 {
    2196           1 :                                     bContainsOnlyTables = false;
    2197             :                                 }
    2198           1 :                             } while ( aContentIdx.GetNode().IsTableNode() );
    2199           1 :                             if ( bContainsOnlyTables )
    2200             :                             {
    2201             :                                 // Additional paragraph containing a space to
    2202             :                                 // assure that by WW created RTF from written WW8
    2203             :                                 // does not crash WW.
    2204           0 :                                 rWrt.WriteStringAsPara( OUString(" ") );
    2205             :                             }
    2206           1 :                         }
    2207             :                     }
    2208             :                 }
    2209             :                 }
    2210           0 :                 else if( i < aSpareFmts.size() )
    2211             :                 {
    2212           0 :                     if( const SwFrmFmt* pFmt = (const SwFrmFmt*)aSpareFmts[ i ] )
    2213             :                     {
    2214           0 :                         const SwNodeIndex* pNdIdx = pFmt->GetCntnt().GetCntntIdx();
    2215           0 :                         rWrt.WriteSpecialText( pNdIdx->GetIndex() + 1,
    2216           0 :                                    pNdIdx->GetNode().EndOfSectionIndex(), nTTyp );
    2217             :                     }
    2218             :                 }
    2219             : 
    2220             :                 // CR at end of one textbox text ( otherwise WW gpft :-( )
    2221           2 :                 rWrt.WriteStringAsPara( OUString() );
    2222             :             }
    2223           2 :             break;
    2224             : 
    2225             :         case TXT_EDN:
    2226             :         case TXT_FTN:
    2227           2 :             for ( i = 0; i < nLen; i++ )
    2228             :             {
    2229             :                 // beginning for PlcfFtnTxt/PlcfEdnTxt
    2230           1 :                 pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
    2231             : 
    2232             :                 // Note content
    2233           1 :                 const SwFmtFtn* pFtn = (SwFmtFtn*)aCntnt[ i ];
    2234           1 :                 rWrt.WriteFtnBegin( *pFtn );
    2235           1 :                 const SwNodeIndex* pIdx = pFtn->GetTxtFtn()->GetStartNode();
    2236             :                 OSL_ENSURE( pIdx, "wo ist der StartNode der Fuss-/EndNote?" );
    2237           1 :                 rWrt.WriteSpecialText( pIdx->GetIndex() + 1,
    2238           1 :                                        pIdx->GetNode().EndOfSectionIndex(),
    2239           3 :                                        nTTyp );
    2240             :             }
    2241           1 :             break;
    2242             : 
    2243             :         default:
    2244             :             OSL_ENSURE( !this, "was ist das fuer ein SubDocType?" );
    2245             :     }
    2246             : 
    2247           5 :     pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
    2248             :     // CR ans Ende ( sonst mault WW )
    2249           5 :     rWrt.WriteStringAsPara( OUString() );
    2250             : 
    2251           5 :     WW8_CP nCpEnd = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    2252           5 :     pTxtPos->Append( nCpEnd );
    2253           5 :     rCount = nCpEnd - nCpStart;
    2254             : 
    2255           5 :     return ( rCount != 0 );
    2256             : }
    2257             : 
    2258          15 : static bool lcl_AuthorComp( const std::pair<OUString,OUString>& aFirst, const std::pair<OUString,OUString>& aSecond)
    2259             : {
    2260          15 :     return aFirst.first < aSecond.first;
    2261             : }
    2262             : 
    2263           7 : static bool lcl_PosComp( const std::pair<WW8_CP, int>& aFirst, const std::pair<WW8_CP, int>& aSecond)
    2264             : {
    2265           7 :     return aFirst.first < aSecond.first;
    2266             : }
    2267             : 
    2268          60 : void WW8_WrPlcSubDoc::WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp,
    2269             :     WW8_FC& rTxtStart, sal_Int32& rTxtCount, WW8_FC& rRefStart, sal_Int32& rRefCount ) const
    2270             : {
    2271             : 
    2272          60 :     sal_uLong nFcStart = rWrt.pTableStrm->Tell();
    2273          60 :     sal_uInt16 nLen = aCps.size();
    2274          60 :     if ( !nLen )
    2275         115 :         return;
    2276             : 
    2277             :     OSL_ENSURE( aCps.size() + 2 == pTxtPos->Count(), "WritePlc: DeSync" );
    2278             : 
    2279           5 :     ::std::vector<std::pair<OUString,OUString> > aStrArr;
    2280             :     typedef ::std::vector<std::pair<OUString,OUString> >::iterator myiter;
    2281           5 :     WW8Fib& rFib = *rWrt.pFib;              // n+1-te CP-Pos nach Handbuch
    2282             :     sal_uInt16 i;
    2283           5 :     bool bWriteCP = true;
    2284             : 
    2285           5 :     switch ( nTTyp )
    2286             :     {
    2287             :         case TXT_ATN:
    2288             :             {
    2289           2 :                 std::vector< std::pair<WW8_CP, int> > aRangeStartPos; // The second of the pair is the original index before sorting.
    2290           4 :                 std::vector< std::pair<WW8_CP, int> > aRangeEndPos; // Same, so we can map between the indexes before/after sorting.
    2291           4 :                 std::map<int, int> aAtnStartMap; // Maps from annotation index to start index.
    2292           4 :                 std::map<int, int> aStartEndMap; // Maps from start index to end index.
    2293             :                 // then write first the GrpXstAtnOwners
    2294           7 :                 for ( i = 0; i < nLen; ++i )
    2295             :                 {
    2296           5 :                     const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
    2297           5 :                     aStrArr.push_back(std::pair<OUString,OUString>(rAtn.msOwner,rAtn.m_sInitials));
    2298           5 :                     if( rAtn.m_nRangeStart != rAtn.m_nRangeEnd )
    2299             :                     {
    2300           4 :                         aRangeStartPos.push_back(std::make_pair(rAtn.m_nRangeStart, i));
    2301           4 :                         aRangeEndPos.push_back(std::make_pair(rAtn.m_nRangeEnd, i));
    2302             :                     }
    2303             :                 }
    2304             : 
    2305             :                 //sort and remove duplicates
    2306           2 :                 ::std::sort(aStrArr.begin(), aStrArr.end(),&lcl_AuthorComp);
    2307           2 :                 myiter aIter = ::std::unique(aStrArr.begin(), aStrArr.end());
    2308           2 :                 aStrArr.erase(aIter, aStrArr.end());
    2309             : 
    2310             :                 // Also sort the start and end positions. We need to reference
    2311             :                 // the start index in the annotation table and also need to
    2312             :                 // reference the end index in the start table, so build a map
    2313             :                 // that knows what index to reference, after sorting.
    2314           2 :                 std::sort(aRangeStartPos.begin(), aRangeStartPos.end(), &lcl_PosComp);
    2315           6 :                 for (i = 0; i < aRangeStartPos.size(); ++i)
    2316           4 :                     aAtnStartMap[aRangeStartPos[i].second] = i;
    2317           2 :                 std::sort(aRangeEndPos.begin(), aRangeEndPos.end(), &lcl_PosComp);
    2318           6 :                 for (i = 0; i < aRangeEndPos.size(); ++i)
    2319           4 :                     aStartEndMap[aRangeEndPos[ aAtnStartMap[i] ].second] = i;
    2320             : 
    2321           2 :                 if ( rWrt.bWrtWW8 )
    2322             :                 {
    2323           6 :                     for ( i = 0; i < aStrArr.size(); ++i )
    2324             :                     {
    2325           4 :                         const OUString& sAuthor = aStrArr[i].first;
    2326           4 :                         SwWW8Writer::WriteShort(*rWrt.pTableStrm, sAuthor.getLength());
    2327             :                         SwWW8Writer::WriteString16(*rWrt.pTableStrm, sAuthor,
    2328           4 :                                 false);
    2329             :                     }
    2330             :                 }
    2331             :                 else
    2332             :                 {
    2333           0 :                     for ( i = 0; i < aStrArr.size(); ++i )
    2334             :                     {
    2335           0 :                         const OUString& sAuthor = aStrArr[i].first;
    2336           0 :                         rWrt.pTableStrm->WriteUChar( (sal_uInt8)sAuthor.getLength() );
    2337             :                         SwWW8Writer::WriteString8(*rWrt.pTableStrm, sAuthor, false,
    2338           0 :                                 RTL_TEXTENCODING_MS_1252);
    2339             :                     }
    2340             :                 }
    2341             : 
    2342           2 :                 rFib.fcGrpStAtnOwners = nFcStart;
    2343           2 :                 nFcStart = rWrt.pTableStrm->Tell();
    2344           2 :                 rFib.lcbGrpStAtnOwners = nFcStart - rFib.fcGrpStAtnOwners;
    2345             : 
    2346             :                 // Commented text ranges
    2347           2 :                 if ( rWrt.bWrtWW8 )
    2348             :                 {
    2349           2 :                     if( aRangeStartPos.size() > 0 )
    2350             :                     {
    2351             :                         // Commented text ranges starting positions (Plcfbkf.aCP)
    2352           2 :                         rFib.fcPlcfAtnbkf = nFcStart;
    2353           6 :                         for ( i = 0; i < aRangeStartPos.size(); ++i )
    2354             :                         {
    2355           4 :                             SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeStartPos[i].first );
    2356             :                         }
    2357           2 :                         SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeStartPos[i-1].first + 1);
    2358             : 
    2359             :                         // Commented text ranges additional informations (Plcfbkf.aFBKF)
    2360           6 :                         for ( i = 0; i < aRangeStartPos.size(); ++i )
    2361             :                         {
    2362           4 :                             SwWW8Writer::WriteShort( *rWrt.pTableStrm, aStartEndMap[i] ); // FBKF.ibkl
    2363           4 :                             SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 ); // FBKF.bkc
    2364             :                         }
    2365             : 
    2366           2 :                         nFcStart = rWrt.pTableStrm->Tell();
    2367           2 :                         rFib.lcbPlcfAtnbkf = nFcStart - rFib.fcPlcfAtnbkf;
    2368             : 
    2369             :                         // Commented text ranges ending positions (PlcfBkl.aCP)
    2370           2 :                         rFib.fcPlcfAtnbkl = nFcStart;
    2371           6 :                         for ( i = 0; i < aRangeEndPos.size(); ++i )
    2372             :                         {
    2373           4 :                             SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeEndPos[i].first );
    2374             :                         }
    2375           2 :                         SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeEndPos[i-1].first + 1);
    2376             : 
    2377           2 :                         nFcStart = rWrt.pTableStrm->Tell();
    2378           2 :                         rFib.lcbPlcfAtnbkl = nFcStart - rFib.fcPlcfAtnbkl;
    2379             : 
    2380             :                         // Commented text ranges as bookmarks (SttbfAtnBkmk)
    2381           2 :                         rFib.fcSttbfAtnbkmk = nFcStart;
    2382           2 :                         SwWW8Writer::WriteShort( *rWrt.pTableStrm, (sal_Int16)(sal_uInt16)0xFFFF ); // SttbfAtnBkmk.fExtend
    2383           2 :                         SwWW8Writer::WriteShort( *rWrt.pTableStrm, aRangeStartPos.size() ); // SttbfAtnBkmk.cData
    2384           2 :                         SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0xA );                   // SttbfAtnBkmk.cbExtra
    2385             : 
    2386           6 :                         for ( i = 0; i < aRangeStartPos.size(); ++i )
    2387             :                         {
    2388           4 :                             SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );         // SttbfAtnBkmk.cchData
    2389             :                             // One ATNBE structure for all text ranges
    2390           4 :                             SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0x0100 );    // ATNBE.bmc
    2391           4 :                             SwWW8Writer::WriteLong( *rWrt.pTableStrm, aAtnStartMap[i] );          // ATNBE.lTag
    2392           4 :                             SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 );         // ATNBE.lTagOld
    2393             :                         }
    2394             : 
    2395           2 :                         nFcStart = rWrt.pTableStrm->Tell();
    2396           2 :                         rFib.lcbSttbfAtnbkmk = nFcStart - rFib.fcSttbfAtnbkmk;
    2397             :                     }
    2398             :                 }
    2399             : 
    2400             :                 // Write the extended >= Word XP ATLD records
    2401           2 :                 if( rWrt.bWrtWW8 )
    2402             :                 {
    2403           7 :                     for( i = 0; i < nLen; ++i )
    2404             :                     {
    2405           5 :                         const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
    2406             : 
    2407           5 :                         sal_uInt32 nDTTM = sw::ms::DateTime2DTTM(rAtn.maDateTime);
    2408             : 
    2409           5 :                         SwWW8Writer::WriteLong( *rWrt.pTableStrm, nDTTM );
    2410           5 :                         SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
    2411           5 :                         SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
    2412           5 :                         SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
    2413           5 :                         SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
    2414             :                     }
    2415             : 
    2416           2 :                     rFib.fcAtrdExtra = nFcStart;
    2417           2 :                     nFcStart = rWrt.pTableStrm->Tell();
    2418           2 :                     rFib.lcbAtrdExtra = nFcStart - rFib.fcAtrdExtra;
    2419           2 :                     rFib.fcHplxsdr = 0x01010002;  //WTF, but apparently necessary
    2420           2 :                     rFib.lcbHplxsdr = 0;
    2421           2 :                 }
    2422             :             }
    2423           2 :             break;
    2424             :         case TXT_TXTBOX:
    2425             :         case TXT_HFTXTBOX:
    2426             :             {
    2427           2 :                 pTxtPos->Write( *rWrt.pTableStrm );
    2428           2 :                 const std::vector<sal_uInt32>* pShapeIds = GetShapeIdArr();
    2429             :                 OSL_ENSURE( pShapeIds, "Where are the ShapeIds?" );
    2430             : 
    2431           4 :                 for ( i = 0; i < nLen; ++i )
    2432             :                 {
    2433             :                     // write textbox story - FTXBXS
    2434             :                     // is it an writer or sdr - textbox?
    2435           2 :                     const SdrObject* pObj = (SdrObject*)aCntnt[ i ];
    2436           2 :                     sal_Int32 nCnt = 1;
    2437           2 :                     if (pObj && !pObj->ISA( SdrTextObj ) )
    2438             :                     {
    2439             :                         // find the "highest" SdrObject of this
    2440           1 :                         const SwFrmFmt& rFmt = *::FindFrmFmt( pObj );
    2441             : 
    2442           1 :                         const SwFmtChain* pChn = &rFmt.GetChain();
    2443           2 :                         while ( pChn->GetNext() )
    2444             :                         {
    2445             :                             // has a chain?
    2446             :                             // then calc the cur pos in the chain
    2447           0 :                             ++nCnt;
    2448           0 :                             pChn = &pChn->GetNext()->GetChain();
    2449             :                         }
    2450             :                     }
    2451           2 :                     if( NULL == pObj )
    2452             :                     {
    2453           0 :                         if( i < aSpareFmts.size() && aSpareFmts[ i ] )
    2454             :                         {
    2455           0 :                             const SwFrmFmt& rFmt = *(const SwFrmFmt*)aSpareFmts[ i ];
    2456             : 
    2457           0 :                             const SwFmtChain* pChn = &rFmt.GetChain();
    2458           0 :                             while( pChn->GetNext() )
    2459             :                             {
    2460             :                                 // has a chain?
    2461             :                                 // then calc the cur pos in the chain
    2462           0 :                                 ++nCnt;
    2463           0 :                                 pChn = &pChn->GetNext()->GetChain();
    2464             :                             }
    2465             :                         }
    2466             :                     }
    2467             :                     // long cTxbx / iNextReuse
    2468           2 :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm, nCnt );
    2469             :                     // long cReusable
    2470           2 :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
    2471             :                     // short fReusable
    2472           2 :                     SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
    2473             :                     // long reserved
    2474           2 :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 );
    2475             :                     // long lid
    2476             :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm,
    2477           2 :                             (*pShapeIds)[i]);
    2478             :                     // long txidUndo
    2479           2 :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
    2480             :                 }
    2481           2 :                 SwWW8Writer::FillCount( *rWrt.pTableStrm, 22 );
    2482           2 :                 bWriteCP = false;
    2483             :             }
    2484           2 :             break;
    2485             :     }
    2486             : 
    2487           5 :     if ( bWriteCP )
    2488             :     {
    2489             :         // write CP Positions
    2490           9 :         for ( i = 0; i < nLen; i++ )
    2491           6 :             SwWW8Writer::WriteLong( *rWrt.pTableStrm, aCps[ i ] );
    2492             : 
    2493             :         // n+1-te CP-Pos nach Handbuch
    2494             :         SwWW8Writer::WriteLong( *rWrt.pTableStrm,
    2495           3 :                 rFib.ccpText + rFib.ccpFtn + rFib.ccpHdr + rFib.ccpEdn +
    2496           3 :                 rFib.ccpTxbx + rFib.ccpHdrTxbx + 1 );
    2497             : 
    2498           3 :         if ( TXT_ATN == nTTyp )
    2499             :         {
    2500           2 :             sal_uInt16 nlTag = 0;
    2501           7 :             for ( i = 0; i < nLen; ++i )
    2502             :             {
    2503           5 :                 const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
    2504             : 
    2505             :                 //aStrArr is sorted
    2506             :                 myiter aIter = ::std::lower_bound(aStrArr.begin(),
    2507             :                         aStrArr.end(), std::pair<OUString,OUString>(rAtn.msOwner,OUString()),
    2508           5 :                         &lcl_AuthorComp);
    2509             :                 OSL_ENSURE(aIter != aStrArr.end() && aIter->first == rAtn.msOwner,
    2510             :                         "Impossible");
    2511           5 :                 sal_uInt16 nFndPos = static_cast< sal_uInt16 >(aIter - aStrArr.begin());
    2512           5 :                 OUString sInitials( aIter->second );
    2513           5 :                 sal_uInt8 nInitialsLen = (sal_uInt8)sInitials.getLength();
    2514           5 :                 if ( nInitialsLen > 9 )
    2515             :                 {
    2516           0 :                     sInitials = sInitials.copy( 0, 9 );
    2517           0 :                     nInitialsLen = 9;
    2518             :                 }
    2519             : 
    2520             :                 // xstUsrInitl[ 10 ] pascal-style String holding initials
    2521             :                 // of annotation author
    2522           5 :                 if ( rWrt.bWrtWW8 )
    2523             :                 {
    2524           5 :                     SwWW8Writer::WriteShort(*rWrt.pTableStrm, nInitialsLen);
    2525             :                     SwWW8Writer::WriteString16(*rWrt.pTableStrm, sInitials,
    2526           5 :                             false);
    2527             :                     SwWW8Writer::FillCount( *rWrt.pTableStrm,
    2528           5 :                             (9 - nInitialsLen) * 2 );
    2529             : 
    2530             :                 }
    2531             :                 else
    2532             :                 {
    2533           0 :                     rWrt.pTableStrm->WriteUChar( nInitialsLen );
    2534             :                     SwWW8Writer::WriteString8(*rWrt.pTableStrm, sInitials,
    2535           0 :                             false, RTL_TEXTENCODING_MS_1252);
    2536           0 :                     SwWW8Writer::FillCount(*rWrt.pTableStrm, 9 - nInitialsLen);
    2537             :                 }
    2538             : 
    2539             :                 // documents layout of WriteShort's below:
    2540             : 
    2541             :                 // SVBT16 ibst;      // index into GrpXstAtnOwners
    2542             :                 // SVBT16 ak;        // not used
    2543             :                 // SVBT16 grfbmc;    // not used
    2544             :                 // SVBT32 ITagBkmk;  // when not -1, this tag identifies the
    2545             : 
    2546           5 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, nFndPos );
    2547           5 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
    2548           5 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
    2549           5 :                 if( rAtn.m_nRangeStart != rAtn.m_nRangeEnd )
    2550             :                 {
    2551           4 :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm, nlTag );
    2552           4 :                     ++nlTag;
    2553             :                 }
    2554             :                 else
    2555           1 :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 );
    2556           5 :             }
    2557             :         }
    2558             :         else
    2559             :         {
    2560           1 :             sal_uInt16 nNo = 0;
    2561           2 :             for ( i = 0; i < nLen; ++i )             // write Flags
    2562             :             {
    2563           1 :                 const SwFmtFtn* pFtn = (SwFmtFtn*)aCntnt[ i ];
    2564             :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm,
    2565           1 :                         !pFtn->GetNumStr().isEmpty() ? 0 : ++nNo );
    2566             :             }
    2567             :         }
    2568             :     }
    2569           5 :     rRefStart = nFcStart;
    2570           5 :     nFcStart = rWrt.pTableStrm->Tell();
    2571           5 :     rRefCount = nFcStart - rRefStart;
    2572             : 
    2573           5 :     pTxtPos->Write( *rWrt.pTableStrm );
    2574             : 
    2575           5 :     switch ( nTTyp )
    2576             :     {
    2577             :         case TXT_TXTBOX:
    2578             :         case TXT_HFTXTBOX:
    2579           4 :             for ( i = 0; i < nLen; ++i )
    2580             :             {
    2581             :                 // write break descriptor (BKD)
    2582             :                 // short itxbxs
    2583           2 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, i );
    2584             :                 // short dcpDepend
    2585           2 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
    2586             :                 // short flags : icol/fTableBreak/fColumnBreak/fMarked/
    2587             :                 //               fUnk/fTextOverflow
    2588           2 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0x800 );
    2589             :             }
    2590           2 :             SwWW8Writer::FillCount( *rWrt.pTableStrm, 6 );
    2591           2 :             break;
    2592             :     }
    2593             : 
    2594           5 :     rTxtStart = nFcStart;
    2595           5 :     rTxtCount = rWrt.pTableStrm->Tell() - nFcStart;
    2596             : }
    2597             : 
    2598           0 : const std::vector<sal_uInt32>* WW8_WrPlcSubDoc::GetShapeIdArr() const
    2599             : {
    2600           0 :     return 0;
    2601          33 : }
    2602             : 
    2603             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10