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

Generated by: LCOV version 1.10