LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - wrtw8sty.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1069 1289 82.9 %
Date: 2014-11-03 Functions: 95 105 90.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10