summaryrefslogtreecommitdiff
path: root/sw/source/filter/ww8/wrtww8.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/ww8/wrtww8.cxx')
-rw-r--r--sw/source/filter/ww8/wrtww8.cxx2226
1 files changed, 2226 insertions, 0 deletions
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
new file mode 100644
index 000000000000..81ac65a89408
--- /dev/null
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -0,0 +1,2226 @@
+/*************************************************************************
+ *
+ * $RCSfile: wrtww8.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:14:58 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PCH
+#include "filt_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER
+
+#include <string.h> // memcpy()
+
+#ifndef _HINTIDS_HXX
+#include <hintids.hxx>
+#endif
+
+#ifndef _SV_SALBTYPE_HXX
+#include <vcl/salbtype.hxx>
+#endif
+#ifndef _SVSTOR_HXX
+#include <so3/svstor.hxx>
+#endif
+#ifndef _ZFORMAT_HXX
+#include <svtools/zformat.hxx>
+#endif
+#ifndef _SFXDOCINF_HXX
+#include <sfx2/docinf.hxx>
+#endif
+#ifndef _SVX_TSPTITEM_HXX
+#include <svx/tstpitem.hxx>
+#endif
+#ifndef _SVDMODEL_HXX
+#include <svx/svdmodel.hxx>
+#endif
+#ifndef _SVDPAGE_HXX
+#include <svx/svdpage.hxx>
+#endif
+#ifndef _SVX_HYZNITEM_HXX //autogen
+#include <svx/hyznitem.hxx>
+#endif
+
+#if SUPD>593
+#ifndef _MSOLEEXP_HXX
+#include <svx/msoleexp.hxx>
+#endif
+#endif
+
+#ifndef _OFA_FLTRCFG_HXX
+#include <offmgr/fltrcfg.hxx>
+#endif
+#ifndef _OFF_APP_HXX //autogen
+#include <offmgr/app.hxx>
+#endif
+
+#ifndef _SWTYPES_HXX
+#include <swtypes.hxx>
+#endif
+#ifndef _SWRECT_HXX
+#include <swrect.hxx>
+#endif
+#ifndef _TXATBASE_HXX
+#include <txatbase.hxx>
+#endif
+#ifndef _FMTCNTNT_HXX
+#include <fmtcntnt.hxx>
+#endif
+#ifndef _FMTPDSC_HXX
+#include <fmtpdsc.hxx>
+#endif
+#ifndef _DOC_HXX
+#include <doc.hxx>
+#endif
+#ifndef _DOCARY_HXX
+#include <docary.hxx>
+#endif
+#ifndef _PAM_HXX
+#include <pam.hxx>
+#endif
+#ifndef _NDTXT_HXX
+#include <ndtxt.hxx>
+#endif
+#ifndef _SHELLIO_HXX
+#include <shellio.hxx>
+#endif
+#ifndef _DOCSTAT_HXX
+#include <docstat.hxx>
+#endif
+#ifndef _PAGEDESC_HXX
+#include <pagedesc.hxx>
+#endif
+#ifndef _FLYPOS_HXX
+#include <flypos.hxx>
+#endif
+#ifndef _BOOKMRK_HXX
+#include <bookmrk.hxx>
+#endif
+#ifndef _SWTABLE_HXX
+#include <swtable.hxx>
+#endif
+#ifndef _WRTWW8_HXX
+#include <wrtww8.hxx>
+#endif
+#ifndef _WW8STRUC_HXX
+#include <ww8struc.hxx>
+#endif
+#ifndef _WRT_FN_HXX
+#include <wrt_fn.hxx>
+#endif
+#ifndef _FLTINI_HXX
+#include <fltini.hxx>
+#endif
+#ifndef _ERRHDL_HXX
+#include <errhdl.hxx>
+#endif
+#ifndef _SWMODULE_HXX
+#include <swmodule.hxx>
+#endif
+#ifndef _SECTION_HXX
+#include <section.hxx>
+#endif
+#include "poolfmt.hxx" // RES_POOLCOLL_STANDARD
+
+#ifndef _MDIEXP_HXX
+#include <mdiexp.hxx> // Progress
+#endif
+#ifndef _STATSTR_HRC
+#include <statstr.hrc> // ResId fuer Statusleiste
+#endif
+
+#ifndef SW_FMTLINE_HXX
+#include <fmtline.hxx>
+#endif
+
+
+class WW8_WrFkp
+{
+ BYTE* pFkp; // gesamter Fkp ( zuerst nur FCs und Sprms )
+ BYTE* pOfs; // Pointer auf Offset-Bereich, spaeter nach pFkp kopiert
+ ePLCFT ePlc;
+ short nStartGrp; // ab hier grpprls
+ short nOldStartGrp;
+ BYTE nItemSize;
+ BYTE nIMax; // Anzahl der Eintrags-Paare
+ BYTE nOldVarLen;
+ BOOL bCombined; // TRUE : Einfuegen verboten
+
+ BYTE SearchSameSprm( USHORT nVarLen, const BYTE* pSprms );
+public:
+ WW8_WrFkp( ePLCFT ePl, WW8_FC nStartFc, BOOL bWrtWW8 );
+ ~WW8_WrFkp();
+ BOOL Append( WW8_FC nEndFc, USHORT nVarLen = 0, const BYTE* pSprms = 0 );
+ BOOL Combine();
+ void Write( SvStream& rStrm, SwWW8WrGrf& rGrf );
+
+ BOOL IsEqualPos( WW8_FC nEndFc ) const
+ { return !bCombined && nIMax && nEndFc == ((INT32*)pFkp)[nIMax]; }
+ void MergeToNew( short& rVarLen, BYTE *& pNewSprms );
+ BOOL IsEmptySprm() const
+ { return !bCombined && nIMax && !nOldVarLen; }
+ void SetNewEnd( WW8_FC nEnd )
+ { ((INT32*)pFkp)[nIMax] = nEnd; }
+
+#ifdef __WW8_NEEDS_COPY
+ WW8_FC GetStartFc() const;
+ WW8_FC GetEndFc() const;
+#else
+ WW8_FC GetStartFc() const { return ((INT32*)pFkp)[0]; };
+ WW8_FC GetEndFc() const { return ((INT32*)pFkp)[nIMax]; };
+#endif // defined __WW8_NEEDS_COPY
+};
+
+
+// -------------------------------------------------------------------------
+// class WW8_WrPc sammelt alle Piece-Eintraege fuer ein Piece
+// -------------------------------------------------------------------------
+
+class WW8_WrPc
+{
+ WW8_CP nStartCp; // Start ZeichenPosition vom Text
+ WW8_FC nStartFc; // Start File Position vom Text
+ USHORT nStatus; // Absatzende im Piece ?
+
+public:
+ WW8_WrPc(WW8_FC nSFc, WW8_CP nSCp )
+ : nStartCp( nSCp ), nStartFc( nSFc ), nStatus( 0x0040 )
+ {}
+
+ void SetStatus() { nStatus = 0x0050; }
+ USHORT GetStatus() const { return nStatus; }
+ WW8_CP GetStartCp() const { return nStartCp; }
+ WW8_FC GetStartFc() const { return nStartFc; }
+};
+
+
+class WW8_WrtBookmarks
+{
+ SvULongs aSttCps, aEndCps; // Array of Start- and End CPs
+ SvStringsDtor aSwBkmkNms; // Array of Sw - Bookmarknames
+// SvStringsDtor aWWBkmkNms; // Array of WW - Bookmarknames
+
+ USHORT GetPos( const String& rNm );
+public:
+ WW8_WrtBookmarks();
+ ~WW8_WrtBookmarks();
+
+ void Append( WW8_CP nStartCp, const String& rNm );
+ void Write( SwWW8Writer& rWrt );
+
+// String GetWWBkmkName( const String& rName ) const;
+};
+
+class WW8_WrtRedlineAuthor
+{
+ SvStringsDtor aAuthors; // Array of Sw - Bookmarknames
+
+ USHORT GetPos( const String& rNm );
+public:
+ WW8_WrtRedlineAuthor() : aAuthors( 0, 4 ) {}
+
+ USHORT AddName( const String& rNm );
+ void Write( SwWW8Writer& rWrt );
+};
+
+
+#define ANZ_DEFAULT_STYLES 16
+
+// die Namen der StorageStreams
+#define sMainStream String::CreateFromAscii( \
+ RTL_CONSTASCII_STRINGPARAM( "WordDocument" ))
+#define sDataStream String::CreateFromAscii( \
+ RTL_CONSTASCII_STRINGPARAM( "Data" ))
+#define sTableStream String::CreateFromAscii( \
+ RTL_CONSTASCII_STRINGPARAM( "1Table" ))
+
+
+SV_IMPL_VARARR( WW8Bytes, BYTE )
+SV_IMPL_PTRARR( WW8_WrFkpPtrs, WW8_FkpPtr )
+
+typedef WW8_WrPc* WW8_WrPcPtr;
+SV_DECL_PTRARR_DEL( WW8_WrPcPtrs, WW8_WrPcPtr, 4, 4 )
+SV_IMPL_PTRARR( WW8_WrPcPtrs, WW8_WrPcPtr )
+
+static void WriteDop( SwWW8Writer& rWrt )
+{
+ WW8Dop& rDop = *rWrt.pDop;
+
+ // default TabStop schreiben
+ const SvxTabStopItem& rTabStop = (SvxTabStopItem& )rWrt.pDoc->
+ GetAttrPool().GetDefaultItem( RES_PARATR_TABSTOP );
+ rDop.dxaTab = (USHORT)rTabStop[0].GetTabPos();
+
+
+ // Werte aus der DocStatistik (werden aufjedenfall fuer die
+ // DocStat-Felder benoetigt!)
+ rDop.fWCFtnEdn = TRUE; // because they are included in StarWriter
+
+ const SwDocStat& rDStat = rWrt.pDoc->GetDocStat();
+ rDop.cWords = rDStat.nWord;
+ rDop.cCh = rDStat.nChar;
+ rDop.cPg = rDStat.nPage;
+ rDop.cParas = rDStat.nPara;
+ rDop.cLines = rDStat.nPara;
+
+// auch damit werden die DocStat-Felder in Kopf-/Fusszeilen nicht korrekt
+// berechnet.
+// ( we do not have this fields! )
+
+ // und noch fuer die Header und Footers
+ rDop.cWordsFtnEnd = rDStat.nWord;
+ rDop.cChFtnEdn = rDStat.nChar;
+ rDop.cPgFtnEdn = rDStat.nPage;
+ rDop.cParasFtnEdn = rDStat.nPara;
+ rDop.cLinesFtnEdn = rDStat.nPara;
+
+ rDop.Write( *rWrt.pTableStrm, *rWrt.pFib );
+}
+
+
+// HasItem ist fuer die Zusammenfassung der Doppel-Attribute
+// Underline / WordLineMode und Box / Shadow.
+// Es kann nur etwas gefunden werden, wenn diese Methode innerhalb
+// der aufgerufenen Methoden WW8_SwAttrIter::OutAttr() und
+// SwWW8Writer::Out_SfxItemSet() benutzt wird.
+const SfxPoolItem* SwWW8Writer::HasItem( USHORT nWhich ) const
+{
+ const SfxPoolItem* pItem;
+ if( pISet )
+ {
+ // if write a EditEngine text, then the WhichIds are greater as
+ // ourer own Ids. So the Id have to translate from ouer into the
+ // EditEngine Range
+ if( RES_WHICHHINT_END < *pISet->GetRanges() )
+ nWhich = TranslateToEditEngineId( nWhich );
+ if( SFX_ITEM_SET != pISet->GetItemState( nWhich, TRUE, &pItem ) )
+ pItem = 0;
+ }
+ else if( pChpIter )
+ pItem = pChpIter->HasTextItem( nWhich );
+ else
+ {
+ ASSERT( !this, "Wo ist mein ItemSet / pChpIter ?" );
+ pItem = 0;
+ }
+ return pItem;
+}
+
+const SfxPoolItem& SwWW8Writer::GetItem( USHORT nWhich ) const
+{
+ const SfxPoolItem* pItem;
+ if( pISet )
+ {
+ // if write a EditEngine text, then the WhichIds are greater as
+ // ourer own Ids. So the Id have to translate from ouer into the
+ // EditEngine Range
+ if( RES_WHICHHINT_END < *pISet->GetRanges() )
+ nWhich = TranslateToEditEngineId( nWhich );
+ pItem = &pISet->Get( nWhich, TRUE );
+ }
+ else if( pChpIter )
+ pItem = &pChpIter->GetItem( nWhich );
+ else
+ {
+ ASSERT( !this, "Wo ist mein ItemSet / pChpIter ?" );
+ pItem = 0;
+ }
+ return *pItem;
+}
+
+//------------------------------------------------------------------------------
+
+WW8_WrPlc1::WW8_WrPlc1( USHORT nStructSz )
+ : aPos( 16, 16 ), aDat( 16 * (int)nStructSz, 16 * (int)nStructSz ),
+ nStructSiz( nStructSz )
+{
+}
+
+void WW8_WrPlc1::Append( WW8_CP nCp, const void* pData )
+{
+ aPos.Insert( nCp, aPos.Count() );
+ aDat.Insert( (BYTE*)pData, nStructSiz, aDat.Count() );
+}
+
+void WW8_WrPlc1::Finish( ULONG nLastCp, ULONG nSttCp )
+{
+ if( aPos.Count() )
+ {
+ aPos.Insert( nLastCp, aPos.Count() );
+ if( nSttCp )
+ for( USHORT n = 0; n < aPos.Count(); ++n )
+ aPos[ n ] -= nSttCp;
+ }
+}
+
+
+void WW8_WrPlc1::Write( SvStream& rStrm )
+{
+ for( USHORT i = 0; i < aPos.Count(); ++i )
+ SwWW8Writer::WriteLong( rStrm, aPos[i] );
+ rStrm.Write( aDat.GetData(), aDat.Count() ); // Anz Eintraege
+}
+
+//------------------------------------------------------------------------------
+// Klasse WW8_WrPlcFld fuer Felder
+//------------------------------------------------------------------------------
+
+
+BOOL WW8_WrPlcFld::Write( SwWW8Writer& rWrt )
+{
+ if( WW8_WrPlc1::Count() <= 1 )
+ return FALSE;
+
+ long *pfc, *plc;
+ switch( nTxtTyp )
+ {
+ case TXT_MAINTEXT:
+ pfc = &rWrt.pFib->fcPlcffldMom;
+ plc = &rWrt.pFib->lcbPlcffldMom;
+ break;
+ case TXT_HDFT:
+ pfc = &rWrt.pFib->fcPlcffldHdr;
+ plc = &rWrt.pFib->lcbPlcffldHdr;
+ break;
+
+ case TXT_FTN:
+ pfc = &rWrt.pFib->fcPlcffldFtn;
+ plc = &rWrt.pFib->lcbPlcffldFtn;
+ break;
+
+ case TXT_EDN:
+ pfc = &rWrt.pFib->fcPlcffldEdn;
+ plc = &rWrt.pFib->lcbPlcffldEdn;
+ break;
+
+ case TXT_TXTBOX:
+ pfc = &rWrt.pFib->fcPlcffldTxbx;
+ plc = &rWrt.pFib->lcbPlcffldTxbx;
+ break;
+
+ case TXT_HFTXTBOX:
+ pfc = &rWrt.pFib->fcPlcffldHdrTxbx;
+ plc = &rWrt.pFib->lcbPlcffldHdrTxbx;
+ break;
+
+ default:
+ pfc = plc = 0;
+ break;
+ }
+
+ if( pfc && plc )
+ {
+ ULONG nFcStart = rWrt.pTableStrm->Tell();
+ WW8_WrPlc1::Write( *rWrt.pTableStrm );
+ *pfc = nFcStart;
+ *plc = rWrt.pTableStrm->Tell() - nFcStart;
+ }
+ return TRUE;
+}
+
+
+//--------------------------------------------------------------------------
+
+void SwWW8Writer::FillCount( SvStream& rStrm, ULONG nCount )
+{
+ static UINT32 __READONLY_DATA aNulls[16] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; // 64 Byte
+
+ while( nCount > 64 )
+ {
+ rStrm.Write( aNulls, 64 ); // in 64-Byte-Schritten
+ nCount -= 64;
+ }
+ rStrm.Write( aNulls, nCount ); // Rest ( 0 .. 64 Bytes ) schreiben
+}
+
+
+ULONG SwWW8Writer::FillUntil( SvStream& rStrm, ULONG nEndPos )
+{
+ ULONG nCurPos = rStrm.Tell();
+ if( !nEndPos ) // nEndPos == 0 -> next Page
+ nEndPos = nCurPos + 0x1ff & ~0x1ffUL;
+
+ if( nEndPos > nCurPos )
+ SwWW8Writer::FillCount( rStrm, nEndPos - nCurPos );
+#ifndef PRODUCT
+ else
+ ASSERT( nEndPos == nCurPos, "Falsches FillUntil()" );
+#endif
+ return rStrm.Tell();
+}
+
+
+//--------------------------------------------------------------------------
+/* */
+
+WW8_WrPlcPn::WW8_WrPlcPn( SwWW8Writer& rWr, ePLCFT ePl, WW8_FC nStartFc )
+ : rWrt( rWr ), ePlc( ePl ), nFkpStartPage( 0 )
+{
+ WW8_FkpPtr pF = new WW8_WrFkp( ePlc, nStartFc, rWrt.bWrtWW8 );
+ aFkps.Insert( pF, aFkps.Count() );
+}
+
+WW8_WrPlcPn::~WW8_WrPlcPn()
+{
+ aFkps.DeleteAndDestroy( 0, aFkps.Count() );
+}
+
+void WW8_WrPlcPn::AppendFkpEntry( WW8_FC nEndFc, short nVarLen,
+ const BYTE* pSprms )
+{
+ WW8_FkpPtr pF = aFkps.GetObject( aFkps.Count() - 1 );
+
+ // big sprm? build the sprmPHugePapx
+ BYTE* pNewSprms = (BYTE*)pSprms;
+ BYTE aHugePapx[ 8 ];
+ if( rWrt.bWrtWW8 && PAP == ePlc && 488 < nVarLen )
+ {
+ BYTE* p = aHugePapx;
+ *p++ = *pSprms++; // set style Id
+ *p++ = *pSprms++;
+ nVarLen -= 2;
+
+ long nDataPos = rWrt.pDataStrm->Tell();
+ SwWW8Writer::WriteShort( *rWrt.pDataStrm, nVarLen );
+ rWrt.pDataStrm->Write( pSprms, nVarLen );
+
+ Set_UInt16( p, 0x6646 ); // set SprmCode
+ Set_UInt32( p, nDataPos ); // set startpos (FC) in the datastream
+ nVarLen = p - aHugePapx;
+ pSprms = pNewSprms = aHugePapx;
+ }
+ // if append at the same FC-EndPos and there are sprms, then get the old
+ // sprms and erase it; they will append now with the new sprms
+ else if( nVarLen && pF->IsEqualPos( nEndFc ))
+ pF->MergeToNew( nVarLen, pNewSprms );
+ // has the prev EndFC an empty sprm and the current is empty too, then
+ // expand only the old EndFc to the new EndFc
+ else if( !nVarLen && pF->IsEmptySprm() )
+ {
+ pF->SetNewEnd( nEndFc );
+ return ;
+ }
+
+ BOOL bOk = pF->Append( nEndFc, nVarLen, pNewSprms );
+ if( !bOk )
+ {
+ pF->Combine();
+ pF = new WW8_WrFkp( ePlc, pF->GetEndFc(), rWrt.bWrtWW8 );// Anfang neuer Fkp
+ // == Ende alter Fkp
+ aFkps.Insert( pF, aFkps.Count() );
+ if( !pF->Append( nEndFc, nVarLen, pNewSprms ) )
+ {
+ ASSERT( !this, "Sprm liess sich nicht einfuegen" );
+ }
+ }
+ if( pNewSprms != pSprms )
+ delete pNewSprms;
+}
+
+void WW8_WrPlcPn::WriteFkps()
+{
+ nFkpStartPage = (USHORT) ( SwWW8Writer::FillUntil( rWrt.Strm() ) >> 9 );
+
+ for( USHORT i = 0; i < aFkps.Count(); i++ )
+ aFkps.GetObject( i )->Write( rWrt.Strm(), *rWrt.pGrf );
+
+ if( CHP == ePlc )
+ {
+ rWrt.pFib->pnChpFirst = nFkpStartPage;
+ rWrt.pFib->cpnBteChp = aFkps.Count();
+ }
+ else
+ {
+ rWrt.pFib->pnPapFirst = nFkpStartPage;
+ rWrt.pFib->cpnBtePap = aFkps.Count();
+ }
+}
+
+void WW8_WrPlcPn::WritePlc()
+{
+ ULONG nFcStart = rWrt.pTableStrm->Tell();
+ USHORT i;
+
+ for( i = 0; i < aFkps.Count(); i++ )
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm,
+ aFkps.GetObject( i )->GetStartFc() );
+
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm,
+ aFkps.GetObject( i - 1 )->GetEndFc() );
+
+ // fuer jedes FKP die Page ausgeben
+ if( rWrt.bWrtWW8) // fuer WW97 Long-Ausgabe
+ for ( i = 0; i < aFkps.Count(); i++)
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, i + nFkpStartPage );
+ else // fuer WW95 Short-Ausgabe
+ for ( i = 0; i < aFkps.Count(); i++)
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm, i + nFkpStartPage );
+
+ if( CHP == ePlc )
+ {
+ rWrt.pFib->fcPlcfbteChpx = nFcStart;
+ rWrt.pFib->lcbPlcfbteChpx = rWrt.pTableStrm->Tell() - nFcStart;
+ }
+ else
+ {
+ rWrt.pFib->fcPlcfbtePapx = nFcStart;
+ rWrt.pFib->lcbPlcfbtePapx = rWrt.pTableStrm->Tell() - nFcStart;
+ }
+}
+
+//--------------------------------------------------------------------------
+/* */
+
+WW8_WrFkp::WW8_WrFkp( ePLCFT ePl, WW8_FC nStartFc, BOOL bWrtWW8 )
+ : nItemSize( ( CHP == ePl ) ? 1 : ( bWrtWW8 ? 13 : 7 )),
+ nIMax( 0 ), ePlc( ePl ), bCombined( FALSE ), nStartGrp( 511 ),
+ nOldStartGrp( 511 ), nOldVarLen( 0 )
+{
+ pFkp = (BYTE*)new INT32[128]; // 512 Byte
+ pOfs = (BYTE*)new INT32[128]; // 512 Byte
+ memset( pFkp, 0, 4 * 128 );
+ memset( pOfs, 0, 4 * 128 );
+ ( (INT32*)pFkp )[0] = nStartFc; // 0. FC-Eintrag auf nStartFc
+}
+
+WW8_WrFkp::~WW8_WrFkp()
+{
+ delete( pFkp );
+ delete( pOfs );
+}
+
+BYTE WW8_WrFkp::SearchSameSprm( USHORT nVarLen, const BYTE* pSprms )
+{
+ if( 3 < nVarLen )
+ {
+ // if the sprms contained picture-references then never equal!
+ for( BYTE n = nVarLen - 1; 3 < n; --n )
+ if( pSprms[ n ] == GRF_MAGIC_3 &&
+ pSprms[ n-1 ] == GRF_MAGIC_2 &&
+ pSprms[ n-2 ] == GRF_MAGIC_1 )
+ return 0;
+ }
+
+ short i;
+ for( i = 0; i < nIMax; i++ )
+ {
+ BYTE nStart = pOfs[i * nItemSize];
+ if( nStart )
+ { // Hat Sprms
+ const BYTE* p = pFkp + ( (USHORT)nStart << 1 );
+ if( ( CHP == ePlc
+ ? (*p++ == nVarLen)
+ : (((USHORT)*p++ << 1 ) == (( nVarLen+1) & 0xfffe)) )
+ && !memcmp( p, pSprms, nVarLen ) )
+ return nStart; // gefunden
+ }
+ }
+ return 0; // nicht gefunden
+}
+
+BOOL WW8_WrFkp::Append( WW8_FC nEndFc, USHORT nVarLen, const BYTE* pSprms )
+{
+ ASSERT( !nVarLen || pSprms, "Item-Pointer fehlt" );
+ ASSERT( nVarLen < ( ( ePlc == PAP ) ? 497U : 502U ), "Sprms zu lang !" );
+
+ if( bCombined )
+ {
+ ASSERT( !this, "Fkp::Append: Fkp is already combined" );
+ return FALSE;
+ }
+ INT32 n = ((INT32*)pFkp)[nIMax]; // letzter Eintrag
+ if( nEndFc <= n )
+ {
+ ASSERT( nEndFc >= n, "+Fkp: FC rueckwaerts" );
+ ASSERT( !nVarLen || !pSprms || nEndFc != n,
+ "+Fkp: selber FC mehrfach benutzt" );
+ // selber FC ohne Sprm wird ohne zu mosern ignoriert.
+
+ return TRUE; // ignorieren, keinen neuen Fkp anlegen
+ }
+
+ BYTE nOldP = ( nVarLen ) ? SearchSameSprm( nVarLen, pSprms ) : 0;
+ // Kombinieren gleicher Eintraege
+ short nOffset, nPos = nStartGrp;
+ if( nVarLen && !nOldP )
+ {
+ nPos = PAP == ePlc
+ ? ( 13 == nItemSize // HACK: PAP und bWrtWW8 !!
+ ? (nStartGrp & 0xFFFE ) - nVarLen - 1
+ : (nStartGrp - (((nVarLen + 1) & 0xFFFE)+1)) & 0xFFFE )
+ : ((nStartGrp - nVarLen - 1) & 0xFFFE);
+ if( nPos < 0 )
+ return FALSE; // Passt absolut nicht
+ nOffset = nPos; // Offset merken (kann auch ungerade sein!)
+ nPos &= 0xFFFE; // Pos fuer Sprms ( gerade Pos )
+ }
+
+ if( (USHORT)nPos <= ( nIMax + 2U ) * 4U + ( nIMax + 1U ) * nItemSize )
+ // Passt hinter CPs und Offsets ?
+ return FALSE; // Nein
+
+ ((INT32*)pFkp)[nIMax + 1] = nEndFc; // FC eintragen
+
+ nOldVarLen = (BYTE)nVarLen;
+ if( nVarLen && !nOldP )
+ { // echt eintragen
+ nOldStartGrp = nStartGrp;
+
+ nStartGrp = nPos;
+ pOfs[nIMax * nItemSize] = (BYTE)( nStartGrp >> 1 );
+ // ( DatenAnfg >> 1 ) eintragen
+ BYTE nCnt = CHP == ePlc
+ ? ( nVarLen < 256 ) ? (BYTE) nVarLen : 255
+ : ( ( nVarLen + 1 ) >> 1 );
+
+ pFkp[ nOffset ] = nCnt; // DatenLaenge eintragen
+ memcpy( pFkp + nOffset + 1, pSprms, nVarLen ); // Sprms speichern
+ }
+ else
+ {
+ // nicht echt eintragen ( keine Sprms oder Wiederholung )
+ // DatenAnfg 0 ( keine Daten ) oder Wiederholung
+ pOfs[nIMax * nItemSize] = nOldP;
+ }
+ nIMax++;
+ return TRUE;
+}
+
+BOOL WW8_WrFkp::Combine()
+{
+ if( bCombined )
+ return FALSE;
+ if( nIMax )
+ memcpy( pFkp + ( nIMax + 1 ) * 4, pOfs, nIMax * nItemSize );
+ DELETEZ( pOfs );
+ ((BYTE*)pFkp)[511] = nIMax;
+ bCombined = TRUE;
+
+#if defined __BIGENDIAN // Hier werden nur die FCs gedreht, die
+ register USHORT i; // Sprms muessen an anderer Stelle gedreht
+ // werden
+ register UINT32* p;
+ for( i = 0, p = (UINT32*)pFkp; i <= nIMax; i++, p++ )
+ *p = SWAPLONG( *p );
+#endif // ifdef __BIGENDIAN
+
+ return TRUE;
+}
+
+void WW8_WrFkp::Write( SvStream& rStrm, SwWW8WrGrf& rGrf )
+{
+ Combine(); // Falls noch nicht Combined
+
+ register BYTE* p; // Suche Magic fuer nPicLocFc
+ BYTE* pEnd = pFkp + nStartGrp;
+ for( p = pFkp + 511 - 4; p >= pEnd; p-- )
+ {
+ if( *p != GRF_MAGIC_1 ) // Suche nach Signatur 0x12 0x34 0x56 0xXX
+ continue;
+ if( *(p+1) != GRF_MAGIC_2 )
+ continue;
+ if( *(p+2) != GRF_MAGIC_3 )
+ continue;
+
+ SVBT32 nPos; // Signatur gefunden
+ LongToSVBT32( rGrf.GetFPos(), nPos ); // FilePos der Grafik
+ memcpy( p, nPos, 4 ); // Patche FilePos ueber Signatur
+ }
+ rStrm.Write( pFkp, 512 );
+}
+
+void WW8_WrFkp::MergeToNew( short& rVarLen, BYTE *& rpNewSprms )
+{
+ BYTE nStart = pOfs[ (nIMax-1) * nItemSize ];
+ if( nStart )
+ { // Hat Sprms
+ BYTE* p = pFkp + ( (USHORT)nStart << 1 );
+
+ // old and new equal? Then copy only one into the new sprms
+ if( nOldVarLen == rVarLen && !memcmp( p+1, rpNewSprms, nOldVarLen ))
+ {
+ BYTE* pNew = new BYTE[ nOldVarLen ];
+ memcpy( pNew, p+1, nOldVarLen );
+ rpNewSprms = pNew;
+ }
+ else
+ {
+ BYTE* pNew = new BYTE[ nOldVarLen + rVarLen ];
+ memcpy( pNew, p+1, nOldVarLen );
+ memcpy( pNew + nOldVarLen, rpNewSprms, rVarLen );
+
+ rpNewSprms = pNew;
+ rVarLen += nOldVarLen;
+ }
+ --nIMax;
+ // if this sprms dont used from others, remove it
+ FASTBOOL bFnd = FALSE;
+ for( USHORT n = 0; n < nIMax; ++n )
+ if( nStart == pOfs[ n * nItemSize ] )
+ {
+ bFnd = TRUE;
+ break;
+ }
+ if( !bFnd )
+ {
+ nStartGrp = nOldStartGrp;
+ memset( p, 0, nOldVarLen+1 );
+ }
+ }
+}
+
+#ifdef __WW8_NEEDS_COPY
+
+WW8_FC WW8_WrFkp::GetStartFc() const
+{
+// wenn bCombined, dann ist das Array ab pFkp schon Bytemaessig auf LittleEndian
+// umgedreht, d.h. zum Herausholen der Anfangs- und Endpositionen muss
+// zurueckgedreht werden.
+ if( bCombined )
+ return SVBT32ToLong( pFkp ); // 0. Element
+ return ((INT32*)pFkp)[0];
+}
+
+WW8_FC WW8_WrFkp::GetEndFc() const
+{
+ if( bCombined )
+ return SVBT32ToLong( &(pFkp[nIMax*4]) ); // nIMax-tes SVBT32-Element
+ return ((INT32*)pFkp)[nIMax];
+}
+
+#endif // defined __WW8_NEEDS_COPY
+
+
+
+//--------------------------------------------------------------------------
+// Methoden fuer Piece-Table-Verwaltung
+//--------------------------------------------------------------------------
+
+WW8_WrPct::WW8_WrPct( WW8_FC nfcMin )
+ : nOldFc( nfcMin ),bIsUni( FALSE ), pPcts( new WW8_WrPcPtrs )
+{
+ AppendPc( nOldFc, bIsUni );
+}
+
+WW8_WrPct::~WW8_WrPct()
+{
+ delete pPcts;
+}
+
+// Piece fuellen und neues Piece erzeugen
+void WW8_WrPct::AppendPc( WW8_FC nStartFc, BOOL bIsUnicode )
+{
+ WW8_CP nStartCp = nStartFc - nOldFc; // Textbeginn abziehen
+ if ( !nStartCp )
+ {
+ if ( 0 != pPcts->Count() )
+ {
+ ASSERT( 1 == pPcts->Count(), "Leeres Piece !!");
+ pPcts->DeleteAndDestroy( pPcts->Count() - 1 , 1);
+ }
+ }
+
+ nOldFc = nStartFc; // StartFc als alten merken
+
+ if( bIsUni )
+ nStartCp >>= 1; // Bei Unicode Anzahl der Zeichen / 2
+
+
+ if ( !bIsUnicode )
+ {
+ nStartFc <<= 1; // Adresse * 2
+ nStartFc |= 0x40000000; // Vorletztes Bit setzen fuer !Unicode
+ }
+
+ if( pPcts->Count() )
+ nStartCp += pPcts->GetObject( pPcts->Count()- 1 )->GetStartCp();
+
+ WW8_WrPcPtr pPc = new WW8_WrPc( nStartFc, nStartCp );
+ pPcts->Insert( pPc, pPcts->Count() );
+
+ bIsUni = bIsUnicode;
+}
+
+
+void WW8_WrPct::WritePc( SwWW8Writer& rWrt )
+{
+ ULONG nPctStart;
+ ULONG nOldPos, nEndPos;
+ USHORT i;
+
+ nPctStart = rWrt.pTableStrm->Tell(); // Beginn Piece-Table
+ *rWrt.pTableStrm << ( char )0x02; // Statusbyte PCT
+ nOldPos = nPctStart + 1; // Position merken
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 ); // Laenge folgt
+ for( i = 0; i < pPcts->Count(); ++i ) // Bereiche
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm,
+ pPcts->GetObject( i )->GetStartCp() );
+
+
+ // die letzte Pos noch errechnen
+ ULONG nStartCp = rWrt.pFib->fcMac - nOldFc;
+ if( bIsUni )
+ nStartCp >>= 1; // Bei Unicode Anzahl der Zeichen / 2
+ nStartCp += pPcts->GetObject( i-1 )->GetStartCp();
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, nStartCp );
+
+ // Pieceverweise
+ for ( i = 0; i < pPcts->Count(); ++i )
+ {
+ WW8_WrPcPtr pPc = pPcts->GetObject( i );
+
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm, pPc->GetStatus());
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, pPc->GetStartFc());
+ SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0); // PRM=0
+ }
+
+ // Eintraege im FIB
+ rWrt.pFib->fcClx = nPctStart;
+ nEndPos = rWrt.pTableStrm->Tell();
+ rWrt.pFib->lcbClx = nEndPos - nPctStart;
+
+ // und noch die Laenge eintragen
+ SwWW8Writer::WriteLong( *rWrt.pTableStrm, nOldPos,
+ nEndPos - nPctStart-5 );
+
+}
+
+void WW8_WrPct::SetParaBreak()
+{
+ ASSERT( pPcts->Count(),"SetParaBreak : aPcts.Count = 0" );
+ pPcts->GetObject( pPcts->Count() - 1)->SetStatus();
+}
+
+ULONG WW8_WrPct::Fc2Cp( ULONG nFc ) const
+{
+ ASSERT( nFc >= (ULONG)nOldFc, "FilePos liegt vorm letzten Piece" );
+ ASSERT( pPcts->Count(), "Fc2Cp noch kein Piece vorhanden" );
+
+ nFc -= nOldFc;
+ if( bIsUni )
+ nFc /= 2;
+ return nFc + pPcts->GetObject( pPcts->Count() - 1 )->GetStartCp();
+}
+
+//--------------------------------------------------------------------------
+/* */
+
+WW8_WrtBookmarks::WW8_WrtBookmarks()
+ : aSttCps( 0, 16 ), aEndCps( 0, 16 ),
+ aSwBkmkNms( 0, 16 )
+// JP 24.06.99: not used at time ,aWWBkmkNms( 0, 16 ),
+{
+}
+
+WW8_WrtBookmarks::~WW8_WrtBookmarks()
+{
+}
+
+void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const String& rNm )
+{
+ USHORT nPos = GetPos( rNm );
+ if( USHRT_MAX == nPos )
+ {
+ // new -> insert as start position
+ nPos = aSttCps.Count();
+ // sort by startposition
+ // theory: write continuous -> then the new position is at end
+ while( nPos && aSttCps[ nPos - 1 ] > ULONG( nStartCp ))
+ --nPos;
+
+ aSttCps.Insert( nStartCp, nPos );
+ aEndCps.Insert( nStartCp, nPos );
+ String* p = new String( rNm );
+ aSwBkmkNms.Insert( p, nPos );
+// JP 24.06.99: not used at time
+// p = new String( GetWWBkmkName(rNm ));
+// aWWBkmkNms.Insert( p, nPos );
+ }
+ else
+ {
+ // old -> its the end position
+ ASSERT( aEndCps[ nPos ] == aSttCps[ nPos ], "end position is valid" );
+ aEndCps.Replace( nStartCp, nPos );
+ }
+}
+
+
+void WW8_WrtBookmarks::Write( SwWW8Writer& rWrt )
+{
+ USHORT nCount = aSttCps.Count(), i;
+ if( nCount )
+ {
+ SvULongs aEndSortTab( 255 < nCount ? 255 : nCount, 4 );
+ // sort then endpositions
+ for( i = 0; i < nCount; ++i )
+ {
+ ULONG nCP = aEndCps[ i ];
+ USHORT nPos = i;
+ while( nPos && aEndSortTab[ nPos - 1 ] > nCP )
+ --nPos;
+ aEndSortTab.Insert( nCP, nPos );
+ }
+
+ // we have some bookmarks found in the document -> write them
+ // first the Bookmark Name Stringtable
+ rWrt.WriteAsStringTable( (SvStrings&)aSwBkmkNms,
+ rWrt.pFib->fcSttbfbkmk,
+ rWrt.pFib->lcbSttbfbkmk );
+
+ // second the Bookmark start positions as pcf of longs
+ SvStream& rStrm = rWrt.bWrtWW8 ? *rWrt.pTableStrm : rWrt.Strm();
+ rWrt.pFib->fcPlcfbkf = rStrm.Tell();
+ for( i = 0; i < nCount; ++i )
+ SwWW8Writer::WriteLong( rStrm, aSttCps[ i ] );
+ SwWW8Writer::WriteLong( rStrm, rWrt.pFib->ccpText );
+ for( i = 0; i < nCount; ++i )
+ {
+ ULONG nEndCP = aEndCps[ i ];
+ USHORT nPos = i;
+ if( aEndSortTab[ nPos ] > nEndCP )
+ {
+ while( aEndSortTab[ --nPos ] != nEndCP )
+ ;
+ }
+ else if( aEndSortTab[ nPos ] < nEndCP )
+ while( aEndSortTab[ ++nPos ] != nEndCP )
+ ;
+
+ SwWW8Writer::WriteLong( rStrm, nPos );
+ }
+ rWrt.pFib->lcbPlcfbkf = rStrm.Tell() - rWrt.pFib->fcPlcfbkf;
+
+ // third the Bookmark end positions
+ rWrt.pFib->fcPlcfbkl = rStrm.Tell();
+ for( i = 0; i < nCount; ++i )
+ SwWW8Writer::WriteLong( rStrm, aEndSortTab[ i ] );
+ SwWW8Writer::WriteLong( rStrm, rWrt.pFib->ccpText );
+ rWrt.pFib->lcbPlcfbkl = rStrm.Tell() - rWrt.pFib->fcPlcfbkl;
+ }
+}
+
+// JP 24.06.99: not used at time
+/*String WW8_WrtBookmarks::GetWWBkmkName( const String& rName ) const
+{
+ // replace all characters that will WinWord not understand
+ return rName;
+}
+*/
+
+USHORT WW8_WrtBookmarks::GetPos( const String& rNm )
+{
+ USHORT nRet = USHRT_MAX, n;
+ for( n = 0; n < aSttCps.Count(); ++n )
+ if( rNm == *aSwBkmkNms.GetObject( n ))
+ {
+ nRet = n;
+ break;
+ }
+ return nRet;
+}
+
+void SwWW8Writer::AppendBookmarks( const SwTxtNode& rNd,
+ xub_StrLen nAktPos, xub_StrLen nLen )
+{
+ SvPtrarr aArr( 8, 8 );
+ USHORT nCntnt;
+ xub_StrLen nAktEnd = nAktPos + nLen;
+ if( GetBookmarks( rNd, nAktPos, nAktEnd, aArr ))
+ {
+ ULONG nNd = rNd.GetIndex(), nSttCP = Fc2Cp( Strm().Tell() );
+ for( USHORT n = 0; n < aArr.Count(); ++n )
+ {
+ const SwBookmark& rBkmk = *(SwBookmark*)aArr[ n ];
+ const SwPosition* pPos = &rBkmk.GetPos(),
+ * pOPos = rBkmk.GetOtherPos();
+ if( pOPos && pOPos->nNode == pPos->nNode &&
+ pOPos->nContent < pPos->nContent )
+ {
+ pOPos = pPos;
+ pPos = rBkmk.GetOtherPos();
+ }
+
+ if( !pOPos || ( nNd == pPos->nNode.GetIndex() &&
+ ( nCntnt = pPos->nContent.GetIndex() ) >= nAktPos &&
+ nCntnt < nAktEnd ) )
+ {
+ ULONG nCp = nSttCP + pPos->nContent.GetIndex() - nAktPos;
+ pBkmks->Append( nCp, rBkmk.GetName() );
+ }
+ if( pOPos && nNd == pOPos->nNode.GetIndex() &&
+ ( nCntnt = pOPos->nContent.GetIndex() ) >= nAktPos &&
+ nCntnt < nAktEnd )
+ {
+ ULONG nCp = nSttCP + pOPos->nContent.GetIndex() - nAktPos;
+ pBkmks->Append( nCp, rBkmk.GetName() );
+ }
+ }
+ }
+}
+
+void SwWW8Writer::AppendBookmark( const String& rName, USHORT nOffset )
+{
+ ULONG nSttCP = Fc2Cp( Strm().Tell() ) + nOffset;
+ pBkmks->Append( nSttCP, rName );
+}
+
+
+//--------------------------------------------------------------------------
+/* */
+
+USHORT WW8_WrtRedlineAuthor::AddName( const String& rNm )
+{
+ for( USHORT n = 0, nCnt = aAuthors.Count(); n < nCnt; ++n )
+ if( *aAuthors[ n ] == rNm )
+ return n;
+
+ String* pNew = new String( rNm );
+ aAuthors.Insert( pNew, n );
+ return n;
+}
+
+void WW8_WrtRedlineAuthor::Write( SwWW8Writer& rWrt )
+{
+ rWrt.WriteAsStringTable( (SvStrings&)aAuthors,
+ rWrt.pFib->fcSttbfRMark,
+ rWrt.pFib->lcbSttbfRMark,
+ rWrt.bWrtWW8 ? 0 : 2 );
+}
+
+USHORT SwWW8Writer::AddRedlineAuthor( USHORT nId )
+{
+ if( !pRedlAuthors )
+ {
+ pRedlAuthors = new WW8_WrtRedlineAuthor;
+ pRedlAuthors->AddName( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "Unknown" )));
+ }
+ return pRedlAuthors->AddName( SW_MOD()->GetRedlineAuthor( nId ) );
+}
+
+//--------------------------------------------------------------------------
+/* */
+
+void SwWW8Writer::WriteAsStringTable( const SvStrings& rStrings,
+ INT32& rfcSttbf, INT32& rlcbSttbf,
+ USHORT nExtraLen )
+{
+ USHORT n, nCount = rStrings.Count();
+ if( nCount )
+ {
+ // we have some Redlines found in the document -> the
+ // Author Name Stringtable
+ SvStream& rStrm = bWrtWW8 ? *pTableStrm : Strm();
+ rfcSttbf = rStrm.Tell();
+ if( bWrtWW8 )
+ {
+ SwWW8Writer::WriteShort( rStrm, -1 );
+ SwWW8Writer::WriteLong( rStrm, nCount );
+ for( n = 0; n < nCount; ++n )
+ {
+ const String& rNm = *rStrings[ n ];
+ SwWW8Writer::WriteShort( rStrm, rNm.Len() );
+ SwWW8Writer::WriteString16( rStrm, rNm, FALSE );
+ if( nExtraLen )
+ SwWW8Writer::FillCount( rStrm, nExtraLen );
+ }
+ }
+ else
+ {
+ SwWW8Writer::WriteShort( rStrm, 0 );
+ for( n = 0; n < nCount; ++n )
+ {
+ const String aNm( rStrings[ n ]->Copy(0, 255 ));
+ rStrm << (BYTE)aNm.Len();
+ SwWW8Writer::WriteString8( rStrm, aNm, FALSE,
+ RTL_TEXTENCODING_MS_1252 );
+ if( nExtraLen )
+ SwWW8Writer::FillCount( rStrm, nExtraLen );
+ }
+ }
+ rlcbSttbf = rStrm.Tell() - rfcSttbf;
+ if( !bWrtWW8 )
+ SwWW8Writer::WriteShort( rStrm, rfcSttbf, (USHORT)rlcbSttbf );
+ }
+}
+
+// WriteShort() traegt an FilePos nPos den Wert nVal ein und seekt auf die
+// alte FilePos zurueck. Benutzt zum Nachtragen von Laengen.
+void SwWW8Writer::WriteShort( SvStream& rStrm, ULONG nPos, INT16 nVal )
+{
+ ULONG nOldPos = rStrm.Tell(); // Pos merken
+ rStrm.Seek( nPos );
+ SwWW8Writer::WriteShort( rStrm, nVal );
+ rStrm.Seek( nOldPos );
+}
+
+void SwWW8Writer::WriteLong( SvStream& rStrm, ULONG nPos, INT32 nVal )
+{
+ ULONG nOldPos = rStrm.Tell(); // Pos merken
+ rStrm.Seek( nPos );
+ SwWW8Writer::WriteLong( rStrm, nVal );
+ rStrm.Seek( nOldPos );
+}
+
+#ifdef __WW8_NEEDS_COPY
+
+void SwWW8Writer::InsUInt16( WW8Bytes& rO, UINT16 n )
+{
+ SVBT16 nL;
+ ShortToSVBT16( n, nL );
+ rO.Insert( nL, 2, rO.Count() );
+}
+void SwWW8Writer::InsUInt32( WW8Bytes& rO, UINT32 n )
+{
+ SVBT32 nL;
+ LongToSVBT32( n, nL );
+ rO.Insert( nL, 4, rO.Count() );
+}
+
+#else
+
+void SwWW8Writer::InsUInt16( WW8Bytes& rO, UINT16 n )
+{
+ rO.Insert( (BYTE*)&n, 2, rO.Count() );
+}
+void SwWW8Writer::InsUInt32( WW8Bytes& rO, UINT32 n )
+{
+ rO.Insert( (BYTE*)&n, 4, rO.Count() );
+}
+
+#endif // defined __WW8_NEEDS_COPY
+
+void SwWW8Writer::InsAsString16( WW8Bytes& rO, const String& rStr )
+{
+ for( const sal_Unicode* pStr = rStr.GetBuffer(); *pStr; ++pStr )
+ SwWW8Writer::InsUInt16( rO, *pStr );
+}
+
+void SwWW8Writer::InsAsString8( WW8Bytes& rO, const String& rStr,
+ rtl_TextEncoding eCodeSet )
+{
+ ByteString sTmp( rStr, eCodeSet );
+ rO.Insert( (BYTE*)sTmp.GetBuffer(), sTmp.Len(), rO.Count() );
+}
+
+void SwWW8Writer::WriteString16( SvStream& rStrm, const String& rStr,
+ BOOL bAddZero )
+{
+ WW8Bytes aBytes;
+ SwWW8Writer::InsAsString16( aBytes, rStr );
+ if( bAddZero )
+ SwWW8Writer::InsUInt16( aBytes, 0 );
+ rStrm.Write( aBytes.GetData(), aBytes.Count() );
+}
+
+void SwWW8Writer::WriteString8( SvStream& rStrm, const String& rStr,
+ BOOL bAddZero, rtl_TextEncoding eCodeSet )
+{
+ WW8Bytes aBytes;
+ SwWW8Writer::InsAsString8( aBytes, rStr, eCodeSet );
+ if( bAddZero )
+ aBytes.Insert( (BYTE)0, aBytes.Count() );
+ rStrm.Write( aBytes.GetData(), aBytes.Count() );
+}
+
+void SwWW8Writer::WriteStringAsPara( const String& rTxt, USHORT nStyleId )
+{
+ if( rTxt.Len() )
+ OutSwString( rTxt, 0, rTxt.Len(), IsUnicode(), RTL_TEXTENCODING_MS_1252 );
+ WriteCR(); // CR danach
+
+ WW8Bytes aArr( 10, 10 );
+ SwWW8Writer::InsUInt16( aArr, nStyleId );
+ if( bOutTable )
+ { // Tab-Attr
+ // sprmPFInTable
+ if( bWrtWW8 )
+ SwWW8Writer::InsUInt16( aArr, 0x2416 );
+ else
+ aArr.Insert( 24, aArr.Count() );
+ aArr.Insert( 1, aArr.Count() );
+ }
+
+ ULONG nPos = Strm().Tell();
+ pPapPlc->AppendFkpEntry( nPos, aArr.Count(), aArr.GetData() );
+ pChpPlc->AppendFkpEntry( nPos );
+}
+
+void SwWW8Writer::WriteSpecialText( ULONG nStart, ULONG nEnd, BYTE nTTyp )
+{
+ BYTE nOldTyp = nTxtTyp;
+ nTxtTyp = nTTyp;
+ SwPaM* pOldPam = pCurPam; //!! Einfaches Umsetzen des PaM ohne
+ SwPaM* pOldEnd = pOrigPam; // Wiederherstellen muesste es auch tun
+ BOOL bOldPageDescs = bOutPageDescs;
+ bOutPageDescs = FALSE;
+ // bOutKF wird in WriteKF1 gemerkt / gesetzt
+ pCurPam = NewSwPaM( *pDoc, nStart, nEnd );
+
+ // Tabelle in Sonderbereichen erkennen
+ if( (nStart != pCurPam->GetMark()->nNode.GetIndex())
+ && pDoc->GetNodes()[ nStart ]->IsTableNode() )
+ pCurPam->GetMark()->nNode = nStart;
+
+ pOrigPam = pCurPam;
+ pCurPam->Exchange();
+
+ WriteText();
+
+ delete pCurPam; // Pam wieder loeschen
+ bOutPageDescs = bOldPageDescs;
+ pCurPam = pOldPam;
+ pOrigPam = pOldEnd;
+ nTxtTyp = nOldTyp;
+}
+
+void SwWW8Writer::OutSwString( const String& rStr, xub_StrLen nStt,
+ xub_StrLen nLen, BOOL bUnicode,
+ rtl_TextEncoding eChrSet )
+
+{
+ if( nLen )
+ {
+ if ( bUnicode != pPiece->IsUnicode() )
+ pPiece->AppendPc ( Strm().Tell(), bUnicode );
+
+ if( nStt || nLen != rStr.Len() )
+ {
+ String sOut( rStr.Copy( nStt, nLen ) );
+ if( bUnicode )
+ SwWW8Writer::WriteString16( Strm(), sOut, FALSE );
+ else
+ SwWW8Writer::WriteString8( Strm(), sOut, FALSE, eChrSet );
+ }
+ else if( bUnicode )
+ SwWW8Writer::WriteString16( Strm(), rStr, FALSE );
+ else
+ SwWW8Writer::WriteString8( Strm(), rStr, FALSE, eChrSet );
+ }
+}
+
+void SwWW8Writer::WriteCR()
+{
+ WriteChar( '\015' );
+ pPiece->SetParaBreak();
+}
+
+void SwWW8Writer::WriteChar( sal_Unicode c )
+{
+ if( pPiece->IsUnicode() )
+ Strm() << c;
+ else
+ Strm() << (BYTE)c;
+}
+
+long SwWW8Writer::GetDTTM( const DateTime& rDT )
+{
+/*
+mint short :6 0000003F minutes (0-59)
+hr short :5 000007C0 hours (0-23)
+dom short :5 0000F800 days of month (1-31)
+mon short :4 000F0000 months (1-12)
+yr short :9 1FF00000 years (1900-2411)-1900
+wdy short :3 E0000000 weekday(Sunday=0
+ Monday=1
+( wdy can be ignored ) Tuesday=2
+ Wednesday=3
+ Thursday=4
+ Friday=5
+ Saturday=6)
+*/
+
+ long nDT = ( rDT.GetDayOfWeek() + 1 ) % 7;
+ nDT <<= 9;
+ nDT += ( rDT.GetYear() - 1900 ) & 0x1ff;
+ nDT <<= 4;
+ nDT += rDT.GetMonth() & 0xf;
+ nDT <<= 5;
+ nDT += rDT.GetDay() & 0x1f;
+ nDT <<= 5;
+ nDT += rDT.GetHour() & 0x1f;
+ nDT <<= 6;
+ nDT += rDT.GetMin() & 0x3f;
+ return nDT;
+}
+
+/* */
+//---------------------------------------------------------------------------
+// Hilfsroutinen fuer Flys
+//---------------------------------------------------------------------------
+// Struktur speichert die aktuellen Daten des Writers zwischen, um
+// einen anderen Dokument-Teil auszugeben, wie z.B. Header/Footer
+WW8SaveData::WW8SaveData( SwWW8Writer& rWriter, ULONG nStt, ULONG nEnd )
+ : rWrt( rWriter ),
+ pOldPam( rWrt.pCurPam ), pOldEnd( rWrt.GetEndPaM() ),
+ pOldFlyFmt( rWrt.pFlyFmt ), pOldPageDesc( rWrt.pAktPageDesc )
+
+{
+ pOldFlyOffset = rWrt.pFlyOffset;
+ if( rWrt.pO->Count() )
+ {
+ pOOld = rWrt.pO;
+ rWrt.pO = new WW8Bytes( 128, 128 );
+ }
+ else
+ pOOld = 0;
+ bOldWriteAll = rWrt.bWriteAll;
+ bOldOutTable = rWrt.bOutTable;
+ bOldIsInTable= rWrt.bIsInTable;
+ bOldFlyFrmAttrs = rWrt.bOutFlyFrmAttrs;
+ bOldStartTOX = rWrt.bStartTOX;
+ bOldInWriteTOX = rWrt.bInWriteTOX;
+
+ rWrt.pCurPam = rWrt.NewSwPaM( *rWrt.pDoc, nStt, nEnd );
+
+ // Tabelle in Sonderbereichen erkennen
+ if( nStt != rWrt.pCurPam->GetMark()->nNode.GetIndex() &&
+ rWrt.pDoc->GetNodes()[ nStt ]->IsTableNode() )
+ rWrt.pCurPam->GetMark()->nNode = nStt;
+
+ rWrt.SetEndPaM( rWrt.pCurPam );
+ rWrt.pCurPam->Exchange( );
+ rWrt.bWriteAll = TRUE;
+ rWrt.bOutTable = FALSE;
+ // Vorsicht: rWrt.bIsInTable darf hier NICHT veraendert werden!
+ rWrt.bOutFlyFrmAttrs = FALSE;
+// rWrt.pAttrSet = 0;
+ rWrt.bStartTOX = FALSE;
+ rWrt.bInWriteTOX = FALSE;
+}
+
+
+WW8SaveData::~WW8SaveData()
+{
+ delete rWrt.pCurPam; // Pam wieder loeschen
+
+ rWrt.pCurPam = pOldPam;
+ rWrt.SetEndPaM( pOldEnd );
+ rWrt.bWriteAll = bOldWriteAll;
+ rWrt.bOutTable = bOldOutTable;
+ rWrt.bIsInTable= bOldIsInTable;
+ rWrt.bOutFlyFrmAttrs = bOldFlyFrmAttrs;
+ rWrt.bStartTOX = bOldStartTOX;
+ rWrt.bInWriteTOX = bOldInWriteTOX;
+ rWrt.pFlyFmt = pOldFlyFmt;
+ rWrt.pAktPageDesc = pOldPageDesc;
+// rWrt.pAttrSet = pOldAttrSet;
+ ASSERT( !rWrt.pO->Count(), " pO ist am Ende von WW8SaveData nicht leer" );
+ if( pOOld )
+ {
+ delete rWrt.pO;
+ rWrt.pO = pOOld;
+ }
+ rWrt.pFlyOffset = pOldFlyOffset;
+}
+
+
+void SwWW8Writer::WriteText()
+{
+ while( pCurPam->GetPoint()->nNode < pCurPam->GetMark()->nNode ||
+ (pCurPam->GetPoint()->nNode == pCurPam->GetMark()->nNode &&
+ pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex()) )
+ {
+ SwNode * pNd = pCurPam->GetNode();
+
+ if( pNd->IsTxtNode() ) // blitzschnelle Methode
+ {
+ const SwTxtNode* pTxtNode = pNd->GetTxtNode();
+ if( pTxtNode->GetpSwAttrSet() )
+ Out_SfxBreakItems( *pTxtNode->GetpSwAttrSet(), *pTxtNode );
+ if( !bIsInTable )
+ OutWW8FlyFrmsInCntnt( *pTxtNode ); // als Zeichen gebundene Flys
+ }
+
+ if( pNd->IsCntntNode() )
+ {
+ SwCntntNode* pCNd = (SwCntntNode*)pNd;
+
+ // erfrage den aktuellen PageDescriptor.
+ if( !bInWriteEscher )
+ OutFlyFrms( *pCNd );
+
+ const SwPageDesc* pTemp = pCNd->GetSwAttrSet().GetPageDesc().GetPageDesc();
+ if( pTemp )
+ pAktPageDesc = pTemp;
+
+ pCurPam->GetPoint()->nContent.Assign( pCNd, 0 );
+ Out( aWW8NodeFnTab, *pCNd, *this );
+ }
+ else if( pNd->IsTableNode() && !bIsInTable )
+ OutWW8_SwTblNode( *this, *(SwTableNode*)pNd );
+ else if( pNd->IsSectionNode() && TXT_MAINTEXT == nTxtTyp )
+ OutWW8_SwSectionNode( *this, *pNd->GetSectionNode() );
+ else if( TXT_MAINTEXT == nTxtTyp && pNd->IsEndNode() &&
+ pNd->FindStartNode()->IsSectionNode() )
+ {
+ const SwSection& rSect = pNd->FindStartNode()->GetSectionNode()
+ ->GetSection();
+ if( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() )
+ bStartTOX = FALSE;
+
+ SwNodeIndex aIdx( *pNd, 1 );
+ if( aIdx.GetNode().IsEndNode()
+ && aIdx.GetNode().FindStartNode()->IsSectionNode() )
+ ;
+ else
+ if( aIdx.GetNode().IsSectionNode() )
+ ;
+ else
+ {
+ ReplaceCr( (char)0xc ); // Indikator fuer Page/Section-Break
+
+ const SwSectionFmt* pParentFmt = rSect.GetFmt()->GetParent();
+ if( !pParentFmt )
+ pParentFmt = (SwSectionFmt*)0xFFFFFFFF;
+
+ ULONG nRstLnNum;
+ if( aIdx.GetNode().IsCntntNode() )
+ nRstLnNum = ((SwCntntNode&)aIdx.GetNode()).GetSwAttrSet().
+ GetLineNumber().GetStartValue();
+ else
+ nRstLnNum = 0;
+
+ pSepx->AppendSep( Fc2Cp( Strm().Tell() ),
+ pAktPageDesc, pParentFmt, nRstLnNum );
+ }
+ }
+ else if( pNd == &pNd->GetNodes().GetEndOfContent() )
+ break;
+
+ ULONG nPos = pCurPam->GetPoint()->nNode++; // Bewegen
+ ::SetProgressState( nPos, pCurPam->GetDoc()->GetDocShell() ); // Wie weit ?
+ }
+}
+
+void SwWW8Writer::WriteMainText()
+{
+ pFib->fcMin = Strm().Tell();
+
+ do {
+ WriteText();
+ } while( FALSE ); //!! Temporaer nur 1 Bereich
+// } while( CopyNextPam( &pCurPam ) ); // bis alle Pam bearbeitet
+
+ if( 0 == Strm().Tell() - pFib->fcMin ) // kein Text ?
+ WriteCR(); // dann CR ans Ende ( sonst mault WW )
+
+ pFib->ccpText = Fc2Cp( Strm().Tell() );
+ pFldMain->Finish( pFib->ccpText, 0 );
+
+ // ccpText beinhaltet Ftn- und KF-Texte
+ // deshalb wird pFib->ccpText evtl. noch geupdated
+ // save the StyleId of the last paragraph. Because WW97 take the style
+ // from the last CR, that will be write after footer/Header/fontnotes/
+ // annotation usw.
+ const SwTxtNode* pLastNd = pCurPam->GetMark()->nNode.GetNode().GetTxtNode();
+ if( pLastNd )
+ nLastFmtId = GetId( (SwTxtFmtColl&)pLastNd->GetAnyFmtColl() );
+}
+
+void SwWW8Writer::WriteFkpPlcUsw()
+{
+ if( !bWrtWW8 )
+ {
+ static BYTE __READONLY_DATA aSpec[2] = { 117, 1 };
+
+ pChpPlc->AppendFkpEntry( Strm().Tell() ); // Sepx mit fSpecial
+ pSepx->WriteSepx( Strm() ); // Slcx.Sepx
+ pGrf->Write(); // Grafiken
+ pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aSpec ), aSpec );
+
+ pChpPlc->WriteFkps(); // Fkp.Chpx
+ pPapPlc->WriteFkps(); // Fkp.Papx
+ pStyles->OutStyleTab(); // Styles
+ pFtn->WritePlc( *this ); // Footnote-Ref & Text Plc
+ pEdn->WritePlc( *this ); // Endnote-Ref & Text Plc
+ pAtn->WritePlc( *this ); // Annotation-Ref & Text Plc
+ pSepx->WritePlcSed( *this ); // Slcx.PlcSed
+ pSepx->WritePlcHdd( *this ); // Slcx.PlcHdd
+ pChpPlc->WritePlc(); // Plcx.Chpx
+ pPapPlc->WritePlc(); // Plcx.Papx
+ OutFontTab( *pFib ); // FFNs
+ if( pRedlAuthors )
+ pRedlAuthors->Write( *this ); // sttbfRMark (RedlineAuthors)
+ pFldMain->Write( *this ); // Fields ( Main Text )
+ pFldHdFt->Write( *this ); // Fields ( Header/Footer )
+ pFldFtn->Write( *this ); // Fields ( FootNotes )
+ pFldEdn->Write( *this ); // Fields ( EndNotes )
+ pBkmks->Write( *this ); // Bookmarks - sttbfBkmk/
+ // plcfBkmkf/plcfBkmkl
+ WriteDop( *this ); // Document-Properties
+
+ }
+ else
+ {
+ // Grafiken in den Data-Tream
+//??? static BYTE __READONLY_DATA aSpec[] = { 0x55,0x08,0x01 };
+//??? pChpPlc->AppendFkpEntry( pDataStrm->Tell() ); // Sepx mit fSpecial
+
+ pGrf->Write(); // Grafiken
+//??? pChpPlc->AppendFkpEntry( pDataStrm->Tell(), sizeof( aSpec ), aSpec );
+
+ // Ausgabe in WordDocument-Stream
+ pChpPlc->WriteFkps(); // Fkp.Chpx
+ pPapPlc->WriteFkps(); // Fkp.Papx
+ pSepx->WriteSepx( Strm() ); // Sepx
+
+ // Ausagbe in Table-Stream
+ pStyles->OutStyleTab(); // fuer WW8 StyleTab
+ pFtn->WritePlc( *this ); // Footnote-Ref & Text Plc
+ pEdn->WritePlc( *this ); // Endnote-Ref & Text Plc
+ pTxtBxs->WritePlc( *this ); // Textbox Text Plc
+ pHFTxtBxs->WritePlc( *this ); // Head/Foot-Textbox Text Plc
+ pAtn->WritePlc( *this ); // Annotation-Ref & Text Plc
+
+ pSepx->WritePlcSed( *this ); // Slcx.PlcSed
+ pSepx->WritePlcHdd( *this ); // Slcx.PlcHdd
+
+ pChpPlc->WritePlc(); // Plcx.Chpx
+ pPapPlc->WritePlc(); // Plcx.Papx
+
+ if( pRedlAuthors )
+ pRedlAuthors->Write( *this ); // sttbfRMark (RedlineAuthors)
+ pFldMain->Write( *this ); // Fields ( Main Text )
+ pFldHdFt->Write( *this ); // Fields ( Header/Footer )
+ pFldFtn->Write( *this ); // Fields ( FootNotes )
+ pFldEdn->Write( *this ); // Fields ( EndNotes )
+ pFldTxtBxs->Write( *this ); // Fields ( Textboxes )
+ pFldHFTxtBxs->Write( *this ); // Fields ( Head/Foot-Textboxes )
+
+ // dggInfo - escher stream
+ WriteEscher();
+
+ pSdrObjs->WritePlc( *this );
+ pHFSdrObjs->WritePlc( *this );
+ // spamom - office drawing table
+ // spahdr - header office drawing table
+
+ pBkmks->Write( *this ); // Bookmarks - sttbfBkmk/
+ // plcfBkmkf/plcfBkmkl
+
+ OutListTab(); // listformats - LSTF
+ OutOverrideListTab(); // - "" - - LFO
+ OutListNamesTab(); // - "" - - ListNames
+
+ pPiece->WritePc( *this ); // Piece-Table
+ OutFontTab( *pFib ); // FFNs
+ WriteDop( *this ); // Document-Properties
+ }
+ Strm().Seek( 0 );
+
+ pFib->Write( Strm() ); // FIB
+}
+
+void SwWW8Writer::StoreDoc1()
+{
+ // Start of Text ( Mangel ueber )
+ SwWW8Writer::FillUntil( Strm(), pFib->fcMin );
+
+ WriteMainText(); // HauptText
+ pFtn->WriteTxt( *this ); // Footnote-Text
+ pSepx->WriteKFTxt( *this ); // K/F-Text
+ pAtn->WriteTxt( *this ); // Annotation-Text
+ pEdn->WriteTxt( *this ); // EndNote-Text
+
+ // create the escher streams
+ if( bWrtWW8 )
+ CreateEscher();
+
+ pTxtBxs->WriteTxt( *this ); // Textbox Text Plc
+ pHFTxtBxs->WriteTxt( *this ); // Head/Foot-Textbox Text Plc
+
+ WriteStringAsPara( aEmptyStr, nLastFmtId ); // CR ans Ende ( sonst mault WW )
+
+ pSepx->Finish( Fc2Cp( Strm().Tell() ));// Text + Ftn + HdFt als Section-Ende
+
+ pFib->fcMac = Strm().Tell(); // Ende aller Texte
+
+ WriteFkpPlcUsw(); // FKP, PLC, .....
+}
+
+ULONG SwWW8Writer::StoreDoc()
+{
+ nIniFlags = ReadFilterFlags( "WWWR" );
+ nCharFmtStart = ANZ_DEFAULT_STYLES;
+ nFmtCollStart = nCharFmtStart + pDoc->GetCharFmts()->Count() - 1;
+
+ bStyDef = bBreakBefore = bOutKF =
+ bOutFlyFrmAttrs = bOutPageDescs = bOutTable = bOutFirstPage =
+ bIsInTable = bOutGrf = bInWriteEscher = bStartTOX =
+ bInWriteTOX = FALSE;
+
+ bFtnAtTxtEnd = bEndAtTxtEnd = TRUE;
+
+ pFlyFmt = 0;
+ pFlyOffset = 0;
+ nTxtTyp = TXT_MAINTEXT;
+ nFlyWidth = nFlyHeight = 0;
+ nStyleBeforeFly = nLastFmtId = 0;
+ pStyAttr = 0;
+ pOutFmtNode = 0;
+ pUsedNumTbl = 0;
+ pEscher = 0;
+ pRedlAuthors = 0;
+ if( aTOXArr.Count() )
+ aTOXArr.Remove( 0, aTOXArr.Count() );
+
+#if SUPD>593
+ if( !pOLEExp )
+ {
+ UINT32 nSvxMSDffOLEConvFlags = 0;
+ const OfaFilterOptions* pOpt = OFF_APP()->GetFilterOptions();
+ if( pOpt->IsStarMath2MathType() )
+ nSvxMSDffOLEConvFlags |= OLE_STARMATH_2_MATHTYPE;
+ if( pOpt->IsStarWriter2WinWord() )
+ nSvxMSDffOLEConvFlags |= OLE_STARWRITER_2_WINWORD;
+ if( pOpt->IsStarCalc2Excel() )
+ nSvxMSDffOLEConvFlags |= OLE_STARCALC_2_EXCEL;
+ if( pOpt->IsStarImpress2PowerPoint() )
+ nSvxMSDffOLEConvFlags |= OLE_STARIMPRESS_2_POWERPOINT;
+
+ pOLEExp = new SvxMSExportOLEObjects( nSvxMSDffOLEConvFlags );
+ }
+#endif
+
+ PrepareStorage();
+
+ PutNumFmtFontsInAttrPool();
+ PutEditEngFontsInAttrPool();
+
+ pFib = new WW8Fib( bWrtWW8 ? 8 : 6 );
+
+ SvStream* pOldStrm = pStrm; // JP 19.05.99: wozu das ???
+ SvStorageStreamRef xWwStrm( pStg->OpenStream( aMainStg ) );
+ SvStorageStreamRef xTableStrm( xWwStrm ), xDataStrm( xWwStrm );
+ xWwStrm->SetBufferSize( 32768 );
+
+ if( bWrtWW8 )
+ {
+ pFib->fWhichTblStm = 1;
+ xTableStrm = pStg->OpenStream( sTableStream, STREAM_STD_WRITE );
+ xDataStrm = pStg->OpenStream( sDataStream, STREAM_STD_WRITE );
+
+ xDataStrm->SetBufferSize( 32768 ); // fuer Grafiken
+ xTableStrm->SetBufferSize( 16384 ); // fuer die Font-/Style-Table, usw.
+
+ xTableStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ xDataStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ }
+
+ pStrm = &xWwStrm;
+ pTableStrm = &xTableStrm;
+ pDataStrm = &xDataStrm;
+
+ pStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ pAktPageDesc = &pDoc->GetPageDesc( 0 ); // Default: "Standard"
+ pSepx = new WW8_WrPlcSepx; // Sepx
+ {
+ const SfxPoolItem* pI;
+ const SwNode* pNd = pCurPam->GetCntntNode();
+ const SfxItemSet* pSet = pNd ? &((SwCntntNode*)pNd)->GetSwAttrSet()
+ : 0;
+
+ ULONG nRstLnNum = pSet ? ((SwFmtLineNumber&)pSet->Get(
+ RES_LINENUMBER )).GetStartValue()
+ : 0;
+
+ const SwTableNode* pTblNd = 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->FindStartNode()->IsSectionNode() )
+ pSectNd = pSectNd->FindStartNode()->GetSectionNode();
+
+ if( TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() )
+ {
+ pNd = pSectNd;
+ pCurPam->GetPoint()->nNode = *pNd;
+ }
+ }
+
+ // Hole evtl. Pagedesc des 1. Nodes
+ if( pSet && SFX_ITEM_ON == pSet->GetItemState(RES_PAGEDESC,TRUE,&pI)
+ && ((SwFmtPageDesc*)pI)->GetPageDesc() )
+ pSepx->AppendSep( 0, *(SwFmtPageDesc*)pI, *pNd, nRstLnNum );
+ else
+ pSepx->AppendSep( 0, pAktPageDesc, 0, nRstLnNum );
+ }
+
+ pFtn = new WW8_WrPlcFtnEdn( TXT_FTN ); // Ftn
+ pEdn = new WW8_WrPlcFtnEdn( TXT_EDN ); // Edn
+ pAtn = new WW8_WrPlcPostIt; // PostIts
+ pTxtBxs = new WW8_WrPlcTxtBoxes( TXT_TXTBOX );
+ pHFTxtBxs = new WW8_WrPlcTxtBoxes( TXT_HFTXTBOX );
+
+ pSdrObjs = new WW8_WrPlcDrawObj( TXT_TXTBOX ); // Draw-/Fly-Objects
+ pHFSdrObjs = new WW8_WrPlcDrawObj( TXT_HFTXTBOX ); // Draw-/Fly-Objects
+ // in header or footer
+
+ pBkmks = new WW8_WrtBookmarks; // Bookmarks
+ CreateBookmarkTbl();
+
+ pPapPlc = new WW8_WrPlcPn( *this, PAP, pFib->fcMin );
+ pChpPlc = new WW8_WrPlcPn( *this, CHP, pFib->fcMin );
+ pO = new WW8Bytes( 128, 128 );
+ pStyles = new WW8WrtStyle( *this );
+ pFldMain = new WW8_WrPlcFld( 2, TXT_MAINTEXT );
+ pFldHdFt = new WW8_WrPlcFld( 2, TXT_HDFT );
+ pFldFtn = new WW8_WrPlcFld( 2, TXT_FTN );
+ pFldEdn = new WW8_WrPlcFld( 2, TXT_EDN );
+ pFldTxtBxs = new WW8_WrPlcFld( 2, TXT_TXTBOX );
+ pFldHFTxtBxs = new WW8_WrPlcFld( 2, TXT_HFTXTBOX );
+
+ pGrf = new SwWW8WrGrf( *this );
+ pPiece = new WW8_WrPct( pFib->fcMin );
+ pDop = new WW8Dop;
+
+ USHORT nRedlineMode = pDoc->GetRedlineMode();
+ pDop->fRevMarking = 0 != (REDLINE_ON & nRedlineMode);
+ pDop->fRMView = 0 != ( REDLINE_SHOW_DELETE & nRedlineMode );
+ if( pDoc->GetRedlineTbl().Count() )
+ pDoc->SetRedlineMode( nRedlineMode | REDLINE_SHOW_DELETE |
+ REDLINE_SHOW_INSERT );
+
+ // set AutoHyphenation flag if found in default para style
+ const SfxPoolItem* pItem;
+ SwTxtFmtColl* pStdTxtFmtColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD );
+ if( pStdTxtFmtColl
+ && SFX_ITEM_SET == pStdTxtFmtColl->GetItemState(
+ RES_PARATR_HYPHENZONE, FALSE, &pItem ) )
+ pDop->fAutoHyphen = ((SvxHyphenZoneItem*)pItem)->IsHyphen();
+
+ // make unique OrdNums (Z-Order) for all drawing-/fly Objects
+ if( pDoc->GetDrawModel() )
+ pDoc->GetDrawModel()->GetPage( 0 )->RecalcObjOrdNums();
+
+ StoreDoc1();
+
+ if( nRedlineMode != pDoc->GetRedlineMode() )
+ pDoc->SetRedlineMode( nRedlineMode );
+
+ if( pUsedNumTbl ) // all used NumRules
+ {
+ // clear array - it's an auto delete array
+ pUsedNumTbl->Remove( 0, pUsedNumTbl->Count() );
+ delete pUsedNumTbl;
+ }
+
+ DELETEZ( pGrf );
+ DELETEZ( pFldFtn );
+ DELETEZ( pFldTxtBxs );
+ DELETEZ( pFldHFTxtBxs );
+ DELETEZ( pFldEdn );
+ DELETEZ( pFldHdFt );
+ DELETEZ( pFldMain );
+ DELETEZ( pStyles );
+ DELETEZ( pO );
+ DELETEZ( pChpPlc );
+ DELETEZ( pPapPlc );
+ DELETEZ( pSepx );
+
+ delete pRedlAuthors;
+ delete pSdrObjs;
+ delete pHFSdrObjs;
+ delete pTxtBxs;
+ delete pHFTxtBxs;
+ delete pAtn;
+ delete pEdn;
+ delete pFtn;
+ delete pBkmks;
+ delete pPiece;
+ delete pDop;
+ delete pFib;
+ pStrm = pOldStrm;
+
+
+ xWwStrm->SetBufferSize( 0 );
+ if( bWrtWW8 )
+ {
+ xTableStrm->SetBufferSize( 0 );
+ xDataStrm->SetBufferSize( 0 );
+ if( 0 == pDataStrm->Seek( STREAM_SEEK_TO_END ))
+ {
+ xDataStrm.Clear();
+ pDataStrm = 0;
+ pStg->Remove( sDataStream );
+ }
+ }
+
+ return 0;
+}
+
+
+void SwWW8Writer::PrepareStorage()
+{
+ ULONG nLen;
+ const BYTE* pData;
+ const char* pName;
+ UINT32 nId1;
+
+ if( bWrtWW8 )
+ {
+ static char __READONLY_DATA aUserName[] = "Microsoft Word-Document";
+ static BYTE __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x09, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x18, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x2D, 0x44,
+ 0x6F, 0x6B, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x00,
+ 0x0A, 0x00, 0x00, 0x00, 0x4D, 0x53, 0x57, 0x6F,
+ 0x72, 0x64, 0x44, 0x6F, 0x63, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x57, 0x6F, 0x72, 0x64, 0x2E, 0x44,
+ 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E,
+ 0x38, 0x00, 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00 };
+
+ pName = aUserName;
+ pData = aCompObj;
+ nLen = sizeof( aCompObj );
+ nId1 = 0x00020906L;
+ }
+ else
+ {
+ static char __READONLY_DATA aUserName[] = "Microsoft Word 6.0 Document";
+ static BYTE __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x09, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x1C, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x20, 0x36,
+ 0x2E, 0x30, 0x2D, 0x44, 0x6F, 0x6B, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x00, 0x0A, 0x00, 0x00, 0x00,
+ 0x4D, 0x53, 0x57, 0x6F, 0x72, 0x64, 0x44, 0x6F,
+ 0x63, 0x00, 0x10, 0x00, 0x00, 0x00, 0x57, 0x6F,
+ 0x72, 0x64, 0x2E, 0x44, 0x6F, 0x63, 0x75, 0x6D,
+ 0x65, 0x6E, 0x74, 0x2E, 0x36, 0x00, 0x00, 0x00,
+ 0x00, 0x00 };
+
+ pName = aUserName;
+ pData = aCompObj;
+ nLen = sizeof( aCompObj );
+ nId1 = 0x00020900L;
+ }
+
+ SvGlobalName aGName( nId1, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46 );
+ pStg->SetClass( aGName, 0, String::CreateFromAscii( pName ));
+ SvStorageStreamRef xStor( pStg->OpenStream( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "\1CompObj" ))));
+ xStor->Write( pData, nLen );
+ // noch mal ueberplaetten, um auch Clipboardformat zu setzen
+ pDoc->GetInfo()->SavePropertySet( pStg ); // DocInfo
+}
+
+
+ULONG SwWW8Writer::WriteStorage()
+{
+ long nMaxNode = pDoc->GetNodes().Count();
+ ::StartProgress( STR_STATSTR_W4WWRITE, 0, nMaxNode, pDoc->GetDocShell() );
+
+ // Tabelle am Doc.-Anfang beachten
+ {
+ SwTableNode * pTNd = pCurPam->GetNode()->FindTableNode();
+ if( pTNd && bWriteAll )
+ // mit dem TabellenNode anfangen !!
+ pCurPam->GetPoint()->nNode = *pTNd;
+ }
+
+ // Tabelle fuer die freifliegenden Rahmen erzeugen, aber nur wenn
+ // das gesamte Dokument geschrieben wird
+ nAktFlyPos = 0;
+ SwPosFlyFrms aFlyPos;
+ pDoc->GetAllFlyFmts( aFlyPos, bWriteAll ? 0 : pOrigPam, bWrtWW8 );
+ // Die Sonderbehandlung fuer Teilausgabe fehlt noch ( siehe RTF )
+ pFlyPos = &aFlyPos;
+
+ ULONG nRet = StoreDoc();
+
+ // loesche die Tabelle mit den freifliegenden Rahmen
+ for( USHORT i = aFlyPos.Count(); i > 0; )
+ delete aFlyPos[ --i ];
+
+ ::EndProgress( pDoc->GetDocShell() );
+ bWrtWW8 = FALSE; // sicherheitshalber: Default fuer's naechste Mal
+ return nRet;
+}
+
+SwWW8Writer::SwWW8Writer( const String& rFltName )
+ : pChpIter( 0 ), aMainStg( sMainStream ), pPapPlc( 0 ), pChpPlc( 0 ),
+ pO( 0 ), pAktPageDesc( 0 ), pISet( 0 ), pUsedNumTbl( 0 ), pBmpPal( 0 ),
+ pKeyMap( 0 )
+#if SUPD>593
+ , pOLEExp( 0 )
+#endif
+{
+ bWrtWW8 = rFltName.EqualsAscii( FILTER_WW8 );
+}
+
+SwWW8Writer::~SwWW8Writer()
+{
+ if( pBmpPal )
+ delete pBmpPal;
+ if( pKeyMap )
+ {
+ NfKeywordTable* pDel = (NfKeywordTable*)pKeyMap;
+ delete [] pDel;
+ }
+#if SUPD>593
+ if( pOLEExp )
+ delete pOLEExp;
+#endif
+}
+
+void GetWW8Writer( const String& rFltName, WriterRef& xRet )
+{
+ xRet = new SwWW8Writer( rFltName );
+}
+
+
+
+/*************************************************************************
+
+ Source Code Control System - Header
+
+ $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/filter/ww8/wrtww8.cxx,v 1.1.1.1 2000-09-18 17:14:58 hr Exp $
+
+ Source Code Control System - Update
+
+ $Log: not supported by cvs2svn $
+ Revision 1.54 2000/09/18 16:04:58 willem.vandorp
+ OpenOffice header added.
+
+ Revision 1.53 2000/08/21 10:14:06 khz
+ Export Line Numbering (restart on new section)
+
+ Revision 1.52 2000/07/25 15:16:21 khz
+ #76811# read/write AutoHyphenation flag from/into Document Properties
+
+ Revision 1.51 2000/07/06 15:55:55 khz
+ Document Statistics
+
+ Revision 1.50 2000/07/05 16:07:30 jp
+ new MS Filteroptions - change StarOffice Objects to OLE-Objects
+
+ Revision 1.49 2000/05/15 16:40:34 jp
+ Changes for Unicode
+
+ Revision 1.48 2000/05/12 16:14:07 jp
+ Changes for Unicode
+
+ Revision 1.47 2000/03/28 18:47:53 jp
+ Bug #74360#: WrFkp::Append - calculate the correct offset for W95
+
+ Revision 1.46 2000/03/09 09:23:04 jp
+ Bug #74053#: write sectionbreaks only in maintext
+
+ Revision 1.45 2000/03/03 16:08:37 pl
+ #73771# workaround for c50 intel compiler
+
+ Revision 1.44 2000/03/01 14:21:03 jp
+ Bug #73720#: StoreDoc1 - search the TOX content section
+
+ Revision 1.43 2000/02/11 14:39:55 hr
+ #70473# changes for unicode ( patched by automated patchtool )
+
+ Revision 1.42 1999/12/20 17:41:33 jp
+ Bug #70749#: Date/Time-Numberformats in german format from the formatter
+
+ Revision 1.41 1999/12/15 17:06:18 jp
+ Bug #70913#: write Ftn-/EndNoteInfo - at end of section or page/doc
+
+ Revision 1.40 1999/12/13 13:56:06 jp
+ Bug #70766#: StoreDoc - look for TOX at start of Document
+
+ Revision 1.39 1999/11/25 21:22:29 jp
+ Bug #70131#: OutFields: append the charattributes of the node to the sprms
+
+ Revision 1.38 1999/11/22 18:26:07 jp
+ export of TOX and TOX entries
+
+ Revision 1.37 1999/11/12 13:06:17 jp
+ write correct PAP-Fkps for Version 8
+
+ Revision 1.36 1999/11/02 09:44:13 jp
+ write sprmPHugePapx
+
+ Revision 1.35 1999/10/29 17:40:18 jp
+ export of 'complex'(vert. merged) tables
+
+ Revision 1.34 1999/10/14 21:06:09 jp
+ Bug #68617#,#68705# and other little things
+
+ Revision 1.33 1999/10/14 11:09:20 jp
+ export Redlines into W95/W97
+
+ Revision 1.32 1999/10/13 18:09:45 jp
+ write redlines
+
+ Revision 1.31 1999/10/13 09:08:51 jp
+ write character attributs of SdrObjects
+
+ Revision 1.30 1999/10/11 11:00:14 jp
+ some changes for export EditEngine text in WW-Format
+
+ Revision 1.29 1999/10/04 16:44:40 jp
+ Bug #68679#: check content range of bookmarkpos
+
+ Revision 1.28 1999/09/08 16:29:21 jp
+ Bug #68618#: recognize the write of escher stream
+
+ Revision 1.27 1999/08/31 07:51:34 JP
+ set NumberFormatInt at streams to littleendian
+
+
+ Rev 1.26 31 Aug 1999 09:51:34 JP
+ set NumberFormatInt at streams to littleendian
+
+ Rev 1.25 24 Aug 1999 20:15:50 JP
+ Escher Export
+
+ Rev 1.24 16 Aug 1999 17:16:28 JP
+ W97 Export: experimental escher export (1)
+
+ Rev 1.23 16 Aug 1999 13:05:44 JP
+ write EscherObjects - only a testversion!
+
+ Rev 1.22 21 Jul 1999 18:28:24 JP
+ W97 Export: experimental escher export
+
+ Rev 1.21 06 Jul 1999 14:54:00 JP
+ W97-Export corrections
+
+ Rev 1.20 30 Jun 1999 19:56:42 JP
+ W97-Export: Fields/PostIts/References
+
+ Rev 1.19 24 Jun 1999 22:52:18 JP
+ Export of Bookmarks and Hyperlinks
+
+ Rev 1.18 23 Jun 1999 20:14:40 JP
+ W97-Export: write Bookmarks
+
+ Rev 1.17 23 Jun 1999 12:46:16 JP
+ Export of numbers und outlinenumbers
+
+ Rev 1.16 16 Jun 1999 19:55:20 JP
+ Change interface of base class Writer, Export of W97 NumRules
+
+ Rev 1.15 04 Jun 1999 17:47:52 JP
+ WW97-Export: Code aufgeteilt
+
+ Rev 1.14 03 Jun 1999 21:04:10 JP
+ Export von Seitenvorlagen verbessert: Abstaende/Umrandung/ErsteSeite/...
+
+ Rev 1.13 02 Jun 1999 18:45:40 JP
+ WinWord-Export um Kopf-/Fusszeilen erweitert
+
+ Rev 1.12 31 May 1999 23:14:24 JP
+ Erweiterungen/Umstellungen fuer Export
+
+ Rev 1.11 31 May 1999 18:54:34 JP
+ Bug #66446#,#66457#: Asserts entfernt
+
+ Rev 1.10 28 May 1999 17:09:06 MPA
+ WinWord97 Export
+
+ Rev 1.9 27 May 1999 23:45:06 JP
+ PiceTable eingebaut, Schnittstellen angepasst, usw.
+
+ Rev 1.8 26 May 1999 16:44:28 MPA
+ Anfaenge Piece-Table
+
+ Rev 1.7 26 May 1999 09:39:30 JP
+ OutStyleTab entfernt, OutFontTab mit Fib-Ref, WritePlc ohne Flag
+
+ Rev 1.6 25 May 1999 17:00:10 MPA
+ Anpassung PAPX/CHPX WW97
+
+ Rev 1.5 21 May 1999 19:20:00 JP
+ kleinere Korrekturen
+
+ Rev 1.4 21 May 1999 17:01:00 MPA
+ Anf,nge WW97
+
+ Rev 1.3 21 May 1999 10:51:52 MPA
+ SwAttrItr:CTor von Pointer nach Ref
+
+ Rev 1.2 21 May 1999 02:00:50 JP
+ Export von WW97 Format: allgemeine Methoden und FontTabelle
+
+ Rev 1.1 19 May 1999 19:34:16 JP
+ WinWord97-ExportFilter
+
+ Rev 1.0 19 May 1999 11:20:02 JP
+ WinWord97-ExportFilter
+
+*************************************************************************/
+