summaryrefslogtreecommitdiff
path: root/sw/source/filter/ww8/wrtw8sty.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/ww8/wrtw8sty.cxx')
-rw-r--r--sw/source/filter/ww8/wrtw8sty.cxx2264
1 files changed, 2264 insertions, 0 deletions
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx
new file mode 100644
index 000000000000..70d0d043710c
--- /dev/null
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -0,0 +1,2264 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+
+#include <algorithm>
+#include <functional>
+
+#include <com/sun/star/i18n/ScriptType.hdl>
+#include <rtl/tencinfo.h>
+#include <hintids.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/fmglob.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <doc.hxx>
+#include <wrtww8.hxx>
+#include <docary.hxx>
+#include <poolfmt.hxx>
+#include <fmtpdsc.hxx>
+#include <pagedesc.hxx>
+#include <ndtxt.hxx>
+#include <ftninfo.hxx>
+#include <fmthdft.hxx>
+#include <section.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtftn.hxx>
+#include <ndindex.hxx>
+#include <txtftn.hxx>
+#include <charfmt.hxx>
+#include <docufld.hxx>
+#include <dcontact.hxx>
+#include <fmtcnct.hxx>
+#include <ftnidx.hxx>
+#include <fmtclds.hxx>
+#include <lineinfo.hxx>
+#include <fmtline.hxx>
+#include <swtable.hxx>
+#include <msfilter.hxx>
+#include <swmodule.hxx>
+
+#include <writerfilter/doctok/sprmids.hxx>
+
+#include "writerhelper.hxx"
+#include "writerwordglue.hxx"
+#include "../inc/wwstyles.hxx"
+#include "ww8par.hxx"
+#include "ww8attributeoutput.hxx"
+#include "docxattributeoutput.hxx"
+
+using namespace sw::util;
+using namespace nsHdFtFlags;
+
+struct WW8_SED
+{
+ SVBT16 aBits1; // orientation change + internal, Default: 6
+ SVBT32 fcSepx; // FC file offset to beginning of SEPX for section.
+ // 0xFFFFFFFF for no Sprms
+ SVBT16 fnMpr; // used internally by Windows Word, Default: 0
+ SVBT32 fcMpr; // FC, points to offset in FC space for MacWord
+ // Default: 0xffffffff ( nothing )
+ // cbSED is 12 (decimal)), C (hex).
+};
+
+SV_IMPL_VARARR( WW8_WrSepInfoPtrs, WW8_SepInfo )
+
+// class WW8_WrPlc0 ist erstmal nur fuer Header / Footer-Positionen, d.h. es
+// gibt keine inhaltstragende Struktur.
+class WW8_WrPlc0
+{
+private:
+ SvULongs aPos; // PTRARR von CPs / FCs
+ ULONG nOfs;
+
+ //No copying
+ WW8_WrPlc0(const WW8_WrPlc0&);
+ WW8_WrPlc0 &operator=(const WW8_WrPlc0&);
+public:
+ WW8_WrPlc0( ULONG nOffset );
+ USHORT Count() const { return aPos.Count(); }
+ void Append( ULONG nStartCpOrFc );
+ void Write( SvStream& rStrm );
+};
+
+//------------------------------------------------------------
+// Styles
+//------------------------------------------------------------
+
+#define WW8_RESERVED_SLOTS 15
+
+// GetId( SwCharFmt ) zur Benutzung im Text -> nil verboten,
+// "Default Char Style" stattdessen
+USHORT MSWordExportBase::GetId( const SwCharFmt& rFmt ) const
+{
+ USHORT nRet = pStyles->GetSlot( rFmt );
+ return ( nRet != 0x0fff ) ? nRet : 10; // Default Char Style
+}
+
+// GetId( SwTxtFmtColl ) zur Benutzung an TextNodes -> nil verboten,
+// "Standard" stattdessen
+USHORT MSWordExportBase::GetId( const SwTxtFmtColl& rColl ) const
+{
+ USHORT nRet = pStyles->GetSlot( rColl );
+ return ( nRet != 0xfff ) ? nRet : 0; // Default TxtFmtColl
+}
+
+
+
+//typedef pFmtT
+MSWordStyles::MSWordStyles( MSWordExportBase& rExport )
+ : m_rExport( rExport )
+{
+ // if exist any Foot-/End-Notes then get from the EndNoteInfo struct
+ // the CharFormats. They will create it!
+ if ( m_rExport.pDoc->GetFtnIdxs().Count() )
+ {
+ m_rExport.pDoc->GetEndNoteInfo().GetAnchorCharFmt( *m_rExport.pDoc );
+ m_rExport.pDoc->GetEndNoteInfo().GetCharFmt( *m_rExport.pDoc );
+ m_rExport.pDoc->GetFtnInfo().GetAnchorCharFmt( *m_rExport.pDoc );
+ m_rExport.pDoc->GetFtnInfo().GetCharFmt( *m_rExport.pDoc );
+ }
+ USHORT nAlloc = WW8_RESERVED_SLOTS + m_rExport.pDoc->GetCharFmts()->Count() - 1 +
+ m_rExport.pDoc->GetTxtFmtColls()->Count() - 1;
+
+ // etwas grosszuegig ( bis zu 15 frei )
+ pFmtA = new SwFmt*[ nAlloc ];
+ memset( pFmtA, 0, nAlloc * sizeof( SwFmt* ) );
+
+ BuildStylesTable();
+}
+
+MSWordStyles::~MSWordStyles()
+{
+ delete[] pFmtA;
+}
+
+// Sty_SetWWSlot() fuer Abhaengigkeiten der Styles -> nil ist erlaubt
+USHORT MSWordStyles::GetSlot( const SwFmt& rFmt ) const
+{
+ USHORT n;
+ for ( n = 0; n < nUsedSlots; n++ )
+ if ( pFmtA[n] == &rFmt )
+ return n;
+ return 0xfff; // 0xfff: WW: nil
+}
+
+USHORT MSWordStyles::BuildGetSlot( const SwFmt& rFmt )
+{
+ USHORT nRet;
+ switch ( nRet = rFmt.GetPoolFmtId() )
+ {
+ case RES_POOLCOLL_STANDARD:
+ nRet = 0;
+ break;
+
+ case RES_POOLCOLL_HEADLINE1:
+ case RES_POOLCOLL_HEADLINE2:
+ case RES_POOLCOLL_HEADLINE3:
+ case RES_POOLCOLL_HEADLINE4:
+ case RES_POOLCOLL_HEADLINE5:
+ case RES_POOLCOLL_HEADLINE6:
+ case RES_POOLCOLL_HEADLINE7:
+ case RES_POOLCOLL_HEADLINE8:
+ case RES_POOLCOLL_HEADLINE9:
+ nRet -= RES_POOLCOLL_HEADLINE1-1;
+ break;
+
+ //case RES_POOLCHR_FOOTNOTE_ANCHOR: nRet =
+ //case RES_POOLCHR_ENDNOTE_ANCHOR:
+ default:
+ nRet = nUsedSlots++;
+ break;
+ }
+ return nRet;
+}
+
+USHORT MSWordStyles::GetWWId( const SwFmt& rFmt ) const
+{
+ USHORT nRet = ww::stiUser; // User-Style als default
+ USHORT nPoolId = rFmt.GetPoolFmtId();
+ if( nPoolId == RES_POOLCOLL_STANDARD )
+ nRet = 0;
+ else if( nPoolId >= RES_POOLCOLL_HEADLINE1 &&
+ nPoolId <= RES_POOLCOLL_HEADLINE9 )
+ nRet = static_cast< USHORT >(nPoolId + 1 - RES_POOLCOLL_HEADLINE1);
+ else if( nPoolId >= RES_POOLCOLL_TOX_IDX1 &&
+ nPoolId <= RES_POOLCOLL_TOX_IDX3 )
+ nRet = static_cast< USHORT >(nPoolId + 10 - RES_POOLCOLL_TOX_IDX1);
+ else if( nPoolId >= RES_POOLCOLL_TOX_CNTNT1 &&
+ nPoolId <= RES_POOLCOLL_TOX_CNTNT5 )
+ nRet = static_cast< USHORT >(nPoolId + 19 - RES_POOLCOLL_TOX_CNTNT1);
+ else if( nPoolId >= RES_POOLCOLL_TOX_CNTNT6 &&
+ nPoolId <= RES_POOLCOLL_TOX_CNTNT9 )
+ nRet = static_cast< USHORT >(nPoolId + 24 - RES_POOLCOLL_TOX_CNTNT6);
+ else
+ switch( nPoolId )
+ {
+ case RES_POOLCOLL_FOOTNOTE: nRet = 29; break;
+ case RES_POOLCOLL_HEADER: nRet = 31; break;
+ case RES_POOLCOLL_FOOTER: nRet = 32; break;
+ case RES_POOLCOLL_TOX_IDXH: nRet = 33; break;
+ case RES_POOLCOLL_JAKETADRESS: nRet = 36; break;
+ case RES_POOLCOLL_SENDADRESS: nRet = 37; break;
+ case RES_POOLCOLL_ENDNOTE: nRet = 43; break;
+ case RES_POOLCOLL_LISTS_BEGIN: nRet = 47; break;
+ case RES_POOLCOLL_DOC_TITEL: nRet = 62; break;
+ case RES_POOLCOLL_SIGNATURE: nRet = 64; break;
+ case RES_POOLCOLL_TEXT: nRet = 66; break;
+ case RES_POOLCOLL_TEXT_MOVE: nRet = 67; break;
+ case RES_POOLCOLL_DOC_SUBTITEL: nRet = 74; break;
+ case RES_POOLCOLL_TEXT_IDENT: nRet = 77; break;
+
+ case RES_POOLCHR_FOOTNOTE_ANCHOR: nRet = 38; break;
+ case RES_POOLCHR_ENDNOTE_ANCHOR: nRet = 42; break;
+ case RES_POOLCHR_INET_NORMAL: nRet = 85; break;
+ case RES_POOLCHR_INET_VISIT: nRet = 86; break;
+ case RES_POOLCHR_HTML_STRONG: nRet = 87; break;
+ case RES_POOLCHR_HTML_EMPHASIS: nRet = 88; break;
+ case RES_POOLCHR_LINENUM: nRet = 40; break;
+ case RES_POOLCHR_PAGENO: nRet = 41; break;
+ }
+ return nRet;
+}
+
+void MSWordStyles::BuildStylesTable()
+{
+ nUsedSlots = WW8_RESERVED_SLOTS; // soviele sind reserviert fuer
+ // Standard und HeadingX u.a.
+ SwFmt* pFmt;
+ USHORT n;
+ const SvPtrarr& rArr = *m_rExport.pDoc->GetCharFmts(); // erst CharFmt
+ // das Default-ZeichenStyle ( 0 ) wird nicht mit ausgegeben !
+ for( n = 1; n < rArr.Count(); n++ )
+ {
+ pFmt = (SwFmt*)rArr[n];
+ pFmtA[ BuildGetSlot( *pFmt ) ] = pFmt;
+ }
+
+ const SvPtrarr& rArr2 = *m_rExport.pDoc->GetTxtFmtColls(); // dann TxtFmtColls
+ // das Default-TextStyle ( 0 ) wird nicht mit ausgegeben !
+ for( n = 1; n < rArr2.Count(); n++ )
+ {
+ pFmt = (SwFmt*)rArr2[n];
+ pFmtA[ BuildGetSlot( *pFmt ) ] = pFmt;
+ }
+}
+
+/// For WW8 only - extend pO so that the size of pTableStrm is even.
+static void impl_SkipOdd( WW8Bytes* pO, sal_Size nTableStrmTell )
+{
+ if ( ( nTableStrmTell + pO->Count() ) & 1 ) // Start auf gerader
+ pO->Insert( (BYTE)0, pO->Count() ); // Adresse
+}
+
+void WW8AttributeOutput::EndStyle()
+{
+ impl_SkipOdd( m_rWW8Export.pO, m_rWW8Export.pTableStrm->Tell() );
+
+ short nLen = m_rWW8Export.pO->Count() - 2; // Laenge des Styles
+ BYTE* p = (BYTE*)m_rWW8Export.pO->GetData() + nPOPosStdLen1;
+ ShortToSVBT16( nLen, p ); // nachtragen
+ p = (BYTE*)m_rWW8Export.pO->GetData() + nPOPosStdLen2;
+ ShortToSVBT16( nLen, p ); // dito
+
+ m_rWW8Export.pTableStrm->Write( m_rWW8Export.pO->GetData(), m_rWW8Export.pO->Count() ); // ins File damit
+ m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren fuer naechsten
+}
+
+void WW8AttributeOutput::StartStyle( const String& rName, bool bPapFmt, USHORT nWwBase,
+ USHORT nWwNext, USHORT nWwId, USHORT /*nId*/ )
+{
+ BYTE aWW8_STD[ sizeof( WW8_STD ) ];
+ BYTE* pData = aWW8_STD;
+ memset( &aWW8_STD, 0, sizeof( WW8_STD ) );
+
+ UINT16 nBit16 = 0x1000; // fInvalHeight
+ nBit16 |= (ww::stiNil & nWwId);
+ Set_UInt16( pData, nBit16 );
+
+ nBit16 = nWwBase << 4; // istdBase
+ nBit16 |= bPapFmt ? 1 : 2; // sgc
+ Set_UInt16( pData, nBit16 );
+
+ nBit16 = nWwNext << 4; // istdNext
+ nBit16 |= bPapFmt ? 2 : 1; // cupx
+ Set_UInt16( pData, nBit16 );
+
+ pData += sizeof( UINT16 ); // bchUpe
+
+ if( m_rWW8Export.bWrtWW8 )
+ {
+ //-------- jetzt neu:
+ // ab Ver8 gibts zwei Felder mehr:
+ //UINT16 fAutoRedef : 1; /* auto redefine style when appropriate */
+ //UINT16 fHidden : 1; /* hidden from UI? */
+ //UINT16 : 14; /* unused bits */
+ pData += sizeof( UINT16 );
+ }
+
+
+ UINT16 nLen = static_cast< UINT16 >( ( pData - aWW8_STD ) + 1 +
+ ((m_rWW8Export.bWrtWW8 ? 2 : 1 ) * (rName.Len() + 1)) ); // vorlaeufig
+
+ WW8Bytes* pO = m_rWW8Export.pO;
+ nPOPosStdLen1 = pO->Count(); // Adr1 zum nachtragen der Laenge
+
+ SwWW8Writer::InsUInt16( *pO, nLen );
+ pO->Insert( aWW8_STD, static_cast< USHORT >( pData - aWW8_STD ), pO->Count() );
+
+ nPOPosStdLen2 = nPOPosStdLen1 + 8; // Adr2 zum nachtragen von "end of upx"
+
+ // Namen schreiben
+ if( m_rWW8Export.bWrtWW8 )
+ {
+ SwWW8Writer::InsUInt16( *pO, rName.Len() ); // Laenge
+ SwWW8Writer::InsAsString16( *pO, rName );
+ }
+ else
+ {
+ pO->Insert( (BYTE)rName.Len(), pO->Count() ); // Laenge
+ SwWW8Writer::InsAsString8( *pO, rName, RTL_TEXTENCODING_MS_1252 );
+ }
+ pO->Insert( (BYTE)0, pO->Count() ); // Trotz P-String 0 am Ende!
+}
+
+void MSWordStyles::SetStyleDefaults( const SwFmt& rFmt, bool bPap )
+{
+ const SwModify* pOldMod = m_rExport.pOutFmtNode;
+ m_rExport.pOutFmtNode = &rFmt;
+ bool aFlags[ static_cast< USHORT >(RES_FRMATR_END) - RES_CHRATR_BEGIN ];
+ USHORT nStt, nEnd, n;
+ if( bPap )
+ nStt = RES_PARATR_BEGIN, nEnd = RES_FRMATR_END;
+ else
+ nStt = RES_CHRATR_BEGIN, nEnd = RES_TXTATR_END;
+
+ // dynamic defaults
+ const SfxItemPool& rPool = *rFmt.GetAttrSet().GetPool();
+ for( n = nStt; n < nEnd; ++n )
+ aFlags[ n - RES_CHRATR_BEGIN ] = 0 != rPool.GetPoolDefaultItem( n );
+
+ // static defaults, that differs between WinWord and SO
+ if( bPap )
+ {
+ aFlags[ static_cast< USHORT >(RES_PARATR_WIDOWS) - RES_CHRATR_BEGIN ] = 1;
+ aFlags[ static_cast< USHORT >(RES_PARATR_HYPHENZONE) - RES_CHRATR_BEGIN ] = 1;
+ }
+ else
+ {
+ aFlags[ RES_CHRATR_FONTSIZE - RES_CHRATR_BEGIN ] = 1;
+ aFlags[ RES_CHRATR_LANGUAGE - RES_CHRATR_BEGIN ] = 1;
+ }
+
+ const SfxItemSet* pOldI = m_rExport.GetCurItemSet();
+ m_rExport.SetCurItemSet( &rFmt.GetAttrSet() );
+
+ const bool* pFlags = aFlags + ( nStt - RES_CHRATR_BEGIN );
+ for ( n = nStt; n < nEnd; ++n, ++pFlags )
+ {
+ if ( *pFlags && SFX_ITEM_SET != rFmt.GetItemState(n, false))
+ {
+ //If we are a character property then see if it is one of the
+ //western/asian ones that must be collapsed together for export to
+ //word. If so default to the western varient.
+ if ( bPap || m_rExport.CollapseScriptsforWordOk(
+ i18n::ScriptType::LATIN, n) )
+ {
+ m_rExport.AttrOutput().OutputItem( rFmt.GetFmtAttr( n, true ) );
+ }
+ }
+ }
+
+ m_rExport.SetCurItemSet( pOldI );
+ m_rExport.pOutFmtNode = pOldMod;
+}
+
+void WW8AttributeOutput::StartStyleProperties( bool bParProp, USHORT nStyle )
+{
+ WW8Bytes* pO = m_rWW8Export.pO;
+
+ impl_SkipOdd( pO, m_rWW8Export.pTableStrm->Tell() );
+
+ UINT16 nLen = ( bParProp ) ? 2 : 0; // Default-Laenge
+ m_nStyleLenPos = pO->Count(); // Laenge zum Nachtragen
+ // Keinen Pointer merken, da sich bei
+ // _grow der Pointer aendert !
+
+ SwWW8Writer::InsUInt16( *pO, nLen ); // Style-Len
+
+ m_nStyleStartSize = pO->Count();
+
+ if ( bParProp )
+ SwWW8Writer::InsUInt16( *pO, nStyle ); // Style-Nummer
+}
+
+void MSWordStyles::WriteProperties( const SwFmt* pFmt, bool bParProp, USHORT nPos,
+ bool bInsDefCharSiz )
+{
+ m_rExport.AttrOutput().StartStyleProperties( bParProp, nPos );
+
+ ASSERT( m_rExport.pCurrentStyle == NULL, "Current style not NULL" ); // set current style before calling out
+ m_rExport.pCurrentStyle = pFmt;
+
+ m_rExport.OutputFormat( *pFmt, bParProp, !bParProp );
+
+ ASSERT( m_rExport.pCurrentStyle == pFmt, "current style was changed" );
+ // reset current style...
+ m_rExport.pCurrentStyle = NULL;
+
+ if ( bInsDefCharSiz ) // nicht abgeleitet v. anderem Style
+ SetStyleDefaults( *pFmt, bParProp );
+
+ m_rExport.AttrOutput().EndStyleProperties( bParProp );
+}
+
+void WW8AttributeOutput::EndStyleProperties( bool /*bParProp*/ )
+{
+ WW8Bytes* pO = m_rWW8Export.pO;
+
+ UINT16 nLen = pO->Count() - m_nStyleStartSize;
+ BYTE* pUpxLen = (BYTE*)pO->GetData() + m_nStyleLenPos; // Laenge zum Nachtragen
+ ShortToSVBT16( nLen, pUpxLen ); // Default-Laenge eintragen
+}
+
+void MSWordStyles::GetStyleData( SwFmt* pFmt, bool& bFmtColl, USHORT& nBase, USHORT& nNext )
+{
+ bFmtColl = pFmt->Which() == RES_TXTFMTCOLL || pFmt->Which() == RES_CONDTXTFMTCOLL;
+
+ // Default: none
+ nBase = 0xfff;
+
+ // Derived from?
+ if ( !pFmt->IsDefault() )
+ nBase = GetSlot( *pFmt->DerivedFrom() );
+
+ SwFmt* pNext;
+ if ( bFmtColl )
+ pNext = &((SwTxtFmtColl*)pFmt)->GetNextTxtFmtColl();
+ else
+ pNext = pFmt; // CharFmt: next CharFmt == self
+
+ nNext = GetSlot( *pNext );
+}
+
+void WW8AttributeOutput::DefaultStyle( USHORT nStyle )
+{
+ if ( nStyle == 10 ) // Default Char-Style ( nur WW )
+ {
+ if ( m_rWW8Export.bWrtWW8 )
+ {
+ static BYTE __READONLY_DATA aDefCharSty[] = {
+ 0x42, 0x00,
+ 0x41, 0x40, 0xF2, 0xFF, 0xA1, 0x00, 0x42, 0x00,
+ 0x00, 0x00, 0x19, 0x00, 0x41, 0x00, 0x62, 0x00,
+ 0x73, 0x00, 0x61, 0x00, 0x74, 0x00, 0x7A, 0x00,
+ 0x2D, 0x00, 0x53, 0x00, 0x74, 0x00, 0x61, 0x00,
+ 0x6E, 0x00, 0x64, 0x00, 0x61, 0x00, 0x72, 0x00,
+ 0x64, 0x00, 0x73, 0x00, 0x63, 0x00, 0x68, 0x00,
+ 0x72, 0x00, 0x69, 0x00, 0x66, 0x00, 0x74, 0x00,
+ 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x00, 0x00,
+ 0x00, 0x00 };
+ m_rWW8Export.pTableStrm->Write( &aDefCharSty, sizeof( aDefCharSty ) );
+ }
+ else
+ {
+ static BYTE __READONLY_DATA aDefCharSty[] = {
+ 0x26, 0x00,
+ 0x41, 0x40, 0xF2, 0xFF, 0xA1, 0x00, 0x26, 0x00,
+ 0x19, 0x41, 0x62, 0x73, 0x61, 0x74, 0x7A, 0x2D,
+ 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64,
+ 0x73, 0x63, 0x68, 0x72, 0x69, 0x66, 0x74, 0x61,
+ 0x72, 0x74, 0x00, 0x00, 0x00, 0x00 };
+ m_rWW8Export.pTableStrm->Write( &aDefCharSty, sizeof( aDefCharSty ) );
+ }
+ }
+ else
+ {
+ UINT16 n = 0;
+ m_rWW8Export.pTableStrm->Write( &n , 2 ); // leerer Style
+ }
+}
+
+// OutputStyle geht fuer TxtFmtColls und CharFmts
+void MSWordStyles::OutputStyle( SwFmt* pFmt, USHORT nPos )
+{
+ if ( !pFmt )
+ m_rExport.AttrOutput().DefaultStyle( nPos );
+ else
+ {
+ bool bFmtColl;
+ USHORT nBase, nWwNext;
+
+ GetStyleData( pFmt, bFmtColl, nBase, nWwNext );
+
+ m_rExport.AttrOutput().StartStyle( pFmt->GetName(), bFmtColl,
+ nBase, nWwNext, GetWWId( *pFmt ), nPos );
+
+ if ( bFmtColl )
+ WriteProperties( pFmt, true, nPos, nBase==0xfff ); // UPX.papx
+
+ WriteProperties( pFmt, false, nPos, bFmtColl && nBase==0xfff ); // UPX.chpx
+
+ m_rExport.AttrOutput().EndStyle();
+ }
+}
+
+void WW8AttributeOutput::StartStyles()
+{
+ WW8Fib& rFib = *m_rWW8Export.pFib;
+
+ ULONG nCurPos = m_rWW8Export.pTableStrm->Tell();
+ if ( nCurPos & 1 ) // Start auf gerader
+ {
+ *m_rWW8Export.pTableStrm << (char)0; // Adresse
+ ++nCurPos;
+ }
+ rFib.fcStshfOrig = rFib.fcStshf = nCurPos;
+ m_nStyAnzPos = nCurPos + 2; // Anzahl wird nachgetragen
+
+ if ( m_rWW8Export.bWrtWW8 )
+ {
+ static BYTE __READONLY_DATA aStShi[] = {
+ 0x12, 0x00,
+ 0x0F, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x5B, 0x00,
+ 0x0F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00 };
+
+ m_rWW8Export.pTableStrm->Write( &aStShi, sizeof( aStShi ) );
+ }
+ else
+ {
+ static BYTE __READONLY_DATA aStShi[] = {
+ 0x0E, 0x00,
+ 0x0F, 0x00, 0x08, 0x00, 0x01, 0x00, 0x4B, 0x00,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ m_rWW8Export.pTableStrm->Write( &aStShi, sizeof( aStShi ) );
+ }
+}
+
+void WW8AttributeOutput::EndStyles( USHORT nNumberOfStyles )
+{
+ WW8Fib& rFib = *m_rWW8Export.pFib;
+
+ rFib.lcbStshfOrig = rFib.lcbStshf = m_rWW8Export.pTableStrm->Tell() - rFib.fcStshf;
+ SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, m_nStyAnzPos, nNumberOfStyles );
+}
+
+void MSWordStyles::OutputStylesTable()
+{
+ m_rExport.bStyDef = true;
+
+ m_rExport.AttrOutput().StartStyles();
+
+ USHORT n;
+ for ( n = 0; n < nUsedSlots; n++ )
+ OutputStyle( pFmtA[n], n );
+
+ m_rExport.AttrOutput().EndStyles( nUsedSlots );
+
+ m_rExport.bStyDef = false;
+}
+
+/* */
+
+//---------------------------------------------------------------------------
+// Fonts
+//---------------------------------------------------------------------------
+wwFont::wwFont(const String &rFamilyName, FontPitch ePitch, FontFamily eFamily,
+ rtl_TextEncoding eChrSet, bool bWrtWW8) : mbAlt(false), mbWrtWW8(bWrtWW8), mePitch(ePitch), meFamily(eFamily), meChrSet(eChrSet)
+{
+ FontMapExport aResult(rFamilyName);
+ msFamilyNm = aResult.msPrimary;
+ msAltNm = aResult.msSecondary;
+ if (msAltNm.Len() && msAltNm != msFamilyNm &&
+ (msFamilyNm.Len() + msAltNm.Len() + 2 <= 65) )
+ {
+ //max size of szFfn in 65 chars
+ mbAlt = true;
+ }
+
+ memset(maWW8_FFN, 0, sizeof(maWW8_FFN));
+
+ if (bWrtWW8)
+ {
+ maWW8_FFN[0] = (BYTE)( 6 - 1 + 0x22 + ( 2 * ( 1 + msFamilyNm.Len() ) ));
+ if (mbAlt)
+ maWW8_FFN[0] = static_cast< BYTE >(maWW8_FFN[0] + 2 * ( 1 + msAltNm.Len()));
+ }
+ else
+ {
+ maWW8_FFN[0] = (BYTE)( 6 - 1 + 1 + msFamilyNm.Len() );
+ if (mbAlt)
+ maWW8_FFN[0] = static_cast< BYTE >(maWW8_FFN[0] + 1 + msAltNm.Len());
+ }
+
+ BYTE aB = 0;
+ switch(ePitch)
+ {
+ case PITCH_VARIABLE:
+ aB |= 2; // aF.prg = 2
+ break;
+ case PITCH_FIXED:
+ aB |= 1;
+ break;
+ default: // aF.prg = 0 : DEFAULT_PITCH (windows.h)
+ break;
+ }
+ aB |= 1 << 2; // aF.fTrueType = 1; weiss ich nicht besser;
+
+ switch(eFamily)
+ {
+ case FAMILY_ROMAN:
+ aB |= 1 << 4; // aF.ff = 1;
+ break;
+ case FAMILY_SWISS:
+ aB |= 2 << 4; // aF.ff = 2;
+ break;
+ case FAMILY_MODERN:
+ aB |= 3 << 4; // aF.ff = 3;
+ break;
+ case FAMILY_SCRIPT:
+ aB |= 4 << 4; // aF.ff = 4;
+ break;
+ case FAMILY_DECORATIVE:
+ aB |= 5 << 4; // aF.ff = 5;
+ break;
+ default: // aF.ff = 0; FF_DONTCARE (windows.h)
+ break;
+ }
+ maWW8_FFN[1] = aB;
+
+ ShortToSVBT16( 400, &maWW8_FFN[2] ); // weiss ich nicht besser
+ // 400 == FW_NORMAL (windows.h)
+ maWW8_FFN[4] = sw::ms::rtl_TextEncodingToWinCharset(eChrSet);
+
+ if (mbAlt)
+ maWW8_FFN[5] = static_cast< BYTE >(msFamilyNm.Len() + 1);
+}
+
+bool wwFont::Write(SvStream *pTableStrm) const
+{
+ pTableStrm->Write(maWW8_FFN, sizeof(maWW8_FFN)); // fixed part
+ if (mbWrtWW8)
+ {
+ // ab Ver8 sind folgende beiden Felder eingeschoben,
+ // werden von uns ignoriert.
+ //char panose[ 10 ]; // 0x6 PANOSE
+ //char fs[ 24 ]; // 0x10 FONTSIGNATURE
+ SwWW8Writer::FillCount(*pTableStrm, 0x22);
+ SwWW8Writer::WriteString16(*pTableStrm, msFamilyNm, true);
+ if (mbAlt)
+ SwWW8Writer::WriteString16(*pTableStrm, msAltNm, true);
+ }
+ else
+ {
+ SwWW8Writer::WriteString8(*pTableStrm, msFamilyNm, true,
+ RTL_TEXTENCODING_MS_1252);
+ if (mbAlt)
+ {
+ SwWW8Writer::WriteString8( *pTableStrm, msAltNm, true,
+ RTL_TEXTENCODING_MS_1252);
+ }
+ }
+ return true;
+}
+
+#ifdef DOCX
+void wwFont::WriteDocx( const DocxAttributeOutput* rAttrOutput ) const
+{
+ // no font embedding, panose id, subsetting, ... implemented
+
+ rAttrOutput->StartFont( msFamilyNm );
+
+ if ( mbAlt )
+ rAttrOutput->FontAlternateName( msAltNm );
+ rAttrOutput->FontCharset( sw::ms::rtl_TextEncodingToWinCharset( meChrSet ) );
+ rAttrOutput->FontFamilyType( meFamily );
+ rAttrOutput->FontPitchType( mePitch );
+
+ rAttrOutput->EndFont();
+}
+#endif
+
+bool operator<(const wwFont &r1, const wwFont &r2)
+{
+ int nRet = memcmp(r1.maWW8_FFN, r2.maWW8_FFN, sizeof(r1.maWW8_FFN));
+ if (nRet == 0)
+ {
+ StringCompare eRet = r1.msFamilyNm.CompareTo(r2.msFamilyNm);
+ if (eRet == COMPARE_EQUAL)
+ eRet = r1.msAltNm.CompareTo(r2.msAltNm);
+ nRet = eRet;
+ }
+ return nRet < 0;
+}
+
+
+USHORT wwFontHelper::GetId(const wwFont &rFont)
+{
+ USHORT nRet;
+ ::std::map<wwFont, USHORT>::const_iterator aIter = maFonts.find(rFont);
+ if (aIter != maFonts.end())
+ nRet = aIter->second;
+ else
+ {
+ nRet = static_cast< USHORT >(maFonts.size());
+ maFonts[rFont] = nRet;
+ }
+ return nRet;
+}
+
+void wwFontHelper::InitFontTable(bool bWrtWW8,const SwDoc& rDoc)
+{
+ mbWrtWW8 = bWrtWW8;
+
+ GetId(wwFont(CREATE_CONST_ASC("Times New Roman"), PITCH_VARIABLE,
+ FAMILY_ROMAN, RTL_TEXTENCODING_MS_1252,bWrtWW8));
+
+ GetId(wwFont(CREATE_CONST_ASC("Symbol"), PITCH_VARIABLE, FAMILY_ROMAN,
+ RTL_TEXTENCODING_SYMBOL,bWrtWW8));
+
+ GetId(wwFont(CREATE_CONST_ASC("Arial"), PITCH_VARIABLE, FAMILY_SWISS,
+ RTL_TEXTENCODING_MS_1252,bWrtWW8));
+
+ const SvxFontItem* pFont = (const SvxFontItem*)GetDfltAttr(RES_CHRATR_FONT);
+
+ GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
+ pFont->GetFamily(), pFont->GetCharSet(),bWrtWW8));
+
+ const SfxItemPool& rPool = rDoc.GetAttrPool();
+ if (0 != (pFont = (const SvxFontItem*)rPool.GetPoolDefaultItem(RES_CHRATR_FONT)))
+ {
+ GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
+ pFont->GetFamily(), pFont->GetCharSet(),bWrtWW8));
+ }
+}
+
+USHORT wwFontHelper::GetId(const Font& rFont)
+{
+ wwFont aFont(rFont.GetName(), rFont.GetPitch(), rFont.GetFamily(),
+ rFont.GetCharSet(), mbWrtWW8);
+ return GetId(aFont);
+}
+
+USHORT wwFontHelper::GetId(const SvxFontItem& rFont)
+{
+ wwFont aFont(rFont.GetFamilyName(), rFont.GetPitch(), rFont.GetFamily(),
+ rFont.GetCharSet(), mbWrtWW8);
+ return GetId(aFont);
+}
+
+::std::vector< const wwFont* > wwFontHelper::AsVector() const
+{
+ ::std::vector<const wwFont *> aFontList( maFonts.size() );
+
+ typedef ::std::map<wwFont, USHORT>::const_iterator myiter;
+ myiter aEnd = maFonts.end();
+ for ( myiter aIter = maFonts.begin(); aIter != aEnd; ++aIter )
+ aFontList[aIter->second] = &aIter->first;
+
+ return aFontList;
+}
+
+void wwFontHelper::WriteFontTable(SvStream *pTableStream, WW8Fib& rFib)
+{
+ rFib.fcSttbfffn = pTableStream->Tell();
+ /*
+ * Reserve some space to fill in the len after we know how big it is
+ */
+ if (mbWrtWW8)
+ SwWW8Writer::WriteLong(*pTableStream, 0);
+ else
+ SwWW8Writer::WriteShort(*pTableStream, 0);
+
+ /*
+ * Convert from fast insertion map to linear vector in the order that we
+ * want to write.
+ */
+ ::std::vector<const wwFont *> aFontList( AsVector() );
+
+ /*
+ * Write them all to pTableStream
+ */
+ ::std::for_each(aFontList.begin(), aFontList.end(),
+ ::std::bind2nd(::std::mem_fun(&wwFont::Write),pTableStream));
+
+ /*
+ * Write the position and len in the FIB
+ */
+ rFib.lcbSttbfffn = pTableStream->Tell() - rFib.fcSttbfffn;
+ if (mbWrtWW8)
+ SwWW8Writer::WriteLong( *pTableStream, rFib.fcSttbfffn, maFonts.size());
+ else
+ {
+ SwWW8Writer::WriteShort( *pTableStream, rFib.fcSttbfffn,
+ (INT16)rFib.lcbSttbfffn );
+ }
+}
+
+#ifdef DOCX
+void wwFontHelper::WriteFontTable( const DocxAttributeOutput& rAttrOutput )
+{
+ ::std::vector<const wwFont *> aFontList( AsVector() );
+
+ ::std::for_each( aFontList.begin(), aFontList.end(),
+ ::std::bind2nd( ::std::mem_fun( &wwFont::WriteDocx ), &rAttrOutput ) );
+}
+#endif
+
+/* */
+
+WW8_WrPlc0::WW8_WrPlc0( ULONG nOffset )
+ : aPos( 4, 4 ), nOfs( nOffset )
+{
+}
+
+void WW8_WrPlc0::Append( ULONG nStartCpOrFc )
+{
+ aPos.Insert( nStartCpOrFc - nOfs, aPos.Count() );
+}
+
+void WW8_WrPlc0::Write( SvStream& rStrm )
+{
+ USHORT nLen = aPos.Count();
+ for( USHORT i = 0; i < nLen; ++i )
+ {
+ SVBT32 nP;
+ UInt32ToSVBT32( aPos[i], nP );
+ rStrm.Write( nP, 4 );
+ }
+}
+
+//------------------------------------------------------------------------------
+
+/* */
+//------------------------------------------------------------------------------
+// class MSWordSections : Uebersetzung PageDescs in Sections
+// behandelt auch Header und Footer
+//------------------------------------------------------------------------------
+
+MSWordSections::MSWordSections( MSWordExportBase& rExport )
+ : mbDocumentIsProtected( false ),
+ aSects( 4, 4 )
+{
+ const SwSectionFmt *pFmt = 0;
+ rExport.pAktPageDesc = &const_cast<const SwDoc *>(rExport.pDoc)->GetPageDesc( 0 );
+
+ const SfxPoolItem* pI;
+ const SwNode* pNd = rExport.pCurPam->GetCntntNode();
+ const SfxItemSet* pSet = pNd ? &((SwCntntNode*)pNd)->GetSwAttrSet() : 0;
+
+ ULONG nRstLnNum = pSet ? ((SwFmtLineNumber&)pSet->Get( RES_LINENUMBER )).GetStartValue() : 0;
+
+ const SwTableNode* pTblNd = rExport.pCurPam->GetNode()->FindTableNode();
+ const SwSectionNode* pSectNd;
+ if ( pTblNd )
+ {
+ pSet = &pTblNd->GetTable().GetFrmFmt()->GetAttrSet();
+ pNd = pTblNd;
+ }
+ else if ( 0 != ( pSectNd = pNd->FindSectionNode() ) )
+ {
+ if ( TOX_HEADER_SECTION == pSectNd->GetSection().GetType() &&
+ pSectNd->StartOfSectionNode()->IsSectionNode() )
+ {
+ pSectNd = pSectNd->StartOfSectionNode()->GetSectionNode();
+ }
+
+ if ( TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() )
+ {
+ pNd = pSectNd;
+ rExport.pCurPam->GetPoint()->nNode = *pNd;
+ }
+
+ if ( CONTENT_SECTION == pSectNd->GetSection().GetType() )
+ pFmt = pSectNd->GetSection().GetFmt();
+ }
+
+ // Hole evtl. Pagedesc des 1. Nodes
+ if ( pSet &&
+ SFX_ITEM_ON == pSet->GetItemState( RES_PAGEDESC, true, &pI ) &&
+ ( (SwFmtPageDesc*)pI )->GetPageDesc() )
+ {
+ AppendSection( *(SwFmtPageDesc*)pI, *pNd, pFmt, nRstLnNum );
+ }
+ else
+ AppendSection( rExport.pAktPageDesc, pFmt, nRstLnNum );
+}
+
+WW8_WrPlcSepx::WW8_WrPlcSepx( MSWordExportBase& rExport )
+ : MSWordSections( rExport ),
+ aCps( 4, 4 ),
+ pAttrs( 0 ),
+ pTxtPos( 0 )
+{
+ // to be in sync with the AppendSection() call in the MSWordSections
+ // constructor
+ aCps.Insert( ULONG( 0 ), aCps.Count() );
+}
+
+MSWordSections::~MSWordSections()
+{
+}
+
+WW8_WrPlcSepx::~WW8_WrPlcSepx()
+{
+ USHORT nLen = aSects.Count();
+ if( pAttrs )
+ {
+ while( nLen )
+ delete[] pAttrs[ --nLen ].pData;
+ delete[] pAttrs;
+ }
+ delete pTxtPos;
+}
+
+sal_uInt16 MSWordSections::CurrentNumberOfColumns( const SwDoc &rDoc ) const
+{
+ ASSERT( aSects.Count(), "no segement inserted yet" );
+ if ( !aSects.Count() )
+ return 1;
+
+ return NumberOfColumns( rDoc, aSects[aSects.Count() - 1] );
+}
+
+sal_uInt16 MSWordSections::NumberOfColumns( const SwDoc &rDoc, const WW8_SepInfo& rInfo ) const
+{
+ const SwPageDesc* pPd = rInfo.pPageDesc;
+ if ( !pPd )
+ pPd = &rDoc.GetPageDesc( 0 );
+
+ if ( !pPd )
+ {
+ ASSERT( pPd, "totally impossible" );
+ return 1;
+ }
+
+ const SfxItemSet &rSet = pPd->GetMaster().GetAttrSet();
+ SfxItemSet aSet( *rSet.GetPool(), RES_COL, RES_COL );
+ aSet.SetParent( &rSet );
+
+ //0xffffffff, what the hell is going on with that!, fixme most terribly
+ if ( rInfo.pSectionFmt && (SwSectionFmt*)0xFFFFFFFF != rInfo.pSectionFmt )
+ aSet.Put( rInfo.pSectionFmt->GetFmtAttr( RES_COL ) );
+
+ const SwFmtCol& rCol = (const SwFmtCol&)aSet.Get( RES_COL );
+ const SwColumns& rColumns = rCol.GetColumns();
+ return rColumns.Count();
+}
+
+const WW8_SepInfo* MSWordSections::CurrentSectionInfo()
+{
+ if ( aSects.Count() > 0 )
+ return &aSects[aSects.Count() - 1];
+
+ return NULL;
+}
+
+void MSWordSections::AppendSection( const SwPageDesc* pPd,
+ const SwSectionFmt* pSectionFmt, ULONG nLnNumRestartNo )
+{
+ aSects.Insert( WW8_SepInfo( pPd, pSectionFmt, nLnNumRestartNo ),
+ aSects.Count() );
+ NeedsDocumentProtected( aSects[aSects.Count()-1] );
+}
+
+void WW8_WrPlcSepx::AppendSep( WW8_CP nStartCp, const SwPageDesc* pPd,
+ const SwSectionFmt* pSectionFmt, ULONG nLnNumRestartNo )
+{
+ aCps.Insert( nStartCp, aCps.Count() );
+
+ AppendSection( pPd, pSectionFmt, nLnNumRestartNo );
+}
+
+void MSWordSections::AppendSection( const SwFmtPageDesc& rPD,
+ const SwNode& rNd, const SwSectionFmt* pSectionFmt, ULONG nLnNumRestartNo )
+{
+ WW8_SepInfo aI( rPD.GetPageDesc(), pSectionFmt, nLnNumRestartNo,
+ rPD.GetNumOffset(), &rNd );
+ aSects.Insert( aI, aSects.Count() );
+ NeedsDocumentProtected( aI );
+}
+
+void WW8_WrPlcSepx::AppendSep( WW8_CP nStartCp, const SwFmtPageDesc& rPD,
+ const SwNode& rNd, const SwSectionFmt* pSectionFmt, ULONG nLnNumRestartNo )
+{
+ aCps.Insert(nStartCp, aCps.Count());
+
+ AppendSection( rPD, rNd, pSectionFmt, nLnNumRestartNo );
+}
+
+// MSWordSections::SetNum() setzt in jeder Section beim 1. Aufruf den
+// Num-Pointer, alle folgenden Aufrufe werden ignoriert. Damit wird
+// die erste Aufzaehlung einer Section uebernommen.
+
+void MSWordSections::SetNum( const SwTxtNode* pNumNd )
+{
+ WW8_SepInfo& rInfo = aSects[ aSects.Count() - 1 ];
+ if ( !rInfo.pNumNd ) // noch nicht belegt
+ rInfo.pNumNd = pNumNd;
+}
+
+void WW8_WrPlcSepx::WriteFtnEndTxt( WW8Export& rWrt, ULONG nCpStt )
+{
+ BYTE nInfoFlags = 0;
+ const SwFtnInfo& rInfo = rWrt.pDoc->GetFtnInfo();
+ if( rInfo.aErgoSum.Len() ) nInfoFlags |= 0x02;
+ if( rInfo.aQuoVadis.Len() ) nInfoFlags |= 0x04;
+
+ BYTE nEmptyStt = rWrt.bWrtWW8 ? 0 : 6;
+ if( nInfoFlags )
+ {
+ if( rWrt.bWrtWW8 )
+ pTxtPos->Append( nCpStt ); // empty footenote separator
+
+ if( 0x02 & nInfoFlags ) // Footenote contiunation separator
+ {
+ pTxtPos->Append( nCpStt );
+ rWrt.WriteStringAsPara( rInfo.aErgoSum );
+ rWrt.WriteStringAsPara( aEmptyStr );
+ nCpStt = rWrt.Fc2Cp( rWrt.Strm().Tell() );
+ }
+ else if( rWrt.bWrtWW8 )
+ pTxtPos->Append( nCpStt );
+
+ if( 0x04 & nInfoFlags ) // Footenote contiunation notice
+ {
+ pTxtPos->Append( nCpStt );
+ rWrt.WriteStringAsPara( rInfo.aQuoVadis );
+ rWrt.WriteStringAsPara( aEmptyStr );
+ nCpStt = rWrt.Fc2Cp( rWrt.Strm().Tell() );
+ }
+ else if( rWrt.bWrtWW8 )
+ pTxtPos->Append( nCpStt );
+
+ if( rWrt.bWrtWW8 )
+ nEmptyStt = 3;
+ else
+ rWrt.pDop->grpfIhdt = nInfoFlags;
+ }
+
+ while( 6 > nEmptyStt++ )
+ pTxtPos->Append( nCpStt );
+
+ // gleich die Flags am Dop setzen
+ WW8Dop& rDop = *rWrt.pDop;
+ // Footnote Info
+ switch( rInfo.eNum )
+ {
+ case FTNNUM_PAGE: rDop.rncFtn = 2; break;
+ case FTNNUM_CHAPTER: rDop.rncFtn = 1; break;
+ default: rDop.rncFtn = 0; break;
+ } // rncFtn
+ rDop.nfcFtnRef = WW8Export::GetNumId( rInfo.aFmt.GetNumberingType() );
+ rDop.nFtn = rInfo.nFtnOffset + 1;
+ rDop.fpc = rWrt.bFtnAtTxtEnd ? 2 : 1;
+
+ // Endnote Info
+ rDop.rncEdn = 0; // rncEdn: Don't Restart
+ const SwEndNoteInfo& rEndInfo = rWrt.pDoc->GetEndNoteInfo();
+ rDop.nfcEdnRef = WW8Export::GetNumId( rEndInfo.aFmt.GetNumberingType() );
+ rDop.nEdn = rEndInfo.nFtnOffset + 1;
+ rDop.epc = rWrt.bEndAtTxtEnd ? 3 : 0;
+}
+
+void MSWordSections::SetHeaderFlag( BYTE& rHeadFootFlags, const SwFmt& rFmt,
+ BYTE nFlag )
+{
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rFmt.GetItemState(RES_HEADER, true, &pItem)
+ && ((SwFmtHeader*)pItem)->IsActive() &&
+ ((SwFmtHeader*)pItem)->GetHeaderFmt() )
+ rHeadFootFlags |= nFlag;
+}
+
+void MSWordSections::SetFooterFlag( BYTE& rHeadFootFlags, const SwFmt& rFmt,
+ BYTE nFlag )
+{
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rFmt.GetItemState(RES_FOOTER, true, &pItem)
+ && ((SwFmtFooter*)pItem)->IsActive() &&
+ ((SwFmtFooter*)pItem)->GetFooterFmt() )
+ rHeadFootFlags |= nFlag;
+}
+
+void WW8_WrPlcSepx::OutHeaderFooter( WW8Export& rWrt, bool bHeader,
+ const SwFmt& rFmt, ULONG& rCpPos, BYTE nHFFlags,
+ BYTE nFlag, BYTE nBreakCode)
+{
+ if ( nFlag & nHFFlags )
+ {
+ pTxtPos->Append( rCpPos );
+ rWrt.WriteHeaderFooterText( rFmt, bHeader);
+ rWrt.WriteStringAsPara( aEmptyStr ); // CR ans Ende ( sonst mault WW )
+ rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() );
+ }
+ else if ( rWrt.bWrtWW8 )
+ {
+ pTxtPos->Append( rCpPos );
+ if (rWrt.bHasHdr && nBreakCode!=0)
+ {
+ rWrt.WriteStringAsPara( aEmptyStr ); // Empty paragraph for empty header/footer
+ rWrt.WriteStringAsPara( aEmptyStr ); // a CR that WW8 needs for end of the stream
+ rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() );
+ }
+ }
+}
+
+void MSWordSections::NeedsDocumentProtected(const WW8_SepInfo &rInfo)
+{
+ if (rInfo.IsProtected())
+ mbDocumentIsProtected = true;
+}
+
+bool WW8_SepInfo::IsProtected() const
+{
+ bool bRet = false;
+ if (
+ pSectionFmt &&
+ ((SwSectionFmt*)0xFFFFFFFF != pSectionFmt)
+ )
+ {
+ const SwSection *pSection = pSectionFmt->GetSection();
+ if (pSection && pSection->IsProtect())
+ {
+ bRet = true;
+ }
+ }
+ return bRet;
+}
+
+
+void MSWordSections::CheckForFacinPg( WW8Export& rWrt ) const
+{
+ // 2 Werte werden gesetzt
+ // Dop.fFacingPages == Kopf-/Fusszeilen unterschiedlich
+ // Dop.fSwapBordersFacingPgs == gespiegelte Raender
+ for( USHORT i = 0, nEnde = 0; i < aSects.Count(); ++i )
+ {
+ WW8_SepInfo& rSepInfo = aSects[i];
+ if( !rSepInfo.pSectionFmt )
+ {
+ const SwPageDesc* pPd = rSepInfo.pPageDesc;
+ if( pPd->GetFollow() && pPd != pPd->GetFollow() &&
+ pPd->GetFollow()->GetFollow() == pPd->GetFollow() &&
+ rSepInfo.pPDNd &&
+ pPd->IsFollowNextPageOfNode( *rSepInfo.pPDNd ) )
+ // das ist also 1.Seite und nachfolgende, also nur den
+ // follow beachten
+ pPd = pPd->GetFollow();
+
+ // left-/right chain of pagedescs ?
+ else if( !( 1 & nEnde ) &&
+ pPd->GetFollow() && pPd != pPd->GetFollow() &&
+ pPd->GetFollow()->GetFollow() == pPd &&
+ (( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
+ nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ||
+ ( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
+ nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ))
+ {
+ rWrt.pDop->fFacingPages = rWrt.pDop->fMirrorMargins = true;
+ nEnde |= 1;
+ }
+
+ if( !( 1 & nEnde ) &&
+ ( !pPd->IsHeaderShared() || !pPd->IsFooterShared() ))
+ {
+ rWrt.pDop->fFacingPages = true;
+ nEnde |= 1;
+ }
+ if( !( 2 & nEnde ) &&
+ nsUseOnPage::PD_MIRROR == ( nsUseOnPage::PD_MIRROR & pPd->ReadUseOn() ))
+ {
+ rWrt.pDop->fSwapBordersFacingPgs =
+ rWrt.pDop->fMirrorMargins = true;
+ nEnde |= 2;
+ }
+
+ if( 3 == nEnde )
+ break; // weiter brauchen wird nicht
+ }
+ }
+}
+
+int MSWordSections::HasBorderItem( const SwFmt& rFmt )
+{
+ const SfxPoolItem* pItem;
+ return SFX_ITEM_SET == rFmt.GetItemState(RES_BOX, true, &pItem) &&
+ ( ((SvxBoxItem*)pItem)->GetTop() ||
+ ((SvxBoxItem*)pItem)->GetBottom() ||
+ ((SvxBoxItem*)pItem)->GetLeft() ||
+ ((SvxBoxItem*)pItem)->GetRight() );
+}
+
+void WW8AttributeOutput::StartSection()
+{
+ m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren
+}
+
+void WW8AttributeOutput::SectionFormProtection( bool bProtected )
+{
+ //If the document is to be exported as protected, then if a segment
+ //is not protected, set the unlocked flag
+ if ( m_rWW8Export.pSepx->DocumentIsProtected() && !bProtected )
+ {
+ if ( m_rWW8Export.bWrtWW8 )
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFProtected );
+ else
+ m_rWW8Export.pO->Insert( 139, m_rWW8Export.pO->Count() );
+ m_rWW8Export.pO->Insert( 1 , m_rWW8Export.pO->Count() );
+ }
+}
+
+void WW8AttributeOutput::SectionLineNumbering( ULONG nRestartNo, const SwLineNumberInfo& rLnNumInfo )
+{
+ // sprmSNLnnMod - activate Line Numbering and define Modulo
+ if ( m_rWW8Export.bWrtWW8 )
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SNLnnMod );
+ else
+ m_rWW8Export.pO->Insert( 154, m_rWW8Export.pO->Count() );
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (UINT16)rLnNumInfo.GetCountBy() );
+
+ // sprmSDxaLnn - xPosition of Line Number
+ if ( m_rWW8Export.bWrtWW8 )
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SDxaLnn );
+ else
+ m_rWW8Export.pO->Insert( 155, m_rWW8Export.pO->Count() );
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (UINT16)rLnNumInfo.GetPosFromLeft() );
+
+ // sprmSLnc - restart number: 0 per page, 1 per section, 2 never restart
+ if ( nRestartNo || !rLnNumInfo.IsRestartEachPage() )
+ {
+ if ( m_rWW8Export.bWrtWW8 )
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SLnc );
+ else
+ m_rWW8Export.pO->Insert( 152, m_rWW8Export.pO->Count() );
+ m_rWW8Export.pO->Insert( nRestartNo ? 1 : 2, m_rWW8Export.pO->Count() );
+ }
+
+ // sprmSLnnMin - Restart the Line Number with given value
+ if ( nRestartNo )
+ {
+ if ( m_rWW8Export.bWrtWW8 )
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SLnnMin );
+ else
+ m_rWW8Export.pO->Insert( 160, m_rWW8Export.pO->Count() );
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (UINT16)nRestartNo - 1 );
+ }
+}
+
+void WW8AttributeOutput::SectionTitlePage()
+{
+ // sprmSFTitlePage
+ if ( m_rWW8Export.bWrtWW8 )
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFTitlePage );
+ else
+ m_rWW8Export.pO->Insert( 143, m_rWW8Export.pO->Count() );
+ m_rWW8Export.pO->Insert( 1, m_rWW8Export.pO->Count() );
+}
+
+void WW8AttributeOutput::SectionPageBorders( const SwFrmFmt* pPdFmt, const SwFrmFmt* pPdFirstPgFmt )
+{
+ if ( m_rWW8Export.bWrtWW8 ) // Seitenumrandung schreiben
+ {
+ USHORT nPgBorder = MSWordSections::HasBorderItem( *pPdFmt ) ? 0 : USHRT_MAX;
+ if ( pPdFmt != pPdFirstPgFmt )
+ {
+ if ( MSWordSections::HasBorderItem( *pPdFirstPgFmt ) )
+ {
+ if ( USHRT_MAX == nPgBorder )
+ {
+ nPgBorder = 1;
+ // nur die 1. Seite umrandet -> BoxItem aus dem
+ // richtigen Format besorgen
+ m_rWW8Export.pISet = &pPdFirstPgFmt->GetAttrSet();
+ OutputItem( pPdFirstPgFmt->GetFmtAttr( RES_BOX ) );
+ }
+ }
+ else if ( !nPgBorder )
+ nPgBorder = 2;
+ }
+
+ if ( USHRT_MAX != nPgBorder )
+ {
+ // Flag und das Border Attribut schreiben
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SPgbProp );
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nPgBorder );
+ }
+ }
+}
+
+void WW8AttributeOutput::SectionBiDi( bool bBiDi )
+{
+ if ( m_rWW8Export.bWrtWW8 )
+ {
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFBiDi );
+ m_rWW8Export.pO->Insert( bBiDi? 1: 0, m_rWW8Export.pO->Count() );
+ }
+}
+
+void WW8AttributeOutput::SectionPageNumbering( USHORT nNumType, USHORT nPageRestartNumber )
+{
+ // sprmSNfcPgn
+ BYTE nb = WW8Export::GetNumId( nNumType );
+ if ( m_rWW8Export.bWrtWW8 )
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SNfcPgn );
+ else
+ m_rWW8Export.pO->Insert( 147, m_rWW8Export.pO->Count() );
+ m_rWW8Export.pO->Insert( nb, m_rWW8Export.pO->Count() );
+
+ if ( nPageRestartNumber )
+ {
+ // sprmSFPgnRestart
+ if ( m_rWW8Export.bWrtWW8 )
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFPgnRestart );
+ else
+ m_rWW8Export.pO->Insert( 150, m_rWW8Export.pO->Count() );
+ m_rWW8Export.pO->Insert( 1, m_rWW8Export.pO->Count() );
+
+ // sprmSPgnStart
+ if ( m_rWW8Export.bWrtWW8 )
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SPgnStart );
+ else
+ m_rWW8Export.pO->Insert( 161, m_rWW8Export.pO->Count() );
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nPageRestartNumber );
+ }
+}
+
+void WW8AttributeOutput::SectionType( BYTE nBreakCode )
+{
+ if ( 2 != nBreakCode ) // new page is the default
+ {
+ if ( m_rWW8Export.bWrtWW8 )
+ SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SBkc );
+ else
+ m_rWW8Export.pO->Insert( 142, m_rWW8Export.pO->Count() );
+ m_rWW8Export.pO->Insert( nBreakCode, m_rWW8Export.pO->Count() );
+ }
+}
+
+void WW8AttributeOutput::SectionWW6HeaderFooterFlags( BYTE nHeadFootFlags )
+{
+ if ( nHeadFootFlags && !m_rWW8Export.bWrtWW8 )
+ {
+ BYTE nTmpFlags = nHeadFootFlags;
+ if ( m_rWW8Export.pDop->fFacingPages )
+ {
+ if ( !(nTmpFlags & WW8_FOOTER_EVEN) && (nTmpFlags & WW8_FOOTER_ODD ) )
+ nTmpFlags |= WW8_FOOTER_EVEN;
+
+ if ( !(nTmpFlags & WW8_HEADER_EVEN) && (nTmpFlags & WW8_HEADER_ODD ) )
+ nTmpFlags |= WW8_HEADER_EVEN;
+ }
+
+ // sprmSGprfIhdt, wird nur noch im WW95 benoetigt
+ m_rWW8Export.pO->Insert( 153, m_rWW8Export.pO->Count() );
+ m_rWW8Export.pO->Insert( nTmpFlags, m_rWW8Export.pO->Count() );
+ }
+}
+
+void WW8Export::SetupSectionPositions( WW8_PdAttrDesc* pA )
+{
+ if ( !pA )
+ return;
+
+ if ( pO->Count() )
+ { // waren Attrs vorhanden ?
+ pA->nLen = pO->Count();
+ pA->pData = new BYTE [pO->Count()];
+ memcpy( pA->pData, pO->GetData(), pO->Count() ); // -> merken
+ pO->Remove( 0, pO->Count() ); // leeren fuer HdFt-Text
+ }
+ else
+ { // keine Attrs da
+ pA->pData = 0;
+ pA->nLen = 0;
+ }
+}
+
+void WW8Export::WriteHeadersFooters( BYTE nHeadFootFlags,
+ const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt, BYTE nBreakCode )
+{
+ ULONG nCpPos = Fc2Cp( Strm().Tell() );
+
+ IncrementHdFtIndex();
+ if ( !(nHeadFootFlags & WW8_HEADER_EVEN) && pDop->fFacingPages )
+ pSepx->OutHeaderFooter( *this, true, rFmt, nCpPos, nHeadFootFlags, WW8_HEADER_ODD, nBreakCode );
+ else
+ pSepx->OutHeaderFooter( *this, true, rLeftFmt, nCpPos, nHeadFootFlags, WW8_HEADER_EVEN, nBreakCode );
+ IncrementHdFtIndex();
+ pSepx->OutHeaderFooter( *this, true, rFmt, nCpPos, nHeadFootFlags, WW8_HEADER_ODD, nBreakCode );
+
+ IncrementHdFtIndex();
+ if ( !(nHeadFootFlags & WW8_FOOTER_EVEN) && pDop->fFacingPages )
+ pSepx->OutHeaderFooter( *this, false, rFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD, nBreakCode );
+ else
+ pSepx->OutHeaderFooter( *this, false, rLeftFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_EVEN, nBreakCode );
+ IncrementHdFtIndex();
+ pSepx->OutHeaderFooter( *this, false, rFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD, nBreakCode );
+
+ //#i24344# Drawing objects cannot be directly shared between main hd/ft
+ //and title hd/ft so we need to differenciate them
+ IncrementHdFtIndex();
+ pSepx->OutHeaderFooter( *this, true, rFirstPageFmt, nCpPos, nHeadFootFlags, WW8_HEADER_FIRST, nBreakCode );
+ pSepx->OutHeaderFooter( *this, false, rFirstPageFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_FIRST, nBreakCode );
+}
+
+void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAttrDesc* pA )
+{
+ const SwPageDesc* pPd = rSepInfo.pPageDesc;
+
+ if ( rSepInfo.pSectionFmt && !pPd )
+ pPd = &const_cast<const SwDoc *>( pDoc )->GetPageDesc( 0 );
+
+ pAktPageDesc = pPd;
+
+ if ( !pPd )
+ return;
+
+ bool bOldPg = bOutPageDescs;
+ bOutPageDescs = true;
+
+ AttrOutput().StartSection();
+
+ // forms
+ AttrOutput().SectionFormProtection( rSepInfo.IsProtected() );
+
+ // line numbers
+ const SwLineNumberInfo& rLnNumInfo = pDoc->GetLineNumberInfo();
+ if ( rLnNumInfo.IsPaintLineNumbers() )
+ AttrOutput().SectionLineNumbering( rSepInfo.nLnNumRestartNo, rLnNumInfo );
+
+ /* sprmSBkc, break code: 0 No break, 1 New column
+ 2 New page, 3 Even page, 4 Odd page
+ */
+ BYTE nBreakCode = 2; // default neue Seite beginnen
+ bool bOutPgDscSet = true, bLeftRightPgChain = false;
+ const SwFrmFmt* pPdFmt = &pPd->GetMaster();
+ const SwFrmFmt* pPdFirstPgFmt = pPdFmt;
+ if ( rSepInfo.pSectionFmt )
+ {
+ // ist pSectionFmt gesetzt, dann gab es einen SectionNode
+ // gueltiger Pointer -> Section beginnt,
+ // 0xfff -> Section wird beendet
+ nBreakCode = 0; // fortlaufender Abschnitt
+
+ if ( rSepInfo.pPDNd && rSepInfo.pPDNd->IsCntntNode() )
+ {
+ if ( !NoPageBreakSection( &rSepInfo.pPDNd->GetCntntNode()->GetSwAttrSet() ) )
+ {
+ nBreakCode = 2;
+ }
+ }
+
+ if ( (SwSectionFmt*)0xFFFFFFFF != rSepInfo.pSectionFmt )
+ {
+ if ( nBreakCode == 0 )
+ bOutPgDscSet = false;
+
+ // Itemset erzeugen, das das PgDesk-AttrSet beerbt:
+ // als Nachkomme wird bei 'deep'-OutputItemSet
+ // auch der Vorfahr abgeklappert
+ const SfxItemSet* pPdSet = &pPdFmt->GetAttrSet();
+ SfxItemSet aSet( *pPdSet->GetPool(), pPdSet->GetRanges() );
+ aSet.SetParent( pPdSet );
+
+ // am Nachkommen NUR die Spaltigkeit gemaess Sect-Attr.
+ // umsetzen
+ aSet.Put( rSepInfo.pSectionFmt->GetFmtAttr( RES_COL ) );
+
+ const SvxLRSpaceItem &rSectionLR =
+ ItemGet<SvxLRSpaceItem>( *(rSepInfo.pSectionFmt), RES_LR_SPACE );
+ const SvxLRSpaceItem &rPageLR =
+ ItemGet<SvxLRSpaceItem>( *pPdFmt, RES_LR_SPACE );
+
+ SvxLRSpaceItem aResultLR( rPageLR.GetLeft() +
+ rSectionLR.GetLeft(), rPageLR.GetRight() +
+ rSectionLR.GetRight(), 0, 0, RES_LR_SPACE );
+
+ aSet.Put( aResultLR );
+
+ // und raus damit ins WW-File
+ const SfxItemSet* pOldI = pISet;
+ pISet = &aSet;
+ // --> OD 2007-06-12 #TESTING#
+ // Switch off test on default item values, if page description
+ // set (value of <bOutPgDscSet>) isn't written.
+ AttrOutput().OutputStyleItemSet( aSet, true, bOutPgDscSet );
+ // <--
+
+ //Cannot export as normal page framedir, as continous sections
+ //cannot contain any grid settings like proper sections
+ AttrOutput().SectionBiDi( FRMDIR_HORI_RIGHT_TOP == TrueFrameDirection( *rSepInfo.pSectionFmt ) );
+
+ pISet = pOldI;
+ }
+ }
+
+ if ( bOutPgDscSet )
+ {
+ // es ist ein Follow gesetzt und dieser zeigt nicht auf sich
+ // selbst, so liegt eine Seitenverkettung vor.
+ // Falls damit eine "Erste Seite" simuliert werden soll, so
+ // koennen wir das auch als solches schreiben.
+ // Anders sieht es mit Links/Rechts wechseln aus. Dafuer muss
+ // erkannt werden, wo der Seitenwechsel statt findet. Hier ist
+ // es aber dafuer zuspaet!
+ if ( pPd->GetFollow() && pPd != pPd->GetFollow() &&
+ pPd->GetFollow()->GetFollow() == pPd->GetFollow() &&
+ ( !rSepInfo.pPDNd || pPd->IsFollowNextPageOfNode( *rSepInfo.pPDNd ) ) )
+ {
+ const SwPageDesc *pFollow = pPd->GetFollow();
+ const SwFrmFmt& rFollowFmt = pFollow->GetMaster();
+ if ( sw::util::IsPlausableSingleWordSection( *pPdFmt, rFollowFmt ) )
+ {
+ if (rSepInfo.pPDNd)
+ pPdFirstPgFmt = pPd->GetPageFmtOfNode( *rSepInfo.pPDNd );
+ else
+ pPdFirstPgFmt = &pPd->GetMaster();
+
+ pAktPageDesc = pPd = pFollow;
+ pPdFmt = &rFollowFmt;
+
+ // has different headers/footers for the title page
+ AttrOutput().SectionTitlePage();
+ }
+ }
+
+ const SfxItemSet* pOldI = pISet;
+
+ AttrOutput().SectionPageBorders( pPdFmt, pPdFirstPgFmt );
+
+ const SfxPoolItem* pItem;
+ if ( pPdFmt != pPdFirstPgFmt && SFX_ITEM_SET ==
+ pPdFirstPgFmt->GetItemState( RES_PAPER_BIN, true, &pItem ) )
+ {
+ pISet = &pPdFirstPgFmt->GetAttrSet();
+ bOutFirstPage = true;
+ AttrOutput().OutputItem( *pItem );
+ bOutFirstPage = false;
+ }
+
+
+ // left-/right chain of pagedescs ?
+ if ( pPd->GetFollow() && pPd != pPd->GetFollow() &&
+ pPd->GetFollow()->GetFollow() == pPd &&
+ (( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
+ nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ||
+ ( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
+ nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ))
+ {
+ bLeftRightPgChain = true;
+
+ // welches ist der Bezugspunkt ????? (links oder rechts?)
+ // annahme die rechte Seite!
+ if ( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) )
+ {
+ nBreakCode = 3;
+ pPd = pPd->GetFollow();
+ pPdFmt = &pPd->GetMaster();
+ }
+ else
+ nBreakCode = 4;
+ }
+
+ pISet = &pPdFmt->GetAttrSet();
+ AttrOutput().OutputStyleItemSet( pPdFmt->GetAttrSet(), true, false );
+ pISet = pOldI;
+
+ // dann noch die restlichen Einstellungen aus dem PageDesc
+
+ AttrOutput().SectionPageNumbering( pPd->GetNumType().GetNumberingType(), rSepInfo.nPgRestartNo );
+
+ // werden es nur linke oder nur rechte Seiten?
+ if ( 2 == nBreakCode )
+ {
+ if ( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) )
+ nBreakCode = 3;
+ else if ( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) )
+ nBreakCode = 4;
+ }
+ }
+
+ AttrOutput().SectionType( nBreakCode );
+
+ const SwTxtNode* pNd = rSepInfo.pNumNd;
+ if ( pNd )
+ {
+ const SwNumRule* pRule = pNd->GetNumRule();
+ if ( pRule )
+ OutputOlst( *pRule );
+ }
+
+ // Header oder Footer
+ BYTE nHeadFootFlags = 0;
+
+ const SwFrmFmt* pPdLeftFmt = bLeftRightPgChain
+ ? &pPd->GetFollow()->GetMaster()
+ : &pPd->GetLeft();
+
+ if ( nBreakCode != 0 )
+ {
+ MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFmt, WW8_HEADER_ODD );
+ MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFmt, WW8_FOOTER_ODD );
+
+ if ( !pPd->IsHeaderShared() || bLeftRightPgChain )
+ MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdLeftFmt, WW8_HEADER_EVEN );
+
+ if ( !pPd->IsFooterShared() || bLeftRightPgChain )
+ MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdLeftFmt, WW8_FOOTER_EVEN );
+
+ if ( pPdFmt != pPdFirstPgFmt )
+ {
+ // es gibt eine ErsteSeite:
+ MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFirstPgFmt, WW8_HEADER_FIRST );
+ MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFirstPgFmt, WW8_FOOTER_FIRST );
+ }
+
+ AttrOutput().SectionWW6HeaderFooterFlags( nHeadFootFlags );
+ }
+
+ // binary filters only
+ SetupSectionPositions( pA );
+
+ /*
+ !!!!!!!!!!!
+ // Umrandungen an Kopf- und Fusstexten muessten etwa so gehen:
+ // Dabei muss etwas wie pOut eingebaut werden,
+ // das bei jeder Spezialtext-Zeile wiederholt wird.
+ const SwFrmFmt* pFFmt = rFt.GetFooterFmt();
+ const SvxBoxItem& rBox = pFFmt->GetBox(false);
+ OutWW8_SwFmtBox1( m_rWW8Export.pOut, rBox, false);
+ !!!!!!!!!!!
+ Man koennt daraus Absatzattribute machen, die dann bei jedem Absatz
+ beachtet werden. Gilt fuer Hintergrund/Umrandung
+ !!!!!!!!!!!
+ */
+
+ const SwTxtNode *pOldPageRoot = GetHdFtPageRoot();
+ SetHdFtPageRoot( rSepInfo.pPDNd ? rSepInfo.pPDNd->GetTxtNode() : 0 );
+
+ WriteHeadersFooters( nHeadFootFlags, *pPdFmt, *pPdLeftFmt, *pPdFirstPgFmt, nBreakCode );
+
+ SetHdFtPageRoot( pOldPageRoot );
+
+ AttrOutput().EndSection();
+
+ // outside of the section properties again
+ bOutPageDescs = bOldPg;
+}
+
+bool WW8_WrPlcSepx::WriteKFTxt( WW8Export& rWrt )
+{
+ pAttrs = new WW8_PdAttrDesc[ aSects.Count() ];
+ ULONG nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() );
+
+ ASSERT( !pTxtPos, "wer hat den Pointer gesetzt?" );
+ pTxtPos = new WW8_WrPlc0( nCpStart );
+
+ WriteFtnEndTxt( rWrt, nCpStart );
+ CheckForFacinPg( rWrt );
+
+ unsigned int nOldIndex = rWrt.GetHdFtIndex();
+ rWrt.SetHdFtIndex( 0 );
+ for ( USHORT i = 0; i < aSects.Count(); ++i )
+ {
+ WW8_PdAttrDesc* pA = pAttrs + i;
+ pA->pData = 0;
+ pA->nLen = 0;
+ pA->nSepxFcPos = 0xffffffff; // Default: none
+
+ WW8_SepInfo& rSepInfo = aSects[i];
+ rWrt.SectionProperties( rSepInfo, pA );
+ }
+ rWrt.SetHdFtIndex( nOldIndex ); //0
+
+ if ( pTxtPos->Count() )
+ {
+ // HdFt vorhanden ?
+ ULONG nCpEnd = rWrt.Fc2Cp( rWrt.Strm().Tell() );
+ pTxtPos->Append( nCpEnd ); // Ende letzter Hd/Ft fuer PlcfHdd
+
+ if ( nCpEnd > nCpStart )
+ {
+ ++nCpEnd;
+ pTxtPos->Append( nCpEnd + 1 ); // Ende letzter Hd/Ft fuer PlcfHdd
+
+ rWrt.WriteStringAsPara( aEmptyStr ); // CR ans Ende ( sonst mault WW )
+ }
+ rWrt.pFldHdFt->Finish( nCpEnd, rWrt.pFib->ccpText + rWrt.pFib->ccpFtn );
+ rWrt.pFib->ccpHdr = nCpEnd - nCpStart;
+ }
+ else
+ delete pTxtPos, pTxtPos = 0;
+
+ return rWrt.pFib->ccpHdr != 0;
+}
+
+void WW8_WrPlcSepx::WriteSepx( SvStream& rStrm ) const
+{
+ USHORT i;
+ for( i = 0; i < aSects.Count(); i++ ) // ueber alle Sections
+ {
+ WW8_PdAttrDesc* pA = pAttrs + i;
+ if( pA->nLen && pA->pData != NULL)
+ {
+ SVBT16 nL;
+ pA->nSepxFcPos = rStrm.Tell();
+ ShortToSVBT16( pA->nLen, nL );
+ rStrm.Write( nL, 2 );
+ rStrm.Write( pA->pData, pA->nLen );
+ }
+ }
+}
+
+void WW8_WrPlcSepx::WritePlcSed( WW8Export& rWrt ) const
+{
+ ASSERT( aCps.Count() == aSects.Count() + 1, "WrPlcSepx: DeSync" );
+ ULONG nFcStart = rWrt.pTableStrm->Tell();
+
+ USHORT i;
+ // ( ueber alle Sections )
+ for( i = 0; i <= aSects.Count(); i++ )
+ {
+ UINT32 nP = aCps[i];
+ SVBT32 nPos;
+ UInt32ToSVBT32( nP, nPos );
+ rWrt.pTableStrm->Write( nPos, 4 );
+ }
+
+ static WW8_SED aSed = {{4, 0},{0, 0, 0, 0},{0, 0},{0xff, 0xff, 0xff, 0xff}};
+
+ // ( ueber alle Sections )
+ for( i = 0; i < aSects.Count(); i++ )
+ {
+ WW8_PdAttrDesc* pA = pAttrs + i;
+ UInt32ToSVBT32( pA->nSepxFcPos, aSed.fcSepx ); // Sepx-Pos
+ rWrt.pTableStrm->Write( &aSed, sizeof( aSed ) );
+ }
+ rWrt.pFib->fcPlcfsed = nFcStart;
+ rWrt.pFib->lcbPlcfsed = rWrt.pTableStrm->Tell() - nFcStart;
+}
+
+
+void WW8_WrPlcSepx::WritePlcHdd( WW8Export& rWrt ) const
+{
+ if( pTxtPos && pTxtPos->Count() )
+ {
+ rWrt.pFib->fcPlcfhdd = rWrt.pTableStrm->Tell();
+ pTxtPos->Write( *rWrt.pTableStrm ); // Plc0
+ rWrt.pFib->lcbPlcfhdd = rWrt.pTableStrm->Tell() -
+ rWrt.pFib->fcPlcfhdd;
+ }
+}
+
+void MSWordExportBase::WriteHeaderFooterText( const SwFmt& rFmt, bool bHeader )
+{
+ const SwFmtCntnt *pCntnt;
+ if ( bHeader )
+ {
+ bHasHdr = true;
+ const SwFmtHeader& rHd = rFmt.GetHeader();
+ ASSERT( rHd.GetHeaderFmt(), "Header text is not here" );
+ pCntnt = &rHd.GetHeaderFmt()->GetCntnt();
+ }
+ else
+ {
+ bHasFtr = true;
+ const SwFmtFooter& rFt = rFmt.GetFooter();
+ ASSERT( rFt.GetFooterFmt(), "Footer text is not here" );
+ pCntnt = &rFt.GetFooterFmt()->GetCntnt();
+ }
+
+ const SwNodeIndex* pSttIdx = pCntnt->GetCntntIdx();
+
+ if ( pSttIdx )
+ {
+ SwNodeIndex aIdx( *pSttIdx, 1 ),
+ aEnd( *pSttIdx->GetNode().EndOfSectionNode() );
+ ULONG nStart = aIdx.GetIndex();
+ ULONG nEnd = aEnd.GetIndex();
+
+ // Bereich also gueltiger Node
+ if ( nStart < nEnd )
+ {
+ bool bOldKF = bOutKF;
+ bOutKF = true;
+ WriteSpecialText( nStart, nEnd, TXT_HDFT );
+ bOutKF = bOldKF;
+ }
+ else
+ pSttIdx = 0;
+ }
+
+ if ( !pSttIdx )
+ {
+ // es gibt keine Kopf-/Fusszeile, aber ein CR ist immer noch noetig
+ ASSERT( pSttIdx, "K/F-Text nicht richtig da" );
+ AttrOutput().EmptyParagraph(); // CR ans Ende ( sonst mault WW )
+ }
+}
+
+/* */
+//------------------------------------------------------------------------------
+// class WW8_WrPlcFtnEdn : Sammeln der Fuss/Endnoten und Ausgeben der Texte
+// und Plcs am Ende des Docs.
+// WW8_WrPlcFtnEdn ist die Klasse fuer Fuss- und Endnoten
+//------------------------------------------------------------------------------
+WW8_WrPlcSubDoc::WW8_WrPlcSubDoc()
+ : aCps( 0, 16 ), aCntnt( 0, 16 ), pTxtPos( 0 )
+{
+}
+
+WW8_WrPlcSubDoc::~WW8_WrPlcSubDoc()
+{
+ delete pTxtPos;
+}
+
+void WW8_WrPlcFtnEdn::Append( WW8_CP nCp, const SwFmtFtn& rFtn )
+{
+ aCps.Insert( nCp, aCps.Count() );
+ void* p = (void*)&rFtn;
+ aCntnt.Insert( p, aCntnt.Count() );
+}
+
+WW8_Annotation::WW8_Annotation(const SwPostItField* pPostIt)
+{
+ mpRichText = pPostIt->GetTextObject();
+ if (!mpRichText)
+ msSimpleText = pPostIt->GetTxt();
+ msOwner = pPostIt->GetPar1();
+ maDateTime = DateTime(pPostIt->GetDate(), pPostIt->GetTime());
+}
+
+WW8_Annotation::WW8_Annotation(const SwRedlineData* pRedline) : mpRichText(0)
+{
+ msSimpleText = pRedline->GetComment();
+ msOwner = SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor());
+ maDateTime = pRedline->GetTimeStamp();
+}
+
+void WW8_WrPlcAnnotations::Append( WW8_CP nCp, const SwPostItField *pPostIt )
+{
+ aCps.Insert( nCp, aCps.Count() );
+ WW8_Annotation* p = new WW8_Annotation(pPostIt);
+ aCntnt.Insert( p, aCntnt.Count() );
+}
+
+void WW8_WrPlcAnnotations::Append( WW8_CP nCp, const SwRedlineData *pRedline )
+{
+ maProcessedRedlines.insert(pRedline);
+ aCps.Insert( nCp, aCps.Count() );
+ WW8_Annotation* p = new WW8_Annotation(pRedline);
+ aCntnt.Insert( p, aCntnt.Count() );
+}
+
+bool WW8_WrPlcAnnotations::IsNewRedlineComment( const SwRedlineData *pRedline )
+{
+ return maProcessedRedlines.find(pRedline) == maProcessedRedlines.end();
+}
+
+WW8_WrPlcAnnotations::~WW8_WrPlcAnnotations()
+{
+ for( USHORT n=0; n < aCntnt.Count(); n++ )
+ delete (WW8_Annotation*)aCntnt[n];
+}
+
+bool WW8_WrPlcSubDoc::WriteGenericTxt( WW8Export& rWrt, BYTE nTTyp,
+ WW8_CP& rCount )
+{
+ USHORT nLen = aCntnt.Count();
+ if ( !nLen )
+ return false;
+
+ ULONG nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() );
+ pTxtPos = new WW8_WrPlc0( nCpStart );
+ USHORT i;
+
+ switch ( nTTyp )
+ {
+ case TXT_ATN:
+ for ( i = 0; i < nLen; i++ )
+ {
+ // Anfaenge fuer PlcfAtnTxt
+ pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
+
+ rWrt.WritePostItBegin();
+ const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
+ if (rAtn.mpRichText)
+ rWrt.WriteOutliner(*rAtn.mpRichText, nTTyp);
+ else
+ {
+ String sTxt(rAtn.msSimpleText);
+ sTxt.SearchAndReplaceAll(0x0A, 0x0B);
+ rWrt.WriteStringAsPara( sTxt );
+ }
+ }
+ break;
+
+ case TXT_TXTBOX:
+ case TXT_HFTXTBOX:
+ for ( i = 0; i < nLen; i++ )
+ {
+ // textbox - content
+ WW8_CP nCP = rWrt.Fc2Cp( rWrt.Strm().Tell() );
+ aCps.Insert( nCP, i );
+ pTxtPos->Append( nCP );
+
+ // is it an writer or sdr - textbox?
+ const SdrObject& rObj = *(SdrObject*)aCntnt[ i ];
+ if (rObj.GetObjInventor() == FmFormInventor)
+ {
+ BYTE nOldTyp = rWrt.nTxtTyp;
+ rWrt.nTxtTyp = nTTyp;
+ rWrt.GetOCXExp().ExportControl(rWrt,&rObj);
+ rWrt.nTxtTyp = nOldTyp;
+ }
+ else if( rObj.ISA( SdrTextObj ) )
+ rWrt.WriteSdrTextObj(rObj, nTTyp);
+ else
+ {
+ const SwFrmFmt* pFmt = ::FindFrmFmt( &rObj );
+ ASSERT( pFmt, "wo ist das Format geblieben?" );
+
+ const SwNodeIndex* pNdIdx = pFmt->GetCntnt().GetCntntIdx();
+ ASSERT( pNdIdx, "wo ist der StartNode der Textbox?" );
+ rWrt.WriteSpecialText( pNdIdx->GetIndex() + 1,
+ pNdIdx->GetNode().EndOfSectionIndex(),
+ nTTyp );
+ // --> OD 2008-08-07 #156757#
+ {
+ SwNodeIndex aContentIdx = *pNdIdx;
+ aContentIdx++;
+ if ( aContentIdx.GetNode().IsTableNode() )
+ {
+ bool bContainsOnlyTables = true;
+ do {
+ aContentIdx = *(aContentIdx.GetNode().EndOfSectionNode());
+ aContentIdx++;
+ if ( !aContentIdx.GetNode().IsTableNode() &&
+ aContentIdx.GetIndex() != pNdIdx->GetNode().EndOfSectionIndex() )
+ {
+ bContainsOnlyTables = false;
+ }
+ } while ( aContentIdx.GetNode().IsTableNode() );
+ if ( bContainsOnlyTables )
+ {
+ // Additional paragraph containing a space to
+ // assure that by WW created RTF from written WW8
+ // does not crash WW.
+ rWrt.WriteStringAsPara( String::CreateFromAscii( " " ) );
+ }
+ }
+ }
+ // <--
+ }
+
+ // CR at end of one textbox text ( otherwise WW gpft :-( )
+ rWrt.WriteStringAsPara( aEmptyStr );
+ }
+ break;
+
+ case TXT_EDN:
+ case TXT_FTN:
+ for ( i = 0; i < nLen; i++ )
+ {
+ // Anfaenge fuer PlcfFtnTxt/PlcfEdnTxt
+ pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
+
+ // Noten-Inhalt
+ const SwFmtFtn* pFtn = (SwFmtFtn*)aCntnt[ i ];
+ rWrt.WriteFtnBegin( *pFtn );
+ const SwNodeIndex* pIdx = pFtn->GetTxtFtn()->GetStartNode();
+ ASSERT( pIdx, "wo ist der StartNode der Fuss-/EndNote?" );
+ rWrt.WriteSpecialText( pIdx->GetIndex() + 1,
+ pIdx->GetNode().EndOfSectionIndex(),
+ nTTyp );
+ }
+ break;
+
+ default:
+ ASSERT( !this, "was ist das fuer ein SubDocType?" );
+ }
+
+ pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
+ // CR ans Ende ( sonst mault WW )
+ rWrt.WriteStringAsPara( aEmptyStr );
+
+ WW8_CP nCpEnd = rWrt.Fc2Cp( rWrt.Strm().Tell() );
+ pTxtPos->Append( nCpEnd );
+ rCount = nCpEnd - nCpStart;
+
+ return ( rCount != 0 );
+}
+
+void WW8_WrPlcSubDoc::WriteGenericPlc( WW8Export& rWrt, BYTE nTTyp,
+ WW8_FC& rTxtStart, sal_Int32& rTxtCount, WW8_FC& rRefStart, sal_Int32& rRefCount ) const
+{
+ typedef ::std::vector<String>::iterator myiter;
+
+ ULONG nFcStart = rWrt.pTableStrm->Tell();
+ USHORT nLen = aCps.Count();
+ if ( !nLen )
+ return;
+
+ ASSERT( aCps.Count() + 2 == pTxtPos->Count(), "WritePlc: DeSync" );
+
+ ::std::vector<String> aStrArr;
+ WW8Fib& rFib = *rWrt.pFib; // n+1-te CP-Pos nach Handbuch
+ USHORT i;
+ bool bWriteCP = true;
+
+ switch ( nTTyp )
+ {
+ case TXT_ATN:
+ {
+ // then write first the GrpXstAtnOwners
+ for ( i = 0; i < nLen; ++i )
+ {
+ const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
+ aStrArr.push_back(rAtn.msOwner);
+ }
+
+ //sort and remove duplicates
+ ::std::sort(aStrArr.begin(), aStrArr.end());
+ myiter aIter = ::std::unique(aStrArr.begin(), aStrArr.end());
+ aStrArr.erase(aIter, aStrArr.end());
+
+ if ( rWrt.bWrtWW8 )
+ {
+ for ( i = 0; i < aStrArr.size(); ++i )
+ {
+ const String& rStr = aStrArr[i];
+ SwWW8Writer::WriteShort(*rWrt.pTableStrm, rStr.Len());
+ SwWW8Writer::WriteString16(*rWrt.pTableStrm, rStr,
+ false);
+ }
+ }
+ else
+ {
+ for ( i = 0; i < aStrArr.size(); ++i )
+ {
+ const String& rStr = aStrArr[i];
+ *rWrt.pTableStrm << (BYTE)rStr.Len();
+ SwWW8Writer::WriteString8(*rWrt.pTableStrm, rStr, false,
+ RTL_TEXTENCODING_MS_1252);
+ }
+ }
+
+ rFib.fcGrpStAtnOwners = nFcStart;
+ nFcStart = rWrt.pTableStrm->Tell();
+ rFib.lcbGrpStAtnOwners = nFcStart - rFib.fcGrpStAtnOwners;
+
+ // Write the extended >= Word XP ATLD records
+ if( rWrt.bWrtWW8 )
+ {
+ for( i = 0; i < nLen; ++i )
+ {
+ const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
+
+ sal_uInt32 nDTTM = sw::ms::DateTime2DTTM(rAtn.maDateTime);
+
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, nDTTM );
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
+ }
+
+ rFib.fcAtrdExtra = nFcStart;
+ nFcStart = rWrt.pTableStrm->Tell();
+ rFib.lcbAtrdExtra = nFcStart - rFib.fcAtrdExtra;
+ rFib.fcHplxsdr = 0x01010002; //WTF, but apparently necessary
+ rFib.lcbHplxsdr = 0;
+ }
+ }
+ break;
+ case TXT_TXTBOX:
+ case TXT_HFTXTBOX:
+ {
+ pTxtPos->Write( *rWrt.pTableStrm );
+ const SvULongs* pShapeIds = GetShapeIdArr();
+ ASSERT( pShapeIds, "wo sind die ShapeIds?" );
+
+ // nLen = pTxtPos->Count();
+ for ( i = 0; i < nLen; ++i )
+ {
+ // write textbox story - FTXBXS
+ // is it an writer or sdr - textbox?
+ const SdrObject* pObj = (SdrObject*)aCntnt[ i ];
+ INT32 nCnt = 1;
+ if ( !pObj->ISA( SdrTextObj ) )
+ {
+ // find the "highest" SdrObject of this
+ const SwFrmFmt& rFmt = *::FindFrmFmt( pObj );
+
+ const SwFmtChain* pChn = &rFmt.GetChain();
+ while ( pChn->GetNext() )
+ {
+ // has a chain?
+ // then calc the cur pos in the chain
+ ++nCnt;
+ pChn = &pChn->GetNext()->GetChain();
+ }
+ }
+ // long cTxbx / iNextReuse
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, nCnt );
+ // long cReusable
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
+ // short fReusable
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
+ // long reserved
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 );
+ // long lid
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm,
+ (*pShapeIds)[i]);
+ // long txidUndo
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
+ }
+ SwWW8Writer::FillCount( *rWrt.pTableStrm, 22 );
+ bWriteCP = false;
+ }
+ break;
+ }
+
+ if ( bWriteCP )
+ {
+ // Schreibe CP-Positionen
+ for ( i = 0; i < nLen; i++ )
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, aCps[ i ] );
+
+ // n+1-te CP-Pos nach Handbuch
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm,
+ rFib.ccpText + rFib.ccpFtn + rFib.ccpHdr + rFib.ccpEdn +
+ rFib.ccpTxbx + rFib.ccpHdrTxbx + 1 );
+
+ if ( TXT_ATN == nTTyp )
+ {
+ for ( i = 0; i < nLen; ++i )
+ {
+ const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
+
+ //aStrArr is sorted
+ myiter aIter = ::std::lower_bound(aStrArr.begin(),
+ aStrArr.end(), rAtn.msOwner);
+ ASSERT(aIter != aStrArr.end() && *aIter == rAtn.msOwner,
+ "Impossible");
+ sal_uInt16 nFndPos = static_cast< sal_uInt16 >(aIter - aStrArr.begin());
+ String sAuthor(*aIter);
+ BYTE nNameLen = (BYTE)sAuthor.Len();
+ if ( nNameLen > 9 )
+ {
+ sAuthor.Erase( 9 );
+ nNameLen = 9;
+ }
+
+ // xstUsrInitl[ 10 ] pascal-style String holding initials
+ // of annotation author
+ if ( rWrt.bWrtWW8 )
+ {
+ SwWW8Writer::WriteShort(*rWrt.pTableStrm, nNameLen);
+ SwWW8Writer::WriteString16(*rWrt.pTableStrm, sAuthor,
+ false);
+ SwWW8Writer::FillCount( *rWrt.pTableStrm,
+ (9 - nNameLen) * 2 );
+
+ }
+ else
+ {
+ *rWrt.pTableStrm << nNameLen;
+ SwWW8Writer::WriteString8(*rWrt.pTableStrm, sAuthor,
+ false, RTL_TEXTENCODING_MS_1252);
+ SwWW8Writer::FillCount(*rWrt.pTableStrm, 9 - nNameLen);
+ }
+
+ //SVBT16 ibst; // index into GrpXstAtnOwners
+ //SVBT16 ak; // not used
+ //SVBT16 grfbmc; // not used
+ //SVBT32 ITagBkmk; // when not -1, this tag identifies the
+
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm, nFndPos );
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 );
+ }
+ }
+ else
+ {
+ USHORT nNo = 0;
+ for ( i = 0; i < nLen; ++i ) // Schreibe Flags
+ {
+ const SwFmtFtn* pFtn = (SwFmtFtn*)aCntnt[ i ];
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm,
+ pFtn->GetNumStr().Len() ? 0 : ++nNo );
+ }
+ }
+ }
+ rRefStart = nFcStart;
+ nFcStart = rWrt.pTableStrm->Tell();
+ rRefCount = nFcStart - rRefStart;
+
+ pTxtPos->Write( *rWrt.pTableStrm );
+
+ switch ( nTTyp )
+ {
+ case TXT_TXTBOX:
+ case TXT_HFTXTBOX:
+ for ( i = 0; i < nLen; ++i )
+ {
+ // write break descriptor (BKD)
+ // short itxbxs
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm, i );
+ // short dcpDepend
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
+ // short flags : icol/fTableBreak/fColumnBreak/fMarked/
+ // fUnk/fTextOverflow
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0x800 );
+ }
+ SwWW8Writer::FillCount( *rWrt.pTableStrm, 6 );
+ break;
+ }
+
+ rTxtStart = nFcStart;
+ rTxtCount = rWrt.pTableStrm->Tell() - nFcStart;
+}
+
+const SvULongs* WW8_WrPlcSubDoc::GetShapeIdArr() const
+{
+ return 0;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */