summaryrefslogtreecommitdiff
path: root/sw/source/filter/writer
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/writer')
-rw-r--r--sw/source/filter/writer/makefile.mk94
-rw-r--r--sw/source/filter/writer/writer.cxx780
-rw-r--r--sw/source/filter/writer/wrt_fn.cxx230
-rw-r--r--sw/source/filter/writer/wrtswtbl.cxx959
4 files changed, 2063 insertions, 0 deletions
diff --git a/sw/source/filter/writer/makefile.mk b/sw/source/filter/writer/makefile.mk
new file mode 100644
index 000000000000..bea300064a8e
--- /dev/null
+++ b/sw/source/filter/writer/makefile.mk
@@ -0,0 +1,94 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 17:14:57 $
+#
+# 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): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=writer
+
+PROJECTPCH=filt_pch
+PROJECTPCHSOURCE=..\filt_1st\filt_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : $(PRJ)$/inc$/swpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/inc$/sw.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+ writer.cxx \
+ wrt_fn.cxx \
+ wrtswtbl.cxx \
+ wrttxatr.cxx \
+
+SLOFILES = \
+ $(SLO)$/writer.obj \
+ $(SLO)$/wrt_fn.obj \
+ $(SLO)$/wrtswtbl.obj \
+ $(SLO)$/wrttxatr.obj \
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sw/source/filter/writer/writer.cxx b/sw/source/filter/writer/writer.cxx
new file mode 100644
index 000000000000..677df928acee
--- /dev/null
+++ b/sw/source/filter/writer/writer.cxx
@@ -0,0 +1,780 @@
+/*************************************************************************
+ *
+ * $RCSfile: writer.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:14:57 $
+ *
+ * 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 PRECOMPILED
+#include "filt_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include <hintids.hxx>
+#endif
+
+#define _SVSTDARR_STRINGSSORTDTOR
+#include <svtools/svstdarr.hxx>
+
+#ifndef _STREAM_HXX //autogen
+#include <tools/stream.hxx>
+#endif
+#ifndef _SFXDOCFILE_HXX //autogen
+#include <sfx2/docfile.hxx>
+#endif
+#ifndef SVTOOLS_URIHELPER_HXX
+#include <svtools/urihelper.hxx>
+#endif
+#ifndef _FILTER_HXX //autogen
+#include <svtools/filter.hxx>
+#endif
+#ifndef _SVX_IMPGRF_HXX //autogen
+#include <svx/impgrf.hxx>
+#endif
+#ifndef _SVX_FONTITEM_HXX //autogen
+#include <svx/fontitem.hxx>
+#endif
+#ifndef _EEITEM_HXX
+#include <svx/eeitem.hxx>
+#endif
+
+
+#ifndef _TOOLS_TEMPFILE_HXX
+#include <tools/tempfile.hxx>
+#endif
+#ifndef _SHELLIO_HXX
+#include <shellio.hxx>
+#endif
+#ifndef _PAM_HXX
+#include <pam.hxx>
+#endif
+#ifndef _DOC_HXX
+#include <doc.hxx>
+#endif
+#ifndef _DOCARY_HXX
+#include <docary.hxx>
+#endif
+#ifndef _NODE_HXX
+#include <node.hxx>
+#endif
+#ifndef _FORMAT_HXX
+#include <format.hxx>
+#endif
+#ifndef _BOOKMRK_HXX
+#include <bookmrk.hxx> // fuer SwBookmark ...
+#endif
+#ifndef _NUMRULE_HXX //autogen
+#include <numrule.hxx>
+#endif
+
+#ifndef _SWSWERROR_H
+#include <swerror.h>
+#endif
+
+// Stringbuffer fuer die umgewandelten Zahlen
+static sal_Char aNToABuf[] = "0000000000000000000000000";
+#define NTOABUFLEN (sizeof(aNToABuf))
+
+DECLARE_TABLE( SwBookmarkNodeTable, SvPtrarr* )
+
+struct Writer_Impl
+{
+ SvStringsSortDtor *pSrcArr, *pDestArr;
+ SvPtrarr* pFontRemoveLst, *pBkmkArr;
+ SwBookmarkNodeTable* pBkmkNodePos;
+
+ Writer_Impl( const SwDoc& rDoc );
+ ~Writer_Impl();
+
+ void RemoveFontList( SwDoc& rDoc );
+ void InsertBkmk( const SwBookmark& rBkmk );
+};
+
+Writer_Impl::Writer_Impl( const SwDoc& rDoc )
+ : pSrcArr( 0 ), pDestArr( 0 ), pFontRemoveLst( 0 ), pBkmkNodePos( 0 )
+{
+}
+
+Writer_Impl::~Writer_Impl()
+{
+ delete pSrcArr;
+ delete pDestArr;
+ delete pFontRemoveLst;
+
+ if( pBkmkNodePos )
+ {
+ for( SvPtrarr* p = pBkmkNodePos->First(); p; p = pBkmkNodePos->Next() )
+ delete p;
+ delete pBkmkNodePos;
+ }
+}
+
+void Writer_Impl::RemoveFontList( SwDoc& rDoc )
+{
+ ASSERT( pFontRemoveLst, "wo ist die FontListe?" );
+ for( USHORT i = pFontRemoveLst->Count(); i; )
+ {
+ SvxFontItem* pItem = (SvxFontItem*)(*pFontRemoveLst)[ --i ];
+ rDoc.GetAttrPool().Remove( *pItem );
+ }
+}
+
+void Writer_Impl::InsertBkmk( const SwBookmark& rBkmk )
+{
+ if( !pBkmkNodePos )
+ pBkmkNodePos = new SwBookmarkNodeTable;
+
+ ULONG nNd = rBkmk.GetPos().nNode.GetIndex();
+ SvPtrarr* pArr = pBkmkNodePos->Get( nNd );
+ if( !pArr )
+ {
+ pArr = new SvPtrarr( 1, 4 );
+ pBkmkNodePos->Insert( nNd, pArr );
+ }
+
+ void* p = (void*)&rBkmk;
+ pArr->Insert( p, pArr->Count() );
+
+ if( rBkmk.GetOtherPos() && rBkmk.GetOtherPos()->nNode != nNd )
+ {
+ nNd = rBkmk.GetOtherPos()->nNode.GetIndex();
+ pArr = pBkmkNodePos->Get( nNd );
+ if( !pArr )
+ {
+ pArr = new SvPtrarr( 1, 4 );
+ pBkmkNodePos->Insert( nNd, pArr );
+ }
+ pArr->Insert( p, pArr->Count() );
+ }
+}
+
+/*
+ * Dieses Modul ist die Zentrale-Sammelstelle fuer alle Write-Filter
+ * und ist eine DLL !
+ *
+ * Damit der Writer mit den unterschiedlichen Writern arbeiten kann,
+ * muessen fuer diese die Ausgabe-Funktionen der Inhalts tragenden
+ * Objecte auf die verschiedenen Ausgabe-Funktionen gemappt werden.
+ *
+ * Dazu kann fuer jedes Object ueber den Which-Wert in einen Tabelle ge-
+ * griffen werden, um seine Ausgabe-Funktion zu erfragen.
+ * Diese Funktionen stehen in den entsprechenden Writer-DLL's.
+ */
+
+Writer::Writer()
+ : pImpl( 0 ), pStrm( 0 ), pOrigPam( 0 ), pOrigFileName( 0 ),
+ pCurPam(0), pDoc( 0 )
+{
+ bWriteAll = bShowProgress = bUCS2_WithStartChar = TRUE;
+ bASCII_NoLastLineEnd = bASCII_ParaAsBlanc = bASCII_ParaAsCR =
+ bWriteClipboardDoc = bWriteOnlyFirstTable = FALSE;
+}
+
+Writer::~Writer()
+{
+}
+
+void Writer::ResetWriter()
+{
+ if( pImpl && pImpl->pFontRemoveLst )
+ pImpl->RemoveFontList( *pDoc );
+ delete pImpl, pImpl = 0;
+
+ if( pCurPam )
+ {
+ while( pCurPam->GetNext() != pCurPam )
+ delete pCurPam->GetNext();
+ delete pCurPam;
+ }
+ pCurPam = 0;
+ pOrigFileName = 0;
+ pDoc = 0;
+ pStrm = 0;
+
+ bShowProgress = bUCS2_WithStartChar = TRUE;
+ bASCII_NoLastLineEnd = bASCII_ParaAsBlanc = bASCII_ParaAsCR =
+ bWriteClipboardDoc = bWriteOnlyFirstTable = FALSE;
+}
+
+BOOL Writer::CopyNextPam( SwPaM ** ppPam )
+{
+ if( (*ppPam)->GetNext() == pOrigPam )
+ {
+ *ppPam = pOrigPam; // wieder auf den Anfangs-Pam setzen
+ return FALSE; // Ende vom Ring
+ }
+
+ // ansonsten kopiere den die Werte aus dem naechsten Pam
+ *ppPam = ((SwPaM*)(*ppPam)->GetNext() );
+
+ *pCurPam->GetPoint() = *(*ppPam)->Start();
+ *pCurPam->GetMark() = *(*ppPam)->End();
+
+ return TRUE;
+}
+
+// suche die naechste Bookmark-Position aus der Bookmark-Tabelle
+
+USHORT Writer::FindPos_Bkmk( const SwPosition& rPos ) const
+{
+ USHORT nRet = USHRT_MAX;
+ const SwBookmarks& rBkmks = pDoc->GetBookmarks();
+
+ if( rBkmks.Count() )
+ {
+ SwBookmark aBkmk( rPos );
+ USHORT nPos;
+ if( rBkmks.Seek_Entry( &aBkmk, &nPos ))
+ {
+ // suche abwaerts nach weiteren Bookmarks auf der Cursor-Position
+ while( 0 < nPos &&
+ rBkmks[ nPos-1 ]->IsEqualPos( aBkmk ))
+ --nPos;
+ }
+ else if( nPos < rBkmks.Count() )
+ nRet = nPos;
+ }
+ return nRet;
+}
+
+
+SwPaM* Writer::NewSwPaM( SwDoc & rDoc, ULONG nStartIdx, ULONG nEndIdx,
+ BOOL bNodesArray ) const
+{
+ SwNodes* pNds = bNodesArray ? &rDoc.GetNodes() : (SwNodes*)rDoc.GetUndoNds();
+
+ SwNodeIndex aStt( *pNds, nStartIdx );
+ SwCntntNode* pCNode = aStt.GetNode().GetCntntNode();
+ if( !pCNode && 0 == ( pCNode = pNds->GoNext( &aStt )) )
+ ASSERT( !this, "An StartPos kein ContentNode mehr" );
+
+ SwPaM* pNew = new SwPaM( aStt );
+ pNew->SetMark();
+ aStt = nEndIdx;
+ if( 0 == (pCNode = aStt.GetNode().GetCntntNode()) &&
+ 0 == (pCNode = pNds->GoPrevious( &aStt )) )
+ ASSERT( !this, "An StartPos kein ContentNode mehr" );
+ pCNode->MakeEndIndex( &pNew->GetPoint()->nContent );
+ pNew->GetPoint()->nNode = aStt;
+ return pNew;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+// Stream-spezifisches
+#ifndef PRODUCT
+SvStream& Writer::Strm()
+{
+ ASSERT( pStrm, "Oh-oh. Dies ist ein Storage-Writer. Gleich knallts!" );
+ return *pStrm;
+}
+#endif
+
+
+SvStream& Writer::OutHex( SvStream& rStrm, ULONG nHex, BYTE nLen )
+{ // in einen Stream aus
+ // Pointer an das Bufferende setzen
+ sal_Char* pStr = aNToABuf + (NTOABUFLEN-1);
+ for( BYTE n = 0; n < nLen; ++n )
+ {
+ *(--pStr) = (sal_Char)(nHex & 0xf ) + 48;
+ if( *pStr > '9' )
+ *pStr += 39;
+ nHex >>= 4;
+ }
+ return rStrm << pStr;
+}
+
+SvStream& Writer::OutLong( SvStream& rStrm, long nVal )
+{
+ // Pointer an das Bufferende setzen
+ sal_Char* pStr = aNToABuf + (NTOABUFLEN-1);
+
+ int bNeg = nVal < 0;
+ if( bNeg )
+ nVal = -nVal;
+
+ do {
+ *(--pStr) = (sal_Char)(nVal % 10 ) + 48;
+ nVal /= 10;
+ } while( nVal );
+
+ // Ist Zahl negativ, dann noch -
+ if( bNeg )
+ *(--pStr) = '-';
+
+ return rStrm << pStr;
+}
+
+SvStream& Writer::OutULong( SvStream& rStrm, ULONG nVal )
+{
+ // Pointer an das Bufferende setzen
+ sal_Char* pStr = aNToABuf + (NTOABUFLEN-1);
+
+ do {
+ *(--pStr) = (sal_Char)(nVal % 10 ) + 48;
+ nVal /= 10;
+ } while ( nVal );
+ return rStrm << pStr;
+}
+
+
+ULONG Writer::Write( SwPaM& rPaM, SvStream& rStrm, const String* pFName )
+{
+ pStrm = &rStrm;
+ pDoc = rPaM.GetDoc();
+ pOrigFileName = pFName;
+ pImpl = new Writer_Impl( *pDoc );
+
+ // PaM kopieren, damit er veraendert werden kann
+ pCurPam = new SwPaM( *rPaM.End(), *rPaM.Start() );
+ // zum Vergleich auf den akt. Pam sichern
+ pOrigPam = &rPaM;
+
+ ULONG nRet = WriteStream();
+
+ ResetWriter();
+
+ return nRet;
+}
+
+ULONG Writer::Write( SwPaM& rPam, SfxMedium& rMed, const String* pFileName )
+{
+ return IsStgWriter()
+ ? Write( rPam, *rMed.GetStorage(), pFileName )
+ : Write( rPam, *rMed.GetOutStream(), pFileName );
+}
+
+ULONG Writer::Write( SwPaM& rPam, SvStorage&, const String* )
+{
+ ASSERT( !this, "Schreiben in Storages auf einem Stream?" );
+ return ERR_SWG_WRITE_ERROR;
+}
+
+
+BOOL Writer::CopyLocalFileToINet( String& rFileNm, BOOL bCIdTarget )
+{
+ BOOL bRet = FALSE;
+ INetURLObject aFileUrl( rFileNm ), aTargetUrl( *pOrigFileName );
+ if( ( INET_PROT_FILE == aFileUrl.GetProtocol() ||
+ (bCIdTarget && INET_PROT_CID == aFileUrl.GetProtocol()) ) &&
+ ( (bCIdTarget && INET_PROT_FILE == aTargetUrl.GetProtocol()) ||
+ (!bCIdTarget && INET_PROT_FILE != aTargetUrl.GetProtocol() &&
+ INET_PROT_FTP <= aTargetUrl.GetProtocol() &&
+ INET_PROT_NEWS >= aTargetUrl.GetProtocol()) ) )
+ {
+ if( pImpl->pSrcArr )
+ {
+ // wurde die Datei schon verschoben
+ USHORT nPos;
+ if( pImpl->pSrcArr->Seek_Entry( &rFileNm, &nPos ))
+ {
+ rFileNm = *(*pImpl->pDestArr)[ nPos ];
+ return TRUE;
+ }
+ }
+ else
+ {
+ pImpl->pSrcArr = new SvStringsSortDtor( 4, 4 );
+ pImpl->pDestArr = new SvStringsSortDtor( 4, 4 );
+ }
+
+ String* pSrc = new String( rFileNm );
+
+ String* pDest = 0;
+
+ if( INET_PROT_FILE == aFileUrl.GetProtocol() )
+ {
+ SvFileStream aTmp( aFileUrl.PathToFileName(), STREAM_READ );
+
+ pDest = new String( aTargetUrl.GetPartBeforeLastName() );
+ *pDest += aFileUrl.GetName();
+
+ if( INET_PROT_FILE == aTargetUrl.GetProtocol() )
+ {
+ ASSERT( bCIdTarget,
+ "CopyLocalFile: file->file: CId-Flag nicht gesetzt" );
+ INetURLObject aCpyURL( *pDest );
+ SvFileStream aCpy( aCpyURL.PathToFileName(), STREAM_WRITE );
+ aCpy << aTmp;
+
+ aCpy.Close();
+ bRet = SVSTREAM_OK == aCpy.GetError();
+ }
+ else
+ {
+ ASSERT( !bCIdTarget,
+ "CopyLocalFile: file->net: CId-Flag gesetzt" );
+ SfxMedium aMedium( *pDest, STREAM_WRITE | STREAM_SHARE_DENYNONE,
+ FALSE, FALSE );
+
+ SvFileStream aCpy( aMedium.GetPhysicalName(), STREAM_WRITE );
+ aCpy << aTmp;
+ aCpy.Close();
+
+ aMedium.Close();
+ aMedium.Commit();
+
+ bRet = 0 == aMedium.GetError();
+ }
+ }
+ else
+ {
+ ASSERT( INET_PROT_CID == aFileUrl.GetProtocol(),
+ "CopyLocalFile: cid->file: Source-URL nicht cid" );
+ ASSERT( INET_PROT_FILE == aTargetUrl.GetProtocol(),
+ "CopyLocalFile: cid->file: Target-URL nicht file" );
+ ASSERT( bCIdTarget,
+ "CopyLocalFile: cid->file: CId-Flag nicht gesetzt" );
+
+ SfxMedium aMedium( *pSrc, STREAM_READ | STREAM_SHARE_DENYNONE,
+ FALSE, TRUE );
+ if( aMedium.GetInStream() )
+ {
+ // Eine CID-URL wird in eine Datei kopiert, wenn eine
+ // Mail beantworted wird. Die Datei muss dann die richtige
+ // Extension bekommen. Da Netscape-CIDs keine Extensions
+ // enthalten muessen wir sie ueber den Grafik-Typ
+ // bestimmen und koennen sie nicht uas der URL extrahieren.
+ GraphicDescriptor aDesc( *aMedium.GetInStream() );
+ GraphicFilter *pGrfFilter = GetGrfFilter();
+
+ if ( aDesc.Detect( FALSE ) )
+ {
+ String aExt( pGrfFilter->GetImportFormatShortName(
+ aDesc.GetImportFormatNumber( aDesc.GetFileFormat(),
+ pGrfFilter->GetConfig() ) ) );
+
+ INetURLObject aAbsObj(URIHelper::SmartRelToAbs(aTargetUrl.GetMainURL()));
+ aAbsObj.removeSegment();
+ String sPath(aAbsObj.GetMainURL());
+ TempFile aTempFile(aTargetUrl.GetBase(), &aExt, &sPath);
+
+ SvFileStream aCpy( aTempFile.GetName(), STREAM_WRITE );
+ aCpy << *aMedium.GetInStream();
+ aCpy.Close();
+
+ bRet = SVSTREAM_OK == aCpy.GetError();
+ if( bRet )
+ pDest = new String( aTempFile.GetName() );
+ }
+ }
+ }
+
+ if( bRet )
+ {
+ pImpl->pSrcArr->Insert( pSrc );
+ pImpl->pDestArr->Insert( pDest );
+ rFileNm = *pDest;
+ }
+ else
+ {
+ delete pSrc;
+ delete pDest;
+ }
+ }
+
+ return bRet;
+}
+
+void Writer::PutNumFmtFontsInAttrPool()
+{
+ // dann gibt es noch in den NumRules ein paar Fonts
+ // Diese in den Pool putten. Haben sie danach einen RefCount > 1
+ // kann es wieder entfernt werden - ist schon im Pool
+ SfxItemPool& rPool = pDoc->GetAttrPool();
+ const SwNumRuleTbl& rListTbl = pDoc->GetNumRuleTbl();
+ const SwNumRule* pRule;
+ const SwNumFmt* pFmt;
+ const Font *pFont, *pDefFont = &SwNumRule::GetDefBulletFont();
+ BOOL bCheck = FALSE;
+
+ for( USHORT nGet = rListTbl.Count(); nGet; )
+ if( pDoc->IsUsed( *(pRule = rListTbl[ --nGet ] )))
+ for( BYTE nLvl = 0; nLvl < MAXLEVEL; ++nLvl )
+ if( SVX_NUM_CHAR_SPECIAL == (pFmt = &pRule->Get( nLvl ))->eType ||
+ SVX_NUM_BITMAP == pFmt->eType )
+ {
+ if( 0 == ( pFont = pFmt->GetBulletFont() ) )
+ pFont = pDefFont;
+
+ if( bCheck )
+ {
+ if( *pFont == *pDefFont )
+ continue;
+ }
+ else if( *pFont == *pDefFont )
+ bCheck = TRUE;
+
+ _AddFontItem( rPool, SvxFontItem( pFont->GetFamily(),
+ pFont->GetName(), pFont->GetStyleName(),
+ pFont->GetPitch(), pFont->GetCharSet() ));
+ }
+}
+
+void Writer::PutEditEngFontsInAttrPool()
+{
+ SfxItemPool& rPool = pDoc->GetAttrPool();
+ if( rPool.GetSecondaryPool() )
+ {
+ USHORT nW = EE_CHAR_FONTINFO;
+ const SvxFontItem* pFont = (const SvxFontItem*)&rPool.GetDefaultItem( nW );
+ _AddFontItem( rPool, *pFont );
+
+ if( 0 != ( pFont = (const SvxFontItem*)rPool.GetPoolDefaultItem( nW )) )
+ _AddFontItem( rPool, *pFont );
+
+ USHORT nMaxItem = rPool.GetItemCount( nW );
+ for( USHORT nGet = 0; nGet < nMaxItem; ++nGet )
+ if( 0 != (pFont = (const SvxFontItem*)rPool.GetItem( nW, nGet )) )
+ _AddFontItem( rPool, *pFont );
+ }
+}
+
+void Writer::_AddFontItem( SfxItemPool& rPool, const SvxFontItem& rFont )
+{
+ const SvxFontItem* pItem;
+ if( RES_CHRATR_FONT != rFont.Which() )
+ {
+ SvxFontItem aFont( rFont );
+ aFont.SetWhich( RES_CHRATR_FONT );
+ pItem = (SvxFontItem*)&rPool.Put( aFont );
+ }
+ else
+ pItem = (SvxFontItem*)&rPool.Put( rFont );
+
+ if( 1 < pItem->GetRef() )
+ rPool.Remove( *pItem );
+ else
+ {
+ if( !pImpl->pFontRemoveLst )
+ pImpl->pFontRemoveLst = new SvPtrarr( 0, 10 );
+
+ void* p = (void*)pItem;
+ pImpl->pFontRemoveLst->Insert( p, pImpl->pFontRemoveLst->Count() );
+ }
+}
+
+// build a bookmark table, which is sort by the node position. The
+// OtherPos of the bookmarks also inserted.
+void Writer::CreateBookmarkTbl()
+{
+ const SwBookmarks& rBkmks = pDoc->GetBookmarks();
+ for( USHORT n = rBkmks.Count(); n; )
+ {
+ const SwBookmark& rBkmk = *rBkmks[ --n ];
+ if( rBkmk.IsBookMark() )
+ pImpl->InsertBkmk( rBkmk );
+ }
+}
+
+
+// search alle Bookmarks in the range and return it in the Array
+USHORT Writer::GetBookmarks( const SwCntntNode& rNd, xub_StrLen nStt,
+ xub_StrLen nEnd, SvPtrarr& rArr )
+{
+ ASSERT( !rArr.Count(), "es sind noch Eintraege vorhanden" );
+
+ ULONG nNd = rNd.GetIndex();
+ SvPtrarr* pArr = pImpl->pBkmkNodePos ? pImpl->pBkmkNodePos->Get( nNd ) : 0;
+ if( pArr )
+ {
+ // there exist some bookmarks, search now all which is in the range
+ if( !nStt && nEnd == rNd.Len() )
+ // all
+ rArr.Insert( pArr, 0 );
+ else
+ {
+ USHORT n;
+ xub_StrLen nCntnt;
+ for( n = 0; n < pArr->Count(); ++n )
+ {
+ void* p = (*pArr)[ n ];
+ const SwBookmark& rBkmk = *(SwBookmark*)p;
+ if( rBkmk.GetPos().nNode == nNd &&
+ (nCntnt = rBkmk.GetPos().nContent.GetIndex() ) >= nStt &&
+ nCntnt < nEnd )
+ {
+ rArr.Insert( p, rArr.Count() );
+ }
+ else if( rBkmk.GetOtherPos() && nNd ==
+ rBkmk.GetOtherPos()->nNode.GetIndex() && (nCntnt =
+ rBkmk.GetOtherPos()->nContent.GetIndex() ) >= nStt &&
+ nCntnt < nEnd )
+ {
+ rArr.Insert( p, rArr.Count() );
+ }
+ }
+ }
+ }
+ return rArr.Count();
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+// Storage-spezifisches
+
+ULONG StgWriter::WriteStream()
+{
+ ASSERT( !this, "Schreiben in Streams auf einem Storage?" );
+ return ERR_SWG_WRITE_ERROR;
+}
+
+ULONG StgWriter::Write( SwPaM& rPaM, SvStorage& rStg, const String* pFName )
+{
+ pStrm = 0;
+ pStg = &rStg;
+ pDoc = rPaM.GetDoc();
+ pOrigFileName = pFName;
+ pImpl = new Writer_Impl( *pDoc );
+
+ // PaM kopieren, damit er veraendert werden kann
+ pCurPam = new SwPaM( *rPaM.End(), *rPaM.Start() );
+ // zum Vergleich auf den akt. Pam sichern
+ pOrigPam = &rPaM;
+
+ ULONG nRet = WriteStorage();
+
+ pStg = NULL;
+ ResetWriter();
+
+ return nRet;
+}
+
+/*************************************************************************
+
+ Source Code Control System - Header
+
+ $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/filter/writer/writer.cxx,v 1.1.1.1 2000-09-18 17:14:57 hr Exp $
+
+ Source Code Control System - Update
+
+ $Log: not supported by cvs2svn $
+ Revision 1.103 2000/09/18 16:04:55 willem.vandorp
+ OpenOffice header added.
+
+ Revision 1.102 2000/08/04 16:25:50 jp
+ read/write unicode ascii files
+
+ Revision 1.101 2000/06/26 13:01:26 os
+ INetURLObject::SmartRelToAbs removed
+
+ Revision 1.100 2000/06/13 09:43:46 os
+ using UCB
+
+ Revision 1.99 2000/05/08 16:51:53 jp
+ Changes for Unicode
+
+ Revision 1.98 1999/10/13 10:38:29 jp
+ PutEditEngFontsInAtrPool - check if the editenginepool exist
+
+ Revision 1.97 1999/10/12 20:04:37 jp
+ Writer: put EditEngine fonts into the writer pool
+
+ Revision 1.96 1999/08/12 10:19:56 MIB
+ Don\'t delete impl if it hasn\'t been set (for XML filter)
+
+
+ Rev 1.95 12 Aug 1999 12:19:56 MIB
+ Don't delete impl if it hasn't been set (for XML filter)
+
+ Rev 1.94 30 Jun 1999 18:53:20 JP
+ dtor for impl class
+
+ Rev 1.93 24 Jun 1999 22:51:34 JP
+ new: Writer with internal Impl-structur, build Bookmark table sortet by nodes
+
+ Rev 1.92 23 Jun 1999 19:13:40 JP
+ interface of Writer::FindPos_Bkmk has changed
+
+ Rev 1.91 16 Jun 1999 19:52:14 JP
+ Change interface of base class Writer
+
+ Rev 1.90 28 Jan 1999 14:21:28 JP
+ GraphicFilter-SS hat sich geaendert - Task #59174#
+
+ Rev 1.89 30 Oct 1998 18:30:02 JP
+ Task #58596#: neues Flag an der Writerklasse -> schreibe nur die 1. Tabelle
+
+ Rev 1.88 27 Jun 1998 16:02:08 JP
+ Writer mit neuen Flags; fuer den ASCII-Writer, etwas aufgeraeumt
+
+ Rev 1.87 23 Apr 1998 19:07:44 MIB
+ fix #49729#: Stream beim kopieren von Grafiken ins INet schliessen
+
+ Rev 1.86 22 Jan 1998 20:02:56 JP
+ CTOR des SwPaM umgestellt
+
+ Rev 1.85 26 Nov 1997 14:29:14 MA
+ headerfiles
+
+ Rev 1.84 03 Nov 1997 14:12:48 MA
+ precomp entfernt
+
+ Rev 1.83 13 Oct 1997 16:06:34 JP
+ pNext vom Ring wurde privat; zugriff ueber GetNext()
+
+ Rev 1.82 09 Oct 1997 14:26:24 JP
+ Umstellung NodeIndex/-Array/BigPtrArray
+
+ Rev 1.81 03 Sep 1997 11:59:44 JP
+ zusaetzliches include von docary
+
+*************************************************************************/
+
diff --git a/sw/source/filter/writer/wrt_fn.cxx b/sw/source/filter/writer/wrt_fn.cxx
new file mode 100644
index 000000000000..98784a8a3eb9
--- /dev/null
+++ b/sw/source/filter/writer/wrt_fn.cxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * $RCSfile: wrt_fn.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:14:57 $
+ *
+ * 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 PRECOMPILED
+#include "filt_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SFXITEMITER_HXX //autogen
+#include <svtools/itemiter.hxx>
+#endif
+#ifndef _SFX_WHITER_HXX //autogen
+#include <svtools/whiter.hxx>
+#endif
+
+
+#include "shellio.hxx"
+#include "wrt_fn.hxx"
+#include "pam.hxx"
+#include "node.hxx"
+#include "format.hxx"
+
+
+
+Writer& Out( const SwAttrFnTab pTab, const SfxPoolItem& rHt, Writer & rWrt )
+{
+ USHORT nId = rHt.Which();
+ ASSERT( nId < POOLATTR_END && nId >= POOLATTR_BEGIN, "SwAttrFnTab::Out()" );
+ FnAttrOut pOut;
+ if( 0 != ( pOut = pTab[ nId - RES_CHRATR_BEGIN] ))
+ (*pOut)( rWrt, rHt );
+ return rWrt;
+
+}
+
+Writer& Out_SfxItemSet( const SwAttrFnTab pTab, Writer& rWrt,
+ const SfxItemSet& rSet, BOOL bDeep,
+ BOOL bTstForDefault )
+{
+ // erst die eigenen Attribute ausgeben
+ const SfxItemPool& rPool = *rSet.GetPool();
+ const SfxItemSet* pSet = &rSet;
+ if( !pSet->Count() ) // Optimierung - leere Sets
+ {
+ if( !bDeep )
+ return rWrt;
+ while( 0 != ( pSet = pSet->GetParent() ) && !pSet->Count() )
+ ;
+ if( !pSet )
+ return rWrt;
+ }
+ const SfxPoolItem* pItem;
+ FnAttrOut pOut;
+ if( !bDeep || !pSet->GetParent() )
+ {
+ ASSERT( rSet.Count(), "Wurde doch schon behandelt oder?" );
+ SfxItemIter aIter( *pSet );
+ pItem = aIter.GetCurItem();
+ do {
+ if( 0 != ( pOut = pTab[ pItem->Which() - RES_CHRATR_BEGIN] ))
+ (*pOut)( rWrt, *pItem );
+ } while( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) );
+ }
+ else
+ {
+ SfxWhichIter aIter( *pSet );
+ register USHORT nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ if( SFX_ITEM_SET == pSet->GetItemState( nWhich, bDeep, &pItem ) &&
+ ( !bTstForDefault || (
+ *pItem != rPool.GetDefaultItem( nWhich )
+ || ( pSet->GetParent() &&
+ *pItem != pSet->GetParent()->Get( nWhich ))
+ )) && 0 != ( pOut = pTab[ nWhich - RES_CHRATR_BEGIN] ))
+ (*pOut)( rWrt, *pItem );
+ nWhich = aIter.NextWhich();
+ }
+ }
+ return rWrt;
+}
+
+
+
+Writer& Out( const SwNodeFnTab pTab, SwNode& rNode, Writer & rWrt )
+{
+ // es muss ein CntntNode sein !!
+ SwCntntNode * pCNd = rNode.GetCntntNode();
+ if( !pCNd )
+ return rWrt;
+
+ USHORT nId;
+ switch( pCNd->GetNodeType() )
+ {
+ case ND_TEXTNODE: nId = RES_TXTNODE; break;
+ case ND_GRFNODE: nId = RES_GRFNODE; break;
+ case ND_OLENODE: nId = RES_OLENODE; break;
+ default:
+ ASSERT( FALSE, "was fuer ein Node ist es denn nun?" );
+ }
+ FnNodeOut pOut;
+ if( 0 != ( pOut = pTab[ nId - RES_NODE_BEGIN ] ))
+ (*pOut)( rWrt, *pCNd );
+ return rWrt;
+}
+
+
+/*************************************************************************
+
+ Source Code Control System - Header
+
+ $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/filter/writer/wrt_fn.cxx,v 1.1.1.1 2000-09-18 17:14:57 hr Exp $
+
+ Source Code Control System - Update
+
+ $Log: not supported by cvs2svn $
+ Revision 1.32 2000/09/18 16:04:55 willem.vandorp
+ OpenOffice header added.
+
+ Revision 1.31 1999/07/06 12:55:38 JP
+ Out_SfxItemSet: test to default items optional
+
+
+ Rev 1.30 06 Jul 1999 14:55:38 JP
+ Out_SfxItemSet: test to default items optional
+
+ Rev 1.29 26 Nov 1997 14:29:14 MA
+ headerfiles
+
+ Rev 1.28 03 Nov 1997 14:12:48 MA
+ precomp entfernt
+
+ Rev 1.27 22 Jan 1997 12:01:18 JP
+ neu: Tabellen Box Attribute
+
+ Rev 1.26 16 Oct 1996 16:58:54 JP
+ unbenutzte Methoden entfernt
+
+ Rev 1.25 01 Jul 1996 16:03:14 MA
+ includes
+
+ Rev 1.24 22 Mar 1996 14:52:12 SWG
+ include hinzugefuegt
+
+ Rev 1.23 24 Nov 1995 17:24:42 OM
+ PCH->PRECOMPILED
+
+ Rev 1.22 25 Oct 1994 15:57:12 MA
+ PreHdr.
+
+ Rev 1.21 04 Oct 1994 16:34:06 JP
+ Out_SfxItemSet: optimiert
+
+ Rev 1.20 28 Sep 1994 12:37:34 JP
+ neue Methode: Out_SfxItemSet
+
+ Rev 1.19 25 Aug 1994 18:09:12 JP
+ Umstellung Attribute (von SwHint -> SfxPoolItem)
+
+ Rev 1.18 15 Feb 1994 15:31:30 MI
+ handsegmentierung
+
+ Rev 1.17 28 Jan 1994 11:34:06 MI
+ TCOV() entfernt, SW_... nach SEG_... umbenannt
+
+ Rev 1.16 13 Jan 1994 08:31:32 MI
+ Segmentierung per #define ermoeglicht
+
+*************************************************************************/
+
+
diff --git a/sw/source/filter/writer/wrtswtbl.cxx b/sw/source/filter/writer/wrtswtbl.cxx
new file mode 100644
index 000000000000..308c191c48e4
--- /dev/null
+++ b/sw/source/filter/writer/wrtswtbl.cxx
@@ -0,0 +1,959 @@
+/*************************************************************************
+ *
+ * $RCSfile: wrtswtbl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:14:57 $
+ *
+ * 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
+
+#ifndef _HINTIDS_HXX
+#include <hintids.hxx>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SVX_BOXITEM_HXX //autogen
+#include <svx/boxitem.hxx>
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include <svx/brshitem.hxx>
+#endif
+#ifndef _FRACT_HXX
+#include <tools/fract.hxx>
+#endif
+
+#ifndef _WRTSWTBL_HXX
+#include <wrtswtbl.hxx>
+#endif
+#ifndef _SWTABLE_HXX
+#include <swtable.hxx>
+#endif
+#ifndef _FRMFMT_HXX
+#include <frmfmt.hxx>
+#endif
+#ifndef _FMTFSIZE_HXX
+#include <fmtfsize.hxx>
+#endif
+#ifndef _FMTORNT_HXX
+#include <fmtornt.hxx>
+#endif
+#ifndef _FRMATR_HXX
+#include <frmatr.hxx>
+#endif
+#ifndef _HTMLTBL_HXX
+#include <htmltbl.hxx>
+#endif
+
+
+SV_IMPL_PTRARR( SwWriteTableCells, SwWriteTableCellPtr )
+SV_IMPL_OP_PTRARR_SORT( SwWriteTableRows, SwWriteTableRowPtr )
+SV_IMPL_OP_PTRARR_SORT( SwWriteTableCols, SwWriteTableColPtr )
+
+//-----------------------------------------------------------------------
+
+SwVertOrient SwWriteTableCell::GetVertOri() const
+{
+ SwVertOrient eCellVertOri = VERT_TOP;
+ if( pBox->GetSttNd() )
+ {
+ const SfxItemSet& rItemSet = pBox->GetFrmFmt()->GetAttrSet();
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_VERT_ORIENT, FALSE, &pItem ) )
+ {
+ SwVertOrient eBoxVertOri =
+ ((const SwFmtVertOrient *)pItem)->GetVertOrient();
+ if( VERT_CENTER==eBoxVertOri || VERT_BOTTOM==eBoxVertOri)
+ eCellVertOri = eBoxVertOri;
+ }
+ }
+
+ return eCellVertOri;
+}
+
+//-----------------------------------------------------------------------
+
+SwWriteTableRow::SwWriteTableRow( long nPosition )
+ : nPos(nPosition), pBackground( 0 ),
+ bTopBorder(TRUE), bBottomBorder(TRUE),
+ nTopBorder(USHRT_MAX), nBottomBorder(USHRT_MAX)
+{
+}
+
+
+SwWriteTableCell *SwWriteTableRow::AddCell( const SwTableBox *pBox,
+ USHORT nRow, USHORT nCol,
+ USHORT nRowSpan, USHORT nColSpan,
+ long nHeight,
+ const SvxBrushItem *pBackground )
+{
+ SwWriteTableCell *pCell =
+ new SwWriteTableCell( pBox, nRow, nCol, nRowSpan, nColSpan,
+ nHeight, pBackground );
+ aCells.Insert( pCell, aCells.Count() );
+
+ return pCell;
+}
+
+//-----------------------------------------------------------------------
+
+SwWriteTableCol::SwWriteTableCol( USHORT nPosition )
+ : nPos(nPosition),
+ bLeftBorder(TRUE), bRightBorder(TRUE),
+ nWidthOpt( 0 ), bRelWidthOpt( FALSE ),
+ bOutWidth( TRUE )
+{
+}
+
+//-----------------------------------------------------------------------
+
+long SwWriteTable::GetBoxWidth( const SwTableBox *pBox )
+{
+ const SwFrmFmt *pFmt = pBox->GetFrmFmt();
+ const SwFmtFrmSize& aFrmSize=
+ (const SwFmtFrmSize&)pFmt->GetAttr( RES_FRM_SIZE );
+
+ return aFrmSize.GetSize().Width();
+}
+
+long SwWriteTable::GetLineHeight( const SwTableLine *pLine )
+{
+#ifndef PRODUCT
+ BOOL bOldGetLineHeightCalled = bGetLineHeightCalled;
+ bGetLineHeightCalled = TRUE;
+#endif
+
+ long nHeight = 0;
+ if( bUseLayoutHeights )
+ {
+ // Erstmal versuchen wir die Hoehe ueber das Layout zu bekommen
+ long nHeight = pLine->GetLineRect( FALSE ).Height();
+ if( nHeight > 0 )
+ return nHeight;
+
+ // Wenn kein Layout gefunden wurde, gehen wir von festen Hoehen aus.
+ bUseLayoutHeights = FALSE;
+
+#ifndef PRODUCT
+ ASSERT( !bOldGetLineHeightCalled, "Layout ungueltig?" );
+#endif
+ }
+
+ const SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+ USHORT nBoxes = rBoxes.Count();
+
+ for( USHORT nBox=0; nBox<nBoxes; nBox++ )
+ {
+ const SwTableBox* pBox = rBoxes[nBox];
+ if( pBox->GetSttNd() )
+ {
+ if( nHeight < ROW_DFLT_HEIGHT )
+ nHeight = ROW_DFLT_HEIGHT;
+ }
+ else
+ {
+ long nTmp = 0;
+ const SwTableLines &rLines = pBox->GetTabLines();
+ for( USHORT nLine=0; nLine<rLines.Count(); nLine++ )
+ {
+ nTmp += GetLineHeight( rLines[nLine] );
+ }
+ if( nHeight < nTmp )
+ nHeight = nTmp;
+ }
+ }
+
+ return nHeight;
+}
+
+long SwWriteTable::GetLineHeight( const SwTableBox *pBox ) const
+{
+ const SwTableLine *pLine = pBox->GetUpper();
+
+ if( !pLine )
+ return 0;
+
+ const SwFrmFmt *pLineFrmFmt = pLine->GetFrmFmt();
+ const SfxPoolItem* pItem;
+ const SfxItemSet& rItemSet = pLineFrmFmt->GetAttrSet();
+
+ long nHeight = 0;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRM_SIZE, TRUE, &pItem ))
+ nHeight = ((SwFmtFrmSize*)pItem)->GetHeight();
+
+ return nHeight;
+}
+
+const SvxBrushItem *SwWriteTable::GetLineBrush( const SwTableBox *pBox,
+ SwWriteTableRow *pRow )
+{
+ const SwTableLine *pLine = pBox->GetUpper();
+
+ while( pLine )
+ {
+ const SwFrmFmt *pLineFrmFmt = pLine->GetFrmFmt();
+ const SfxPoolItem* pItem;
+ const SfxItemSet& rItemSet = pLineFrmFmt->GetAttrSet();
+
+ const SvxBrushItem *pBrushItem = 0;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, FALSE,
+ &pItem ) )
+ {
+ if( !pLine->GetUpper() )
+ {
+ if( !pRow->GetBackground() )
+ pRow->SetBackground( (const SvxBrushItem *)pItem );
+ pItem = 0;
+ }
+
+ return (const SvxBrushItem *)pItem;
+ }
+
+ pBox = pLine->GetUpper();
+ pLine = pBox ? pBox->GetUpper() : 0;
+ }
+
+ return 0;
+}
+
+
+void SwWriteTable::MergeBorders( const SvxBorderLine* pBorderLine,
+ BOOL bTable )
+{
+ if( (UINT32)-1 == nBorderColor )
+ {
+ Color aGrayColor( COL_GRAY );
+ if( !pBorderLine->GetColor().IsRGBEqual( aGrayColor ) )
+ nBorderColor = pBorderLine->GetColor().GetColor();
+ }
+
+ if( !bCollectBorderWidth )
+ return;
+
+ USHORT nOutWidth = pBorderLine->GetOutWidth();
+ if( bTable )
+ {
+ if( nOutWidth && (!nBorder || nOutWidth < nBorder) )
+ nBorder = nOutWidth;
+ }
+ else
+ {
+ if( nOutWidth && (!nInnerBorder || nOutWidth < nInnerBorder) )
+ nInnerBorder = nOutWidth;
+ }
+
+ USHORT nDist = pBorderLine->GetInWidth() ? pBorderLine->GetDistance()
+ : 0;
+ if( nDist && (!nCellSpacing || nDist < nCellSpacing) )
+ nCellSpacing = nDist;
+}
+
+
+USHORT SwWriteTable::MergeBoxBorders( const SwTableBox *pBox,
+ USHORT nRow, USHORT nCol,
+ USHORT nRowSpan, USHORT nColSpan,
+ USHORT& rTopBorder,
+ USHORT &rBottomBorder )
+{
+ USHORT nBorderMask = 0;
+
+ const SwFrmFmt *pFrmFmt = pBox->GetFrmFmt();
+ const SvxBoxItem& rBoxItem = (const SvxBoxItem&)pFrmFmt->GetAttr( RES_BOX );
+
+ USHORT nWidth = 0;
+
+ if( rBoxItem.GetTop() )
+ {
+ nBorderMask |= 1;
+ MergeBorders( rBoxItem.GetTop(), nRow==0 );
+ rTopBorder = rBoxItem.GetTop()->GetOutWidth();
+ }
+
+ if( rBoxItem.GetLeft() )
+ {
+ nBorderMask |= 4;
+ MergeBorders( rBoxItem.GetLeft(), nCol==0 );
+ }
+
+ if( rBoxItem.GetBottom() )
+ {
+ nBorderMask |= 2;
+ MergeBorders( rBoxItem.GetBottom(), nRow+nRowSpan==aRows.Count() );
+ rBottomBorder = rBoxItem.GetBottom()->GetOutWidth();
+ }
+
+ if( rBoxItem.GetRight() )
+ {
+ nBorderMask |= 8;
+ MergeBorders( rBoxItem.GetRight(), nCol+nColSpan==aCols.Count() );
+ }
+
+ // If any distance is set, the smallest one is used. This holds for
+ // the four distance of a box as well as for the distances of different
+ // boxes.
+ if( bCollectBorderWidth )
+ {
+ USHORT nDist = rBoxItem.GetDistance( BOX_LINE_TOP );
+ if( nDist && (!nCellPadding || nDist < nCellPadding) )
+ nCellPadding = nDist;
+ nDist = rBoxItem.GetDistance( BOX_LINE_BOTTOM );
+ if( nDist && (!nCellPadding || nDist < nCellPadding) )
+ nCellPadding = nDist;
+ nDist = rBoxItem.GetDistance( BOX_LINE_LEFT );
+ if( nDist && (!nCellPadding || nDist < nCellPadding) )
+ nCellPadding = nDist;
+ nDist = rBoxItem.GetDistance( BOX_LINE_RIGHT );
+ if( nDist && (!nCellPadding || nDist < nCellPadding) )
+ nCellPadding = nDist;
+ }
+
+ return nBorderMask;
+}
+
+
+USHORT SwWriteTable::GetRawWidth( USHORT nCol, USHORT nColSpan ) const
+{
+ USHORT nWidth = aCols[nCol+nColSpan-1]->GetPos();
+ if( nCol > 0 )
+ nWidth -= aCols[nCol-1]->GetPos();
+
+ return nWidth;
+}
+
+USHORT SwWriteTable::GetLeftSpace( USHORT nCol ) const
+{
+ USHORT nSpace = nCellPadding + nCellSpacing;
+
+ // In der ersten Spalte auch noch die Liniendicke abziehen
+ if( nCol==0 )
+ {
+ nSpace += nLeftSub;
+
+ const SwWriteTableCol *pCol = aCols[nCol];
+ if( pCol->HasLeftBorder() )
+ nSpace += nBorder;
+ }
+
+ return nSpace;
+}
+
+USHORT SwWriteTable::GetRightSpace( USHORT nCol, USHORT nColSpan ) const
+{
+ USHORT nSpace = nCellPadding;
+
+ // In der letzten Spalte noch einmal zusaetzlich CELLSPACING und
+ // und die Liniendicke abziehen
+ if( nCol+nColSpan==aCols.Count() )
+ {
+ nSpace += (nCellSpacing + nRightSub);
+
+ const SwWriteTableCol *pCol = aCols[nCol+nColSpan-1];
+ if( pCol->HasRightBorder() )
+ nSpace += nBorder;
+ }
+
+ return nSpace;
+}
+
+USHORT SwWriteTable::GetAbsWidth( USHORT nCol, USHORT nColSpan ) const
+{
+ long nWidth = GetRawWidth( nCol, nColSpan );
+ if( nBaseWidth != nTabWidth )
+ {
+ nWidth *= nTabWidth;
+ nWidth /= nBaseWidth;
+ }
+
+ nWidth -= GetLeftSpace( nCol ) + GetRightSpace( nCol, nColSpan );
+
+ ASSERT( nWidth > 0, "Spaltenbreite <= 0. OK?" );
+ return nWidth > 0 ? (USHORT)nWidth : 0;
+}
+
+USHORT SwWriteTable::GetRelWidth( USHORT nCol, USHORT nColSpan ) const
+{
+ long nWidth = GetRawWidth( nCol, nColSpan );
+
+ return (USHORT)(long)Fraction( nWidth*256 + GetBaseWidth()/2,
+ GetBaseWidth() );
+}
+
+USHORT SwWriteTable::GetPrcWidth( USHORT nCol, USHORT nColSpan ) const
+{
+ long nWidth = GetRawWidth( nCol, nColSpan );
+
+ // sieht komisch aus, ist aber nichts anderes als
+ // [(100 * nWidth) + .5] ohne Rundungsfehler
+ return (USHORT)(long)Fraction( nWidth*100 + GetBaseWidth()/2,
+ GetBaseWidth() );
+}
+
+long SwWriteTable::GetAbsHeight( long nRawHeight, USHORT nRow,
+ USHORT nRowSpan ) const
+{
+ nRawHeight -= (2*nCellPadding + nCellSpacing);
+
+ // In der ersten Zeile noch einmal zusaetzlich CELLSPACING und
+ // und die Liniendicke abziehen
+ const SwWriteTableRow *pRow = 0;
+ if( nRow==0 )
+ {
+ nRawHeight -= nCellSpacing;
+ pRow = aRows[nRow];
+ if( pRow->HasTopBorder() )
+ nRawHeight -= nBorder;
+ }
+
+ // In der letzten Zeile noch die Liniendicke abziehen
+ if( nRow+nRowSpan==aRows.Count() )
+ {
+ if( !pRow || nRowSpan > 1 )
+ pRow = aRows[nRow+nRowSpan-1];
+ if( pRow->HasBottomBorder() )
+ nRawHeight -= nBorder;
+ }
+
+ ASSERT( nRawHeight > 0, "Zeilenheohe <= 0. OK?" );
+ return nRawHeight > 0 ? nRawHeight : 0;
+}
+
+
+
+BOOL SwWriteTable::ShouldExpandSub( const SwTableBox *pBox,
+ BOOL bExpandedBefore,
+ USHORT nDepth ) const
+{
+ return !pBox->GetSttNd() && nDepth > 0;
+}
+
+void SwWriteTable::CollectTableRowsCols( long nStartRPos,
+ USHORT nStartCPos,
+ long nParentLineHeight,
+ USHORT nParentLineWidth,
+ const SwTableLines& rLines,
+ USHORT nDepth )
+{
+ BOOL bSubExpanded = FALSE;
+ USHORT nLines = rLines.Count();
+
+#ifndef PRODUCT
+ USHORT nEndCPos = 0;
+#endif
+
+ long nRPos = nStartRPos;
+ for( USHORT nLine = 0; nLine < nLines; nLine++ )
+ {
+ /*const*/ SwTableLine *pLine = rLines[nLine];
+
+ long nOldRPos = nRPos;
+
+ if( nLine < nLines-1 || nParentLineHeight==0 )
+ {
+ nRPos += GetLineHeight( pLine );
+ SwWriteTableRow *pRow = new SwWriteTableRow( nRPos );
+
+ USHORT nRow;
+ if( aRows.Seek_Entry( pRow, &nRow ) )
+ delete pRow;
+ else
+ aRows.Insert( pRow );
+ }
+ else
+ {
+ long nCheckPos = nRPos + GetLineHeight( pLine );
+ nRPos = nStartRPos + nParentLineHeight;
+#ifndef PRODUCT
+ SwWriteTableRow aRow( nStartRPos + nParentLineHeight );
+ ASSERT( aRows.Seek_Entry(&aRow),
+ "Parent-Zeile nicht gefunden" );
+ ASSERT( !bUseLayoutHeights ||
+ SwWriteTableRow(nCheckPos) == SwWriteTableRow(nRPos),
+ "Hoehe der Zeilen stimmt nicht mit Parent ueberein" );
+#endif
+ }
+
+ // Fuer alle Boxen der Zeile ggf. eine Spalte einfuegen
+ const SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+ USHORT nBoxes = rBoxes.Count();
+
+ USHORT nCPos = nStartCPos;
+ for( USHORT nBox=0; nBox<nBoxes; nBox++ )
+ {
+ const SwTableBox *pBox = rBoxes[nBox];
+
+ USHORT nOldCPos = nCPos;
+
+ if( nBox < nBoxes-1 || (nParentLineWidth==0 && nLine==0) )
+ {
+ nCPos += (USHORT)GetBoxWidth( pBox );
+ SwWriteTableCol *pCol = new SwWriteTableCol( nCPos );
+
+ USHORT nCol;
+ if( aCols.Seek_Entry( pCol, &nCol ) )
+ delete pCol;
+ else
+ aCols.Insert( pCol );
+
+ if( nBox==nBoxes-1 )
+ {
+ ASSERT( nLine==0 && nParentLineWidth==0,
+ "Jetzt wird die Parent-Breite plattgemacht!" );
+ nParentLineWidth = nCPos-nStartCPos;
+ }
+ }
+ else
+ {
+#ifndef PRODUCT
+ USHORT nCheckPos = nCPos + (USHORT)GetBoxWidth( pBox );
+ if( !nEndCPos )
+ {
+ nEndCPos = nCheckPos;
+ }
+ else
+ {
+ ASSERT( SwWriteTableCol(nCheckPos) ==
+ SwWriteTableCol(nEndCPos),
+ "Zelle enthaelt unterschiedlich breite Zeilen" );
+ }
+#endif
+ nCPos = nStartCPos + nParentLineWidth;
+#ifndef PRODUCT
+ SwWriteTableCol aCol( nStartCPos + nParentLineWidth );
+ ASSERT( aCols.Seek_Entry(&aCol),
+ "Parent-Zelle nicht gefunden" );
+ ASSERT( SwWriteTableCol(nCheckPos) ==
+ SwWriteTableCol(nCPos),
+ "Breite der Zellen stimmt nicht mit Parent ueberein" );
+#endif
+ }
+
+ if( ShouldExpandSub( pBox, bSubExpanded, nDepth ) )
+ {
+ CollectTableRowsCols( nOldRPos, nOldCPos,
+ nRPos - nOldRPos,
+ nCPos - nOldCPos,
+ pBox->GetTabLines(),
+ nDepth-1 );
+ bSubExpanded = TRUE;
+ }
+ }
+ }
+}
+
+
+void SwWriteTable::FillTableRowsCols( long nStartRPos, USHORT nStartRow,
+ USHORT nStartCPos, USHORT nStartCol,
+ long nParentLineHeight,
+ USHORT nParentLineWidth,
+ const SwTableLines& rLines,
+ const SvxBrushItem* pParentBrush,
+ USHORT nDepth )
+{
+ USHORT nLines = rLines.Count();
+ BOOL bSubExpanded = FALSE;
+
+ // Festlegen der Umrandung
+ long nRPos = nStartRPos;
+ USHORT nRow = nStartRow;
+
+ for( USHORT nLine = 0; nLine < nLines; nLine++ )
+ {
+ const SwTableLine *pLine = rLines[nLine];
+
+ // Position der letzten ueberdeckten Zeile ermitteln
+ long nOldRPos = nRPos;
+ if( nLine < nLines-1 || nParentLineHeight==0 )
+ nRPos += GetLineHeight( pLine );
+ else
+ nRPos = nStartRPos + nParentLineHeight;
+
+ // Und ihren Index
+ USHORT nOldRow = nRow;
+ SwWriteTableRow aRow( nRPos );
+ BOOL bFound = aRows.Seek_Entry( &aRow, &nRow );
+ ASSERT( bFound, "Wo ist die Zeile geblieben?" );
+
+ SwWriteTableRow *pRow = aRows[nOldRow];
+ SwWriteTableRow *pEndRow = aRows[nRow];
+ if( nLine==0 && nParentLineHeight==0 )
+ nHeadEndRow = nRow;
+
+ const SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+
+ const SwFrmFmt *pLineFrmFmt = pLine->GetFrmFmt();
+ const SfxPoolItem* pItem;
+ const SfxItemSet& rItemSet = pLineFrmFmt->GetAttrSet();
+
+ long nHeight = 0;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRM_SIZE, TRUE, &pItem ))
+ nHeight = ((SwFmtFrmSize*)pItem)->GetHeight();
+
+
+ const SvxBrushItem *pBrushItem, *pLineBrush = pParentBrush;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, FALSE,
+ &pItem ) )
+ {
+ pLineBrush = (const SvxBrushItem *)pItem;
+
+ // Wenn die Zeile die gesamte Tabelle umspannt, koennen
+ // Wir den Hintergrund an der Zeile ausgeben. Sonst muessen
+ // wir in an den Zelle ausgeben.
+ BOOL bOutAtRow = !nParentLineWidth;
+ if( !bOutAtRow && nStartCPos==0 )
+ {
+ USHORT nEndCol;
+ SwWriteTableCol aCol( nParentLineWidth );
+ bOutAtRow = aCols.Seek_Entry(&aCol,&nEndCol) &&
+ nEndCol == aCols.Count()-1;
+ }
+ if( bOutAtRow )
+ {
+ pRow->SetBackground( pLineBrush );
+ pBrushItem = 0;
+ }
+ else
+ pBrushItem = pLineBrush;
+ }
+ else
+ {
+ pRow->SetBackground( pLineBrush );
+ pBrushItem = 0;
+ }
+
+ USHORT nBoxes = rBoxes.Count();
+ USHORT nCPos = nStartCPos;
+ USHORT nCol = nStartCol;
+
+ for( USHORT nBox=0; nBox<nBoxes; nBox++ )
+ {
+ const SwTableBox *pBox = rBoxes[nBox];
+
+ // Position der letzten ueberdeckten Spalte ermitteln
+ USHORT nOldCPos = nCPos;
+ if( nBox < nBoxes-1 || (nParentLineWidth==0 && nLine==0) )
+ {
+ nCPos += (USHORT)GetBoxWidth( pBox );
+ if( nBox==nBoxes-1 )
+ nParentLineWidth = nCPos - nStartCPos;
+ }
+ else
+ nCPos = nStartCPos + nParentLineWidth;
+
+ // Und ihren Index
+ USHORT nOldCol = nCol;
+ SwWriteTableCol aCol( nCPos );
+ BOOL bFound = aCols.Seek_Entry( &aCol, &nCol );
+ ASSERT( bFound, "Wo ist die Spalte geblieben?" );
+
+ if( !ShouldExpandSub( pBox, bSubExpanded, nDepth ) )
+ {
+ USHORT nRowSpan = nRow - nOldRow + 1;
+ USHORT nColSpan = nCol - nOldCol + 1;
+ pRow->AddCell( pBox, nOldRow, nOldCol,
+ nRowSpan, nColSpan, nHeight,
+ pBrushItem );
+ nHeight = 0; // Die Hoehe braucht nur einmal geschieben werden
+
+ if( pBox->GetSttNd() )
+ {
+ // Wegen OS/2 schon hier, sonst gibt es einen
+ // Optimierungs-Fehler!!!!
+ SwWriteTableCol *pCol = aCols[nOldCol];
+
+ USHORT nTopBorder = USHRT_MAX, nBottomBorder = USHRT_MAX;
+ USHORT nBorderMask = MergeBoxBorders( pBox, nOldRow, nOldCol,
+ nRowSpan, nColSpan,
+ nTopBorder,
+ nBottomBorder );
+
+ if( !(nBorderMask & 4) )
+ pCol->bLeftBorder = FALSE;
+
+ pCol = aCols[nCol];
+ if( !(nBorderMask & 8) )
+ pCol->bRightBorder = FALSE;
+
+ if( !(nBorderMask & 1) )
+ pRow->bTopBorder = FALSE;
+ else if( !pRow->nTopBorder || nTopBorder < pRow->nTopBorder )
+ pRow->nTopBorder = nTopBorder;
+
+ if( !(nBorderMask & 2) )
+ pEndRow->bBottomBorder = FALSE;
+ else if( !pEndRow->nBottomBorder ||
+ nBottomBorder < pEndRow->nBottomBorder )
+ pEndRow->nBottomBorder = nBottomBorder;
+ }
+ else
+ {
+ aCols[nOldCol]->bLeftBorder = FALSE;
+ aCols[nCol]->bRightBorder = FALSE;
+ pRow->bTopBorder = FALSE;
+ pEndRow->bBottomBorder = FALSE;
+ }
+ }
+ else
+ {
+ FillTableRowsCols( nOldRPos, nOldRow, nOldCPos, nOldCol,
+ nRPos-nOldRPos, nCPos-nOldCPos,
+ pBox->GetTabLines(),
+ pLineBrush, nDepth-1 );
+ bSubExpanded = TRUE;
+ }
+
+ nCol++; // Die naechste Zelle faengt in der nachten Spalte an
+ }
+
+ nRow++;
+ }
+}
+
+SwWriteTable::SwWriteTable( const SwTableLines& rLines, long nWidth,
+ USHORT nBWidth, BOOL bRel, USHORT nMaxDepth,
+ USHORT nLSub, USHORT nRSub )
+ : nBorderColor( (UINT32)-1 ),
+ nBorder( 0 ),
+ nInnerBorder( 0 ),
+ nCellPadding( 0 ),
+ nCellSpacing( 0 ),
+ nTabWidth( nWidth ),
+ nBaseWidth( nBWidth ),
+ nLeftSub( nLSub ), nRightSub( nRSub ),
+ bRelWidths( bRel ),
+ bUseLayoutHeights( TRUE ),
+#ifndef PRODUCT
+ bGetLineHeightCalled( FALSE ),
+#endif
+ nHeadEndRow( USHRT_MAX ),
+ bColsOption( FALSE ),
+ bColTags( TRUE ),
+ bLayoutExport( FALSE ),
+ bCollectBorderWidth( TRUE )
+{
+ USHORT nParentWidth = nBaseWidth + nLeftSub + nRightSub;
+
+ // Erstmal die Tabellen-Struktur festlegen. Hinter der Tabelle ist in
+ // jedem Fall eine Spalte zu Ende
+ SwWriteTableCol *pCol = new SwWriteTableCol( nParentWidth );
+ aCols.Insert( pCol );
+ CollectTableRowsCols( 0, 0, 0, nParentWidth, rLines, nMaxDepth - 1 );
+
+ // Und jetzt mit leben fuellen
+ FillTableRowsCols( 0, 0, 0, 0, 0, nParentWidth, rLines, 0, nMaxDepth - 1 );
+
+ // Einige Twip-Werte an Pixel-Grenzen anpassen
+ if( !nBorder )
+ nBorder = nInnerBorder;
+}
+
+
+
+SwWriteTable::SwWriteTable( const SwHTMLTableLayout *pLayoutInfo )
+ : nBorderColor( (UINT32)-1 ),
+ nBorder( 0 ),
+ nInnerBorder( 0 ),
+ nCellPadding( 0 ),
+ nCellSpacing( 0 ),
+ nTabWidth( pLayoutInfo->GetWidthOption() ),
+ nBaseWidth( pLayoutInfo->GetWidthOption() ),
+ nLeftSub( 0 ), nRightSub( 0 ),
+ bRelWidths( pLayoutInfo->HasPrcWidthOption() ),
+ bUseLayoutHeights( FALSE ),
+#ifndef PRODUCT
+ bGetLineHeightCalled( FALSE ),
+#endif
+ nHeadEndRow( 0 ),
+ bColsOption( pLayoutInfo->HasColsOption() ),
+ bColTags( pLayoutInfo->HasColTags() ),
+ bLayoutExport( TRUE ),
+ bCollectBorderWidth( pLayoutInfo->HaveBordersChanged() )
+{
+ if( !bCollectBorderWidth )
+ {
+ nBorder = pLayoutInfo->GetBorder();
+ nCellPadding = pLayoutInfo->GetCellPadding();
+ nCellSpacing = pLayoutInfo->GetCellSpacing();
+ }
+
+ USHORT nRow, nCol;
+ USHORT nCols = pLayoutInfo->GetColCount();
+ USHORT nRows = pLayoutInfo->GetRowCount();
+
+ // Erstmal die Tabellen-Struktur festlegen.
+ for( nCol=0; nCol<nCols; nCol++ )
+ {
+ SwWriteTableCol *pCol =
+ new SwWriteTableCol( (nCol+1)*COL_DFLT_WIDTH );
+
+ if( bColTags )
+ {
+ const SwHTMLTableLayoutColumn *pLayoutCol =
+ pLayoutInfo->GetColumn( nCol );
+ pCol->SetWidthOpt( pLayoutCol->GetWidthOption(),
+ pLayoutCol->IsRelWidthOption() );
+ }
+
+ aCols.Insert( pCol );
+ }
+
+ for( nRow=0; nRow<nRows; nRow++ )
+ {
+ SwWriteTableRow *pRow =
+ new SwWriteTableRow( (nRow+1)*ROW_DFLT_HEIGHT );
+ pRow->nTopBorder = 0;
+ pRow->nBottomBorder = 0;
+ aRows.Insert( pRow );
+ }
+
+ // Und jetzt mit leben fuellen
+ for( nRow=0; nRow<nRows; nRow++ )
+ {
+ SwWriteTableRow *pRow = aRows[nRow];
+
+ BOOL bHeightExported = FALSE;
+ for( nCol=0; nCol<nCols; nCol++ )
+ {
+ const SwHTMLTableLayoutCell *pLayoutCell =
+ pLayoutInfo->GetCell( nRow, nCol );
+
+ const SwHTMLTableLayoutCnts *pLayoutCnts =
+ pLayoutCell->GetContents();
+
+ // Beginnt die Zelle eigentlich eine Zeile weiter oben oder
+ // weiter vorne?
+ if( ( nRow>0 && pLayoutCnts == pLayoutInfo->GetCell(nRow-1,nCol)
+ ->GetContents() ) ||
+ ( nCol>0 && pLayoutCnts == pLayoutInfo->GetCell(nRow,nCol-1)
+ ->GetContents() ) )
+ {
+ continue;
+ }
+
+ USHORT nRowSpan = pLayoutCell->GetRowSpan();
+ USHORT nColSpan = pLayoutCell->GetColSpan();
+ const SwTableBox *pBox = pLayoutCnts->GetTableBox();
+ ASSERT( pBox,
+ "Tabelle in Tabelle kann nicht ueber Layout exportiert werden" );
+
+ long nHeight = bHeightExported ? 0 : GetLineHeight( pBox );
+ const SvxBrushItem *pBrushItem = GetLineBrush( pBox, pRow );
+
+ SwWriteTableCell *pCell =
+ pRow->AddCell( pBox, nRow, nCol, nRowSpan, nColSpan,
+ nHeight, pBrushItem );
+ pCell->SetWidthOpt( pLayoutCell->GetWidthOption(),
+ pLayoutCell->IsPrcWidthOption() );
+
+ USHORT nTopBorder = USHRT_MAX, nBottomBorder = USHRT_MAX;
+ USHORT nBorderMask =
+ MergeBoxBorders( pBox, nRow, nCol, nRowSpan, nColSpan,
+ nTopBorder, nBottomBorder );
+
+ SwWriteTableCol *pCol = aCols[nCol];
+ if( !(nBorderMask & 4) )
+ pCol->bLeftBorder = FALSE;
+
+ pCol = aCols[nCol+nColSpan-1];
+ if( !(nBorderMask & 8) )
+ pCol->bRightBorder = FALSE;
+
+ if( !(nBorderMask & 1) )
+ pRow->bTopBorder = FALSE;
+
+ SwWriteTableRow *pEndRow = aRows[nRow+nRowSpan-1];
+ if( !(nBorderMask & 2) )
+ pEndRow->bBottomBorder = FALSE;
+
+ // Die Hoehe braucht nur einmal geschieben werden
+ if( nHeight )
+ bHeightExported = TRUE;
+ }
+ }
+
+ // Einige Twip-Werte an Pixel-Grenzen anpassen
+ if( bCollectBorderWidth && !nBorder )
+ nBorder = nInnerBorder;
+}
+
+
+
+/*************************************************************************
+
+ Source Code Control System - Header
+
+ $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/filter/writer/wrtswtbl.cxx,v 1.1.1.1 2000-09-18 17:14:57 hr Exp $
+
+ Source Code Control System - Update
+
+ $Log: not supported by cvs2svn $
+ Revision 1.3 2000/09/18 16:04:55 willem.vandorp
+ OpenOffice header added.
+
+ Revision 1.2 2000/03/03 15:22:02 os
+ StarView remainders removed
+
+ Revision 1.1 1999/10/29 17:38:03 jp
+ class for build a '2D-Table' from a SwTable
+
+
+*************************************************************************/
+