summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Martens <ama@openoffice.org>2001-05-29 11:41:34 +0000
committerAndreas Martens <ama@openoffice.org>2001-05-29 11:41:34 +0000
commit2e8783d6c38eaf367c39ee2ee6c20fa2d4f23662 (patch)
tree5fada10d0b3fd45111e78da056fddc4396cffd0c
parent9ffefe939f98b7f571c56637c2e9e7e1fce14a06 (diff)
Fix #87530#: Save/load layout cache information
-rw-r--r--sw/source/core/doc/docnew.cxx31
-rw-r--r--sw/source/core/inc/laycache.hxx106
-rw-r--r--sw/source/core/layout/calcmove.cxx6
-rw-r--r--sw/source/core/layout/frmtool.cxx387
-rw-r--r--sw/source/core/layout/laycache.cxx1039
-rw-r--r--sw/source/core/layout/layhelp.hxx233
-rw-r--r--sw/source/core/layout/makefile.mk6
7 files changed, 1486 insertions, 322 deletions
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 4918f5fe3ea0..fc400c614870 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: docnew.cxx,v $
*
- * $Revision: 1.14 $
+ * $Revision: 1.15 $
*
- * last change: $Author: mtg $ $Date: 2001-05-11 18:35:50 $
+ * last change: $Author: ama $ $Date: 2001-05-29 12:32:09 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -217,6 +217,9 @@
#ifndef _BREAKIT_HXX
#include <breakit.hxx>
#endif
+#ifndef _LAYCACHE_HXX
+#include <laycache.hxx>
+#endif
#ifndef _MVSAVE_HXX
#include <mvsave.hxx>
#endif
@@ -629,6 +632,7 @@ SwDoc::~SwDoc()
delete pColumnContFmt;
delete pDfltCharFmt;
delete pDfltFrmFmt;
+ delete pLayoutCache;
}
@@ -976,3 +980,26 @@ void SwDoc::ClearForbiddenCharacters( USHORT nLang )
}
}
+/*-----------------28.5.2001 10:06------------------
+ * SwDoc:
+ * Reading and writing of the layout cache.
+ *--------------------------------------------------*/
+
+void SwDoc::ReadLayoutCache( SvStream& rStream )
+{
+ if( !pLayoutCache )
+ pLayoutCache = new SwLayoutCache();
+ if( !pLayoutCache->IsLocked() )
+ {
+ pLayoutCache->GetLockCount() |= 0x8000;
+ pLayoutCache->Read( rStream );
+ pLayoutCache->GetLockCount() &= 0x7fff;
+ }
+}
+
+void SwDoc::WriteLayoutCache( SvStream& rStream )
+{
+ pLayoutCache->Write( rStream, *this );
+}
+
+
diff --git a/sw/source/core/inc/laycache.hxx b/sw/source/core/inc/laycache.hxx
new file mode 100644
index 000000000000..ab3f5a81f12f
--- /dev/null
+++ b/sw/source/core/inc/laycache.hxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * $RCSfile: laycache.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: ama $ $Date: 2001-05-29 12:41:34 $
+ *
+ * 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): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _LAYCACHE_HXX
+#define _LAYCACHE_HXX
+
+
+class SwDoc;
+class SwLayCacheImpl;
+
+/*************************************************************************
+ * class SwLayoutCache
+ *
+ * This class allows to save layout information in the file and it contains
+ * this information after loading of a file.
+ * Call Write(..) with a stream and the document to save and the page break
+ * information of the document will be written.
+ * Call Read(..) with a stream and the member pLayCacheImpl will
+ * read the information from the stream and store it in an internal structur.
+ * There's a simple locking mechanism at these classes,
+ * if somebody reads the information, he increments the lock count by 1,
+ * during the Read(..) function the lock count will set to $8000.
+ *
+ **************************************************************************/
+
+class SwLayoutCache
+{
+ SwLayCacheImpl *pImpl;
+ USHORT nLockCount;
+public:
+ SwLayoutCache() : pImpl( NULL ), nLockCount( 0 ) {}
+ ~SwLayoutCache();
+
+ void Read( SvStream &rStream );
+ void Write( SvStream &rStream, const SwDoc& rDoc );
+
+ void ClearImpl();
+ sal_Bool IsLocked() const { return nLockCount > 0; }
+ USHORT& GetLockCount() { return nLockCount; }
+ SwLayCacheImpl *LockImpl()
+ { if( nLockCount & 0x8000 ) return NULL; ++nLockCount; return pImpl; }
+ void UnlockImpl() { --nLockCount; }
+
+#ifndef PRODUCT
+ sal_Bool CompareLayout( const SwDoc& rDoc ) const;
+#endif
+};
+
+#endif
diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx
index dab5f7d59f14..d1b2222eb999 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: calcmove.cxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: ama $ $Date: 2000-12-06 12:27:40 $
+ * last change: $Author: ama $ $Date: 2001-05-29 12:33:12 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -176,8 +176,6 @@ BOOL SwCntntFrm::ShouldBwdMoved( SwLayoutFrm *pNewUpper, BOOL, BOOL & )
const SwFrm *pPrevFrm = pNewUpper->Lower();
while ( pPrevFrm )
{
- if( !pPrevFrm->GetNext() && !pPrevFrm->IsValid() )
- return TRUE;
aRect.Top( pPrevFrm->Frm().Bottom() );
pPrevFrm = pPrevFrm->GetNext();
}
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index dbfd89dca3f3..999397f60059 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: frmtool.cxx,v $
*
- * $Revision: 1.7 $
+ * $Revision: 1.8 $
*
- * last change: $Author: ama $ $Date: 2001-05-11 09:50:35 $
+ * last change: $Author: ama $ $Date: 2001-05-29 12:37:16 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -85,15 +85,9 @@
#ifndef _SVX_BRSHITEM_HXX //autogen
#include <svx/brshitem.hxx>
#endif
-#ifndef _SVX_BRKITEM_HXX //autogen
-#include <svx/brkitem.hxx>
-#endif
#ifndef _SVX_KEEPITEM_HXX //autogen
#include <svx/keepitem.hxx>
#endif
-#ifndef _SVX_SIZEITEM_HXX //autogen
-#include <svx/sizeitem.hxx>
-#endif
#ifndef _SVX_SHADITEM_HXX //autogen
#include <svx/shaditem.hxx>
#endif
@@ -117,15 +111,6 @@
#ifndef _FMTANCHR_HXX //autogen
#include <fmtanchr.hxx>
#endif
-#ifndef _FMTPDSC_HXX //autogen
-#include <fmtpdsc.hxx>
-#endif
-#ifndef _FMTPDSC_HXX //autogen
-#include <fmtpdsc.hxx>
-#endif
-#ifndef _FMTPDSC_HXX //autogen
-#include <fmtpdsc.hxx>
-#endif
#ifndef _FMTHDFT_HXX //autogen
#include <fmthdft.hxx>
#endif
@@ -135,12 +120,6 @@
#ifndef _FMTFSIZE_HXX //autogen
#include <fmtfsize.hxx>
#endif
-#ifndef _FMTCNCT_HXX //autogen
-#include <fmtcnct.hxx>
-#endif
-#ifndef _DOCSTAT_HXX //autogen
-#include <docstat.hxx>
-#endif
#ifndef _DOCARY_HXX
#include <docary.hxx>
#endif
@@ -150,11 +129,8 @@
#ifndef _SWMODULE_HXX
#include <swmodule.hxx>
#endif
-#include "rootfrm.hxx"
#include "pagefrm.hxx"
-#include "cntfrm.hxx"
#include "colfrm.hxx"
-#include "flyfrm.hxx"
#include "doc.hxx"
#include "fesh.hxx"
#include "viewimp.hxx"
@@ -163,8 +139,6 @@
#include "dcontact.hxx"
#include "frmtool.hxx"
#include "docsh.hxx"
-#include "swtable.hxx"
-#include "errhdl.hxx"
#include "tabfrm.hxx"
#include "rowfrm.hxx"
#include "ftnfrm.hxx"
@@ -179,7 +153,12 @@
#include "node2lay.hxx"
#include "ndole.hxx"
#include "ndtxt.hxx"
-#include "fmtclds.hxx" // SwFmtCol
+#ifndef _LAYHELP_HXX
+#include <layhelp.hxx>
+#endif
+#ifndef _LAYCACHE_HXX
+#include <laycache.hxx>
+#endif
#include "mdiexp.hxx"
#include "statstr.hrc"
@@ -194,6 +173,8 @@ FASTBOOL bSetCompletePaintOnInvalidate = FALSE;
BYTE StackHack::nCnt = 0;
BOOL StackHack::bLocked = FALSE;
+
+
/*************************************************************************
|*
|* SwFrmNotify::SwFrmNotify()
@@ -1026,111 +1007,6 @@ void AppendAllObjs( const SwSpzFrmFmts *pTbl )
aCpy.Remove( 0, aCpy.Count() );
}
-BOOL MA_FASTCALL lcl_CheckInsertPage( SwFrm *pFrm, SwPageFrm *&rpPage,
- SwLayoutFrm *&rpLay,
- ULONG nParagraphCnt,
- ULONG nMaxParaPerPage, BOOL &rbBreakAfter )
-{
- FASTBOOL bEnd = 0 == rpPage->GetNext();
- const SwAttrSet *pAttr = pFrm->GetAttrSet();
- const SvxFmtBreakItem &rBrk = pAttr->GetBreak();
- const SwFmtPageDesc &rDesc = pAttr->GetPageDesc();
- const SwPageDesc *pDesc = rDesc.GetPageDesc();
-
- BOOL bBrk = nParagraphCnt > nMaxParaPerPage || rbBreakAfter;
- rbBreakAfter = rBrk.GetBreak() == SVX_BREAK_PAGE_AFTER ||
- rBrk.GetBreak() == SVX_BREAK_PAGE_BOTH;
- if ( !bBrk )
- bBrk = rBrk.GetBreak() == SVX_BREAK_PAGE_BEFORE ||
- rBrk.GetBreak() == SVX_BREAK_PAGE_BOTH;
-
- if ( bBrk || pDesc )
- {
- USHORT nPgNum = 0;
- if ( !pDesc )
- pDesc = rpPage->GetPageDesc()->GetFollow();
- else
- {
- if ( 0 != (nPgNum = rDesc.GetNumOffset()) )
- ((SwRootFrm*)rpPage->GetUpper())->SetVirtPageNum(TRUE);
- }
- BOOL bOdd = !rpPage->OnRightPage();
- BOOL bInsertEmpty = FALSE;
- if( nPgNum && bOdd != ( ( nPgNum % 2 ) != 0 ) )
- {
- bOdd = !bOdd;
- bInsertEmpty = TRUE;
- }
- ::InsertNewPage( (SwPageDesc&)*pDesc, rpPage->GetUpper(),
- bOdd, bInsertEmpty, FALSE, rpPage->GetNext() );
- if ( bEnd )
- {
- ASSERT( rpPage->GetNext(), "Keine neue Seite?" );
- do
- { rpPage = (SwPageFrm*)rpPage->GetNext();
- } while ( rpPage->GetNext() );
- }
- else
- {
- ASSERT( rpPage->GetNext(), "Keine neue Seite?" );
- rpPage = (SwPageFrm*)rpPage->GetNext();
- if ( rpPage->IsEmptyPage() )
- {
- ASSERT( rpPage->GetNext(), "Keine neue Seite?" );
- rpPage = (SwPageFrm*)rpPage->GetNext();
- }
- }
- rpLay = rpPage->FindBodyCont();
- while( rpLay->Lower() )
- rpLay = (SwLayoutFrm*)rpLay->Lower();
- return TRUE;
- }
- return FALSE;
-}
-
-//Solange eine Section "offen" ist ist im InsertCnt ein Pointer auf die
-//Hilfsklasse SwActualSection vorhanden.
-//Bei Seitenumbruchen wird fuer "offene" Sections entsprechend ein Follow
-//erzeugt.
-//Da Bereiche ineinander verschachtelt sein koennen, sich aber wiederum im
-//Layout nicht ineinander verschachteln, hat die Klasse eine Pointer auf ihren
-//Upper wenn eine "innere" Section notwendig ist. Wenn diese abgeschlossen ist
-//wird einfach wieder der "Upper" weiterverwendet (im Layout muss dafuer
-//natuerlich wieder ein entsprechender Frame erzeugt werden.
-
-//!!Nicht fuer im Layout verschachtelte Bereiche funktionsfaehig.
-
-class SwActualSection
-{
- SwActualSection *pUpper;
- SwSectionFrm *pSectFrm;
- SwSectionNode *pSectNode;
-public:
- SwActualSection( SwActualSection *pUpper,
- SwSectionFrm *pSect,
- SwSectionNode *pNd );
-
- SwSectionFrm *GetSectionFrm() { return pSectFrm; }
- void SetSectionFrm( SwSectionFrm *p ) { pSectFrm = p; }
- SwSectionNode *GetSectionNode() { return pSectNode;}
- SwActualSection *GetUpper() { return pUpper; }
-};
-
-SwActualSection::SwActualSection( SwActualSection *pUp,
- SwSectionFrm *pSect,
- SwSectionNode *pNd ) :
- pUpper( pUp ),
- pSectFrm( pSect ),
- pSectNode( pNd )
-{
- if ( !pSectNode )
- {
- const SwNodeIndex *pIndex = pSect->GetFmt()->GetCntnt().GetCntntIdx();
- pSectNode = pSect->GetFmt()->GetDoc()->GetNodes()[*pIndex]->
- FindSectionNode();
- }
-}
-
void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
ULONG nIndex, BOOL bPages, ULONG nEndIndex,
SwFrm *pPrv )
@@ -1154,76 +1030,44 @@ void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
//Wenn in der DocStatistik eine brauchebare Seitenzahl angegeben ist
//(wird beim Schreiben gepflegt), so wird von dieser Seitenanzahl
//ausgegengen.
- ULONG nMaxParaPerPage = 25;
- ULONG nPgCount;
BOOL bStartPercent = bPages && !nEndIndex &&
- !SfxProgress::GetActiveProgress() &&
- !SfxProgress::GetActiveProgress( pDoc->GetDocShell() );
- if ( bStartPercent )
- {
- nPgCount = pDoc->GetDocStat().nPage;
- if ( nPgCount <= 10 ) //darunter machen wir es nicht.
- nPgCount = 0;
- ULONG nNdCount = pDoc->GetDocStat().nPara;
- if ( nNdCount <= 1 )
- {
- //Anzahl der Absaetze schaetzen.
- ULONG nTmp = pDoc->GetNodes().GetEndOfContent().GetIndex() -
- pDoc->GetNodes().GetEndOfExtras().GetIndex();
- //Fuer Die Tabellen ziehen wir einiges wg. der Start-/EndNodes ab.
- nTmp -= pDoc->GetTblFrmFmts()->Count() * 25;
- //Fuer die Rahmen ziehen auch nocheinmal etwa 5 Absaetze ab.
- nTmp -= (pDoc->GetNodes().GetEndOfAutotext().GetIndex() -
- pDoc->GetNodes().GetEndOfInserts().GetIndex()) / 3 * 5;
- if ( nTmp > 0 )
- nNdCount = nTmp;
- }
- if ( nNdCount < 1000 )
- bStartPercent = FALSE;
- if ( nNdCount > 100 ) //darunter machen wir es nicht
- {
- if ( nPgCount > 0 )
- nMaxParaPerPage = nNdCount / nPgCount;
- else
- {
- nMaxParaPerPage = Max( ULONG(20),
- ULONG(20 + nNdCount / 1000 * 3) );
- //Standard ASCII-Leerzeilen
-#ifdef PM2
- const ULONG nMax = 49;
-#elif MAC
- const ULONG nMax = 56;
-#elif UNIX
- const ULONG nMax = 57;
-#else
- const ULONG nMax = 53;
-#endif
- nMaxParaPerPage = Min( nMaxParaPerPage, nMax );
- nPgCount = nNdCount / nMaxParaPerPage;
- }
- if ( pDoc->IsBrowseMode() )
- nMaxParaPerPage *= 6;
- }
- }
+ !SfxProgress::GetActiveProgress() &&
+ !SfxProgress::GetActiveProgress( pDoc->GetDocShell() );
+
+ SwPageFrm *pPage = pLay->FindPageFrm();
+ const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
+ SwFrm *pFrm = 0;
+ BOOL bBreakAfter = FALSE;
+
+ SwActualSection *pActualSection = 0;
+ SwLayHelper *pPageMaker;
//Wenn das Layout erzeugt wird (bPages == TRUE) steuern wir den Progress
//an. Flys und DrawObjekte werden dann nicht gleich verbunden, dies
//passiert erst am Ende der Funktion.
- if ( bPages && bStartPercent )
+ if ( bPages )
{
- ::StartProgress( STR_STATSTR_LAYOUTINIT, 1, nPgCount, pDoc->GetDocShell());
- bObjsDirect = FALSE;
+ // Attention: the SwLayHelper class uses references to the content-,
+ // page-, layout-frame etc. and may change them!
+ pPageMaker = new SwLayHelper( pDoc, pFrm, pPrv, pPage, pLay,
+ pActualSection, bBreakAfter, nIndex, 0 == nEndIndex );
+ if( bStartPercent )
+ {
+ ULONG nPageCount = pPageMaker->CalcPageCount();
+ if( nPageCount )
+ {
+ ::StartProgress( STR_STATSTR_LAYOUTINIT, 1, nPageCount,
+ pDoc->GetDocShell());
+ bObjsDirect = FALSE;
+ }
+ else
+ bStartPercent = FALSE;
+ }
}
+ else
+ pPageMaker = NULL;
- SwPageFrm *pPage = pLay->FindPageFrm();
- const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
- SwFrm *pFrm = 0;
- USHORT nParagraphCnt = 0;
- BOOL bBreakAfter = FALSE;
- BOOL bFirst = TRUE;
-
- SwActualSection *pActualSection = 0; //Siehe Dokumentation oben bei der
- if( pLay->IsInSct() && //Klassendefinition
+ if( pLay->IsInSct() &&
( pLay->IsSctFrm() || pLay->GetUpper() ) ) // Hierdurch werden Frischlinge
// abgefangen, deren Flags noch nicht ermittelt werden koennen,
// so z.B. beim Einfuegen einer Tabelle
@@ -1245,6 +1089,12 @@ void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
}
}
+ //If a section is "open", the pActualSection points to an SwActualSection.
+ //If the page breaks, for "open" sections a follow will created.
+ //For nested sections (which have, however, not a nested layout),
+ //the SwActualSection class has a member, which points to an upper(section).
+ //When the "inner" section finishs, the upper will used instead.
+
while( TRUE )
{
SwNode *pNd = pDoc->GetNodes()[nIndex];
@@ -1253,61 +1103,10 @@ void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
SwCntntNode* pNode = (SwCntntNode*)pNd;
pFrm = pNode->IsTxtNode() ? new SwTxtFrm( (SwTxtNode*)pNode ) :
pNode->MakeFrm();
- if ( bPages )
- {
- ++nParagraphCnt;
- if ( !bFirst || nEndIndex )
- {
- if ( bFirst )
- nParagraphCnt = USHRT_MAX;
+ if( pPageMaker && pPageMaker->CheckInsert( nIndex )
+ && bStartPercent )
+ ::SetProgressState( pPage->GetPhyPageNum(),pDoc->GetDocShell());
- if ( lcl_CheckInsertPage( pFrm, pPage, pLay, nParagraphCnt,
- nMaxParaPerPage, bBreakAfter ) )
- {
- pPrv = 0;
- nParagraphCnt = 0;
- if ( bPages && bStartPercent )
- ::SetProgressState( pPage->GetPhyPageNum(), pDoc->GetDocShell());
-
- if ( pActualSection )
- {
- //Hatte der SectionFrm ueberhaupt Inhalt? Wenn
- //nicht kann er gleich umgehaengt werden.
- SwFrm *pFrm;
- if ( !pActualSection->GetSectionFrm()->ContainsCntnt())
- {
- pFrm = pActualSection->GetSectionFrm();
- pFrm->Remove();
- }
- else
- {
- pFrm = new SwSectionFrm(
- *pActualSection->GetSectionFrm(), FALSE );
- pActualSection->GetSectionFrm()->SimpleFormat();
- pFrm->Frm().Width( pLay->Prt().Width() );
- pFrm->Prt().Width( pLay->Prt().Width() );
- if( ((SwSectionFrm*)pFrm)->Lower() &&
- ((SwSectionFrm*)pFrm)->Lower()->IsColumnFrm())
- {
- const SwFmtCol &rCol =
- ((SwSectionFrm*)pFrm)->GetFmt()->GetCol();
- ((SwSectionFrm*)pFrm)->AdjustColumns(
- &rCol, FALSE );
- }
- }
- pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
- pFrm->InsertBehind( pLay, 0 );
- pFrm->Frm().Pos() = pLay->Frm().Pos();
- pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
-
- pLay = (SwLayoutFrm*)pFrm;
- if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
- pLay = pLay->GetNextLayoutLeaf();
- }
- }
- }
- bFirst = FALSE;
- }
pFrm->InsertBehind( pLay, pPrv );
pFrm->Frm().Pos() = pLay->Frm().Pos();
pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
@@ -1321,66 +1120,9 @@ void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
SwTableNode *pTblNode = (SwTableNode*)pNd;
pFrm = pTblNode->MakeFrm();
- if ( bPages )
- {
- //Fuer die Seiten zaehlt jede Zeile als ein Absatz.
- SwFrm *pLow = ((SwTabFrm*)pFrm)->Lower();
- do
- { ++nParagraphCnt;
- pLow = pLow->GetNext();
- } while ( pLow );
-
- if ( !bFirst || nEndIndex )
- {
- if ( bFirst )
- nParagraphCnt = USHRT_MAX;
-
- if ( lcl_CheckInsertPage( pFrm, pPage, pLay, nParagraphCnt,
- nMaxParaPerPage, bBreakAfter ) )
- {
- pPrv = 0;
- nParagraphCnt = 0;
- if ( bPages && bStartPercent )
- ::SetProgressState( pPage->GetPhyPageNum(), pDoc->GetDocShell());
-
- if ( pActualSection )
- {
- //Hatte der SectionFrm ueberhaupt Inhalt? Wenn
- //nicht kann er gleich umgehaengt werden.
- SwFrm *pFrm;
- if ( !pActualSection->GetSectionFrm()->ContainsCntnt())
- {
- pFrm = pActualSection->GetSectionFrm();
- pFrm->Remove();
- }
- else
- {
- pFrm = new SwSectionFrm(
- *pActualSection->GetSectionFrm(), FALSE );
- pActualSection->GetSectionFrm()->SimpleFormat();
- pFrm->Frm().Width( pLay->Prt().Width() );
- pFrm->Prt().Width( pLay->Prt().Width() );
- if( ((SwSectionFrm*)pFrm)->Lower() &&
- ((SwSectionFrm*)pFrm)->Lower()->IsColumnFrm())
- {
- const SwFmtCol &rCol =
- ((SwSectionFrm*)pFrm)->GetFmt()->GetCol();
- ((SwSectionFrm*)pFrm)->AdjustColumns(
- &rCol, FALSE );
- }
- }
- pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
- pFrm->InsertBehind( pLay, 0 );
- pFrm->Frm().Pos() = pLay->Frm().Pos();
- pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
-
- pLay = (SwLayoutFrm*)pFrm;
- if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
- pLay = pLay->GetNextLayoutLeaf();
- }
- }
- }
- }
+ if( pPageMaker && pPageMaker->CheckInsert( nIndex )
+ && bStartPercent )
+ ::SetProgressState( pPage->GetPhyPageNum(),pDoc->GetDocShell());
pFrm->InsertBehind( pLay, pPrv );
if ( bObjsDirect && pTbl->Count() )
@@ -1540,6 +1282,20 @@ void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
::EndProgress( pDoc->GetDocShell() );
}
+ if( pPageMaker )
+ {
+ delete pPageMaker;
+ if( pDoc->GetLayoutCache() )
+ {
+#ifndef PRODUCT
+#ifdef DEBUG
+ pDoc->GetLayoutCache()->CompareLayout( *pDoc );
+#endif
+#endif
+ pDoc->GetLayoutCache()->ClearImpl();
+ }
+ }
+
if ( bOldIdle )
pDoc->StartIdleTimer();
pDoc->GetRootFrm()->SetCallbackActionEnabled( bOldCallbackActionEnabled );
@@ -1561,9 +1317,6 @@ void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
SwFrm* pFrm;
while( 0 != (pFrm = aNode2Layout.NextFrm()) )
{
- //Fuer klare Verhaeltnisse sorgen. Wenn ein Prev da ist
- //alle Nachfolger von diesem auf die folgenden Seite
- //schieben
SwLayoutFrm *pUpper = pFrm->GetUpper();
SwFtnFrm* pFtnFrm = pUpper->FindFtnFrm();
BOOL bOldLock, bOldFtn;
@@ -1587,11 +1340,15 @@ void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
}
else
bOldLock = TRUE;
+
+#ifndef PRODUCT
+#ifdef DEBUG
// Wenn pFrm sich nicht bewegen kann, koennen wir auch niemanden
// auf die naechste Seite schieben. Innerhalb eines Rahmens auch
// nicht ( in der 1. Spalte eines Rahmens waere pFrm Moveable()! )
// Auch in spaltigen Bereichen in Tabellen waere pFrm Moveable.
- if ( !pFrm->IsInFly() && pFrm->IsMoveable() &&
+ static BOOL bTest = FALSE;
+ if ( bTest && !pFrm->IsInFly() && pFrm->IsMoveable() &&
(!pFrm->IsInTab() || pFrm->IsTabFrm() ) )
{
SwFrm *pMove = pFrm;
@@ -1697,6 +1454,8 @@ void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
pFrm->IsInDocBody(), nEndIdx, pPrev );
}
else
+#endif
+#endif
{
BOOL bSplit;
SwFrm* pPrv = bApres ? pFrm : pFrm->GetPrev();
diff --git a/sw/source/core/layout/laycache.cxx b/sw/source/core/layout/laycache.cxx
new file mode 100644
index 000000000000..349a6f8ec3b1
--- /dev/null
+++ b/sw/source/core/layout/laycache.cxx
@@ -0,0 +1,1039 @@
+/*************************************************************************
+ *
+ * $RCSfile: laycache.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: ama $ $Date: 2001-05-29 12:40:11 $
+ *
+ * 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 "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include <hintids.hxx>
+#ifndef _SVX_BRKITEM_HXX //autogen
+#include <svx/brkitem.hxx>
+#endif
+#ifndef _STREAM_HXX //autogen
+#include <tools/stream.hxx>
+#endif
+#ifndef _DOC_HXX
+#include <doc.hxx>
+#endif
+#ifndef _DOCSTAT_HXX //autogen
+#include <docstat.hxx>
+#endif
+#ifndef _DOCARY_HXX
+#include <docary.hxx>
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include <fmtpdsc.hxx>
+#endif
+#ifndef _LAYCACHE_HXX
+#include <laycache.hxx>
+#endif
+#ifndef _LAYHELP_HXX
+#include <layhelp.hxx>
+#endif
+#ifndef _PAGEFRM_HXX
+#include <pagefrm.hxx>
+#endif
+#ifndef _ROOTFRM_HXX
+#include <rootfrm.hxx>
+#endif
+#ifndef _TXTFRM_HXX
+#include <txtfrm.hxx>
+#endif
+#ifndef _NDTXT_HXX
+#include <ndtxt.hxx>
+#endif
+#ifndef _SWTABLE_HXX
+#include <swtable.hxx>
+#endif
+#ifndef _TABFRM_HXX
+#include <tabfrm.hxx>
+#endif
+#ifndef _ROWFRM_HXX
+#include <rowfrm.hxx>
+#endif
+#ifndef _COLFRM_HXX
+#include <colfrm.hxx>
+#endif
+#ifndef _BODYFRM_HXX
+#include <bodyfrm.hxx>
+#endif
+#ifndef _NODE_HXX //autogen
+#include <node.hxx>
+#endif
+#ifndef _NDINDEX_HXX
+#include <ndindex.hxx>
+#endif
+#ifndef _SECTFRM_HXX
+#include <sectfrm.hxx>
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include <frmfmt.hxx>
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include <fmtcntnt.hxx>
+#endif
+#ifndef _PAGEDESC_HXX
+#include <pagedesc.hxx>
+#endif
+#ifndef _FRMTOOL_HXX
+#include <frmtool.hxx>
+#endif
+
+/*-----------------28.5.2001 10:06------------------
+ * Reading and writing of the layout cache.
+ * The layout cache is not necessary, but it improves
+ * the performance and reduces the text flow during
+ * the formatting.
+ * The layout cache contains the index of the paragraphs/tables
+ * at the top of every page, so it's possible to create
+ * the right count of pages and to distribute the document content
+ * to this pages before the formatting starts.
+ *--------------------------------------------------*/
+
+void SwLayoutCache::Read( SvStream &rStream )
+{
+ if( !pImpl )
+ {
+ pImpl = new SwLayCacheImpl;
+ if( !pImpl->Read( rStream ) )
+ {
+ delete pImpl;
+ pImpl = 0;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void SwLayCacheImpl::Insert( USHORT nType, ULONG nIndex, xub_StrLen nOffset )
+{
+ aType.Insert( nType, aType.Count() );
+ SvULongs::Insert( nIndex, SvULongs::Count() );
+ aOffset.Insert( nOffset, aOffset.Count() );
+}
+
+BOOL SwLayCacheImpl::Read( SvStream& rStream )
+{
+ SwLayCacheIoImpl aIo( rStream, FALSE );
+ if( aIo.GetMajorVersion() > SW_LAYCACHE_IO_VERSION_MAJOR )
+ return FALSE;
+
+ BYTE cFlags;
+ UINT32 nIndex, nOffset;
+
+ aIo.OpenRec( SW_LAYCACHE_IO_REC_PAGES );
+ aIo.OpenFlagRec();
+ aIo.CloseFlagRec();
+ while( aIo.BytesLeft() && !aIo.HasError() )
+ {
+ switch( aIo.Peek() )
+ {
+ case SW_LAYCACHE_IO_REC_PARA:
+ aIo.OpenRec( SW_LAYCACHE_IO_REC_PARA );
+ cFlags = aIo.OpenFlagRec();
+ aIo.GetStream() >> nIndex;
+ if( (cFlags & 0x01) != 0 )
+ aIo.GetStream() >> nOffset;
+ else
+ nOffset = STRING_LEN;
+ aIo.CloseFlagRec();
+ Insert( SW_LAYCACHE_IO_REC_PARA, nIndex, (xub_StrLen)nOffset );
+ aIo.CloseRec( SW_LAYCACHE_IO_REC_PARA );
+ break;
+ case SW_LAYCACHE_IO_REC_TABLE:
+ aIo.OpenRec( SW_LAYCACHE_IO_REC_TABLE );
+ aIo.OpenFlagRec();
+ aIo.GetStream() >> nIndex
+ >> nOffset;
+ Insert( SW_LAYCACHE_IO_REC_TABLE, nIndex, (xub_StrLen)nOffset );
+ aIo.CloseFlagRec();
+ aIo.CloseRec( SW_LAYCACHE_IO_REC_TABLE );
+ break;
+ default:
+ aIo.SkipRec();
+ break;
+ }
+ }
+ aIo.CloseRec( SW_LAYCACHE_IO_REC_PAGES );
+
+ return !aIo.HasError();
+}
+
+/*-----------------28.5.2001 10:19------------------
+ * SwLayoutCache::Write(..)
+ * writes the index (more precise: the difference between
+ * the index and the first index of the document content)
+ * of the first paragraph/table at the top of every page.
+ * If at the top of a page is the rest of a paragraph/table
+ * from the bottom of the previous page, the character/row
+ * number is stored, too.
+ * --------------------------------------------------*/
+
+void SwLayoutCache::Write( SvStream &rStream, const SwDoc& rDoc )
+{
+ if( rDoc.GetRootFrm() ) // the layout itself ..
+ {
+ SwLayCacheIoImpl aIo( rStream, TRUE );
+ // We want to save the relative index, so we need the index
+ // of the first content
+ ULONG nStartOfContent = rDoc.GetNodes().GetEndOfContent().
+ FindStartNode()->GetIndex();
+ // The first page..
+ SwPageFrm* pPage = (SwPageFrm*)rDoc.GetRootFrm()->Lower();
+ //.. is not very interesting, cause it's clear that the first
+ // page starts with the first paragraph/table, do we get the
+ if( pPage ) // second page
+ pPage = (SwPageFrm*)pPage->GetNext();
+
+ aIo.OpenRec( SW_LAYCACHE_IO_REC_PAGES );
+ aIo.OpenFlagRec( 0, 0 );
+ aIo.CloseFlagRec();
+ while( pPage )
+ {
+ SwLayoutFrm* pLay = pPage->FindBodyCont();
+ SwFrm* pTmp = pLay ? pLay->ContainsAny() : NULL;
+ // We are only interested in paragraph or table frames,
+ // a section frames contains paragraphs/tables.
+ if( pTmp && pTmp->IsSctFrm() )
+ pTmp = ((SwSectionFrm*)pTmp)->ContainsAny();
+
+ if( pTmp ) // any content
+ {
+ if( pTmp->IsTxtFrm() )
+ {
+ ULONG nNdIdx = ((SwTxtFrm*)pTmp)->GetNode()->GetIndex();
+ if( nNdIdx > nStartOfContent )
+ {
+ /* Open Paragraph Record */
+ aIo.OpenRec( SW_LAYCACHE_IO_REC_PARA );
+ BOOL bFollow = ((SwTxtFrm*)pTmp)->IsFollow();
+ aIo.OpenFlagRec( bFollow ? 0x01 : 0x00,
+ bFollow ? 8 : 4 );
+ nNdIdx -= nStartOfContent;
+ aIo.GetStream() << nNdIdx;
+ if( bFollow )
+ aIo.GetStream() << (ULONG)((SwTxtFrm*)pTmp)->GetOfst();
+ aIo.CloseFlagRec();
+ /* Close Paragraph Record */
+ aIo.CloseRec( SW_LAYCACHE_IO_REC_PARA );
+ }
+ }
+ else if( pTmp->IsTabFrm() )
+ {
+ SwTabFrm* pTab = (SwTabFrm*)pTmp;
+ ULONG nOfst = STRING_LEN;
+ if( pTab->IsFollow() )
+ {
+ // If the table is a follow, we have to look for the
+ // master and to count all rows to get the row number
+ nOfst = 0;
+ while( pTab->IsFollow() )
+ pTab = pTab->FindMaster();
+ while( pTab != pTmp )
+ {
+ SwFrm* pSub = pTab->Lower();
+ while( pSub )
+ {
+ ++nOfst;
+ pSub = pSub->GetNext();
+ }
+ pTab = pTab->GetFollow();
+ ASSERT( pTab, "Table follow without master" );
+ }
+ }
+ do
+ {
+ ULONG nNdIdx =
+ pTab->GetTable()->GetTableNode()->GetIndex();
+ if( nNdIdx > nStartOfContent )
+ {
+ /* Open Table Record */
+ aIo.OpenRec( SW_LAYCACHE_IO_REC_TABLE );
+ aIo.OpenFlagRec( 0, 8 );
+ nNdIdx -= nStartOfContent;
+ aIo.GetStream() << nNdIdx
+ << nOfst;
+ aIo.CloseFlagRec();
+ /* Close Table Record */
+ aIo.CloseRec( SW_LAYCACHE_IO_REC_TABLE );
+ }
+ // If the table has a follow on the next page,
+ // we know already the row number and store this
+ // immediately.
+ if( pTab->GetFollow() )
+ {
+ if( nOfst == STRING_LEN )
+ nOfst = 0;
+ do
+ {
+ SwFrm* pSub = pTab->Lower();
+ while( pSub )
+ {
+ ++nOfst;
+ pSub = pSub->GetNext();
+ }
+ pTab = pTab->GetFollow();
+ SwPageFrm *pTabPage = pTab->FindPageFrm();
+ if( pTabPage != pPage )
+ {
+ ASSERT( pPage->GetPhyPageNum() <
+ pTabPage->GetPhyPageNum(),
+ "Looping Tableframes" );
+ pPage = pTabPage;
+ break;
+ }
+ } while ( pTab->GetFollow() );
+ }
+ else
+ break;
+ } while( pTab );
+ }
+ }
+ pPage = (SwPageFrm*)pPage->GetNext();
+ }
+ aIo.CloseRec( SW_LAYCACHE_IO_REC_PAGES );
+ }
+}
+
+#ifndef PRODUCT
+sal_Bool SwLayoutCache::CompareLayout( const SwDoc& rDoc ) const
+{
+ sal_Bool bRet = sal_True;
+ if( pImpl && rDoc.GetRootFrm() )
+ {
+ USHORT nIndex = 0;
+ ULONG nStartOfContent = rDoc.GetNodes().GetEndOfContent().
+ FindStartNode()->GetIndex();
+ SwPageFrm* pPage = (SwPageFrm*)rDoc.GetRootFrm()->Lower();
+ if( pPage )
+ pPage = (SwPageFrm*)pPage->GetNext();
+ while( pPage )
+ {
+ if( nIndex >= pImpl->Count() )
+ {
+ if( bRet )
+ bRet = sal_False;
+ break;
+ }
+ SwLayoutFrm* pLay = pPage->FindBodyCont();
+ SwFrm* pTmp = pLay ? pLay->ContainsAny() : NULL;
+ if( pTmp && pTmp->IsSctFrm() )
+ pTmp = ((SwSectionFrm*)pTmp)->ContainsAny();
+ if( pTmp )
+ {
+ if( pTmp->IsTxtFrm() )
+ {
+ ULONG nNdIdx = ((SwTxtFrm*)pTmp)->GetNode()->GetIndex();
+ if( nNdIdx > nStartOfContent )
+ {
+ BOOL bFollow = ((SwTxtFrm*)pTmp)->IsFollow();
+ nNdIdx -= nStartOfContent;
+ if( pImpl->GetBreakIndex( nIndex ) != nNdIdx ||
+ SW_LAYCACHE_IO_REC_PARA !=
+ pImpl->GetBreakType( nIndex ) ||
+ ( bFollow ? ((SwTxtFrm*)pTmp)->GetOfst()
+ : STRING_LEN ) != pImpl->GetBreakOfst( nIndex ) )
+ {
+ if( bRet )
+ bRet = sal_False;
+ }
+ ++nIndex;
+ }
+ }
+ else if( pTmp->IsTabFrm() )
+ {
+ SwTabFrm* pTab = (SwTabFrm*)pTmp;
+ ULONG nOfst = STRING_LEN;
+ if( pTab->IsFollow() )
+ {
+ nOfst = 0;
+ while( pTab->IsFollow() )
+ pTab = pTab->FindMaster();
+ while( pTab != pTmp )
+ {
+ SwFrm* pSub = pTab->Lower();
+ while( pSub )
+ {
+ ++nOfst;
+ pSub = pSub->GetNext();
+ }
+ pTab = pTab->GetFollow();
+ }
+ }
+ do
+ {
+ ULONG nNdIdx =
+ pTab->GetTable()->GetTableNode()->GetIndex();
+ if( nNdIdx > nStartOfContent )
+ {
+ nNdIdx -= nStartOfContent;
+ if( pImpl->GetBreakIndex( nIndex ) != nNdIdx ||
+ SW_LAYCACHE_IO_REC_TABLE !=
+ pImpl->GetBreakType( nIndex ) ||
+ nOfst != pImpl->GetBreakOfst( nIndex ) )
+ {
+ if( bRet )
+ bRet = sal_False;
+ }
+ ++nIndex;
+ }
+ if( pTab->GetFollow() )
+ {
+ if( nOfst == STRING_LEN )
+ nOfst = 0;
+ do
+ {
+ SwFrm* pSub = pTab->Lower();
+ while( pSub )
+ {
+ ++nOfst;
+ pSub = pSub->GetNext();
+ }
+ pTab = pTab->GetFollow();
+ SwPageFrm *pTabPage = pTab->FindPageFrm();
+ if( pTabPage != pPage )
+ {
+ pPage = pTabPage;
+ break;
+ }
+ } while ( pTab->GetFollow() );
+ }
+ else
+ break;
+ } while( pTab );
+ }
+ }
+ pPage = (SwPageFrm*)pPage->GetNext();
+ }
+ }
+ return bRet;
+}
+#endif
+
+void SwLayoutCache::ClearImpl()
+{
+ if( !IsLocked() )
+ {
+ delete pImpl;
+ pImpl = 0;
+ }
+}
+
+
+SwLayoutCache::~SwLayoutCache()
+{
+ ASSERT( !nLockCount, "Deleting a locked SwLayoutCache!?" );
+ delete pImpl;
+}
+
+/*-----------------28.5.2001 10:47------------------
+ * SwActualSection,
+ * a help class to create not nested section frames
+ * for nested sections.
+ * --------------------------------------------------*/
+
+SwActualSection::SwActualSection( SwActualSection *pUp,
+ SwSectionFrm *pSect,
+ SwSectionNode *pNd ) :
+ pUpper( pUp ),
+ pSectFrm( pSect ),
+ pSectNode( pNd )
+{
+ if ( !pSectNode )
+ {
+ const SwNodeIndex *pIndex = pSect->GetFmt()->GetCntnt().GetCntntIdx();
+ pSectNode = pSect->GetFmt()->GetDoc()->GetNodes()[*pIndex]->
+ FindSectionNode();
+ }
+}
+
+/*-----------------28.5.2001 11:09------------------
+ * SwLayHelper
+ * is the helper class, which utilizes the layout cache information
+ * to distribute the document content to the rigth pages.
+ * It's used by the _InsertCnt(..)-function.
+ * If there's no layout cache, the distibution to the pages is more
+ * a guess, but a guess with statistical background.
+ * --------------------------------------------------*/
+
+SwLayHelper::SwLayHelper( SwDoc *pD, SwFrm* &rpF, SwFrm* &rpP, SwPageFrm* &rpPg,
+ SwLayoutFrm* &rpL, SwActualSection* &rpA, BOOL &rB,
+ ULONG nNodeIndex, BOOL bCache )
+ : rpFrm( rpF ), rpPrv( rpP ), rpPage( rpPg ), rpLay( rpL ),
+ rpActualSection( rpA ), rbBreakAfter(rB), pDoc(pD), nMaxParaPerPage( 25 ),
+ nParagraphCnt( bCache ? 0 : USHRT_MAX ), bFirst( bCache )
+{
+ pImpl = pDoc->GetLayoutCache() ? pDoc->GetLayoutCache()->LockImpl() : NULL;
+ if( pImpl )
+ {
+ nStartOfContent = pDoc->GetNodes().GetEndOfContent().FindStartNode()
+ ->GetIndex();
+ nNodeIndex -= nStartOfContent;
+ nIndex = 0;
+ while( nIndex < pImpl->Count() && (*pImpl)[ nIndex ] < nNodeIndex )
+ ++nIndex;
+ if( nIndex >= pImpl->Count() )
+ {
+ pDoc->GetLayoutCache()->UnlockImpl();
+ pImpl = NULL;
+ }
+ }
+ else
+ {
+ pImpl = NULL;
+ nIndex = USHRT_MAX;
+ nStartOfContent = ULONG_MAX;
+ }
+}
+
+SwLayHelper::~SwLayHelper()
+{
+ if( pImpl )
+ {
+ ASSERT( pDoc && pDoc->GetLayoutCache(), "Missing layoutcache" );
+ pDoc->GetLayoutCache()->UnlockImpl();
+ }
+}
+
+/*-----------------23.5.2001 16:40------------------
+ * SwLayHelper::CalcPageCount() does not really calculate the page count,
+ * it returns the page count value from the layout cache, if available,
+ * otherwise it estimates the page count.
+ * --------------------------------------------------*/
+
+ULONG SwLayHelper::CalcPageCount()
+{
+ ULONG nPgCount;
+ SwLayCacheImpl *pCache = pDoc->GetLayoutCache() ?
+ pDoc->GetLayoutCache()->LockImpl() : NULL;
+ if( pCache )
+ {
+ nPgCount = pCache->Count() + 1;
+ pDoc->GetLayoutCache()->UnlockImpl();
+ }
+ else
+ {
+ nPgCount = pDoc->GetDocStat().nPage;
+ if ( nPgCount <= 10 ) // no page insertion for less than 10 pages
+ nPgCount = 0;
+ ULONG nNdCount = pDoc->GetDocStat().nPara;
+ if ( nNdCount <= 1 )
+ {
+ //Estimates the number of paragraphs.
+ ULONG nTmp = pDoc->GetNodes().GetEndOfContent().GetIndex() -
+ pDoc->GetNodes().GetEndOfExtras().GetIndex();
+ //Tables have a little overhead..
+ nTmp -= pDoc->GetTblFrmFmts()->Count() * 25;
+ //Fly frames, too ..
+ nTmp -= (pDoc->GetNodes().GetEndOfAutotext().GetIndex() -
+ pDoc->GetNodes().GetEndOfInserts().GetIndex()) / 3 * 5;
+ if ( nTmp > 0 )
+ nNdCount = nTmp;
+ }
+ if ( nNdCount > 100 ) // no estimation below this value
+ {
+ if ( nPgCount > 0 )
+ nMaxParaPerPage = nNdCount / nPgCount;
+ else
+ {
+ nMaxParaPerPage = Max( ULONG(20),
+ ULONG(20 + nNdCount / 1000 * 3) );
+#ifdef PM2
+ const ULONG nMax = 49;
+#elif MAC
+ const ULONG nMax = 56;
+#elif UNIX
+ const ULONG nMax = 57;
+#else
+ const ULONG nMax = 53;
+#endif
+ nMaxParaPerPage = Min( nMaxParaPerPage, nMax );
+ nPgCount = nNdCount / nMaxParaPerPage;
+ }
+ if ( nNdCount < 1000 )
+ nPgCount = 0;// no progress bar for small documents
+ if ( pDoc->IsBrowseMode() )
+ nMaxParaPerPage *= 6;
+ }
+ }
+ return nPgCount;
+}
+
+/*-----------------23.5.2001 16:44------------------
+ * SwLayHelper::CheckInsertPage()
+ * inserts a page and return TRUE, if
+ * - the break after flag is set
+ * - the actual content wants a break before
+ * - the maximum count of paragraph/rows is reached
+ *
+ * The break after flag is set, if the actual content
+ * wants a break after.
+ * --------------------------------------------------*/
+
+BOOL SwLayHelper::CheckInsertPage()
+{
+ FASTBOOL bEnd = 0 == rpPage->GetNext();
+ const SwAttrSet *pAttr = rpFrm->GetAttrSet();
+ const SvxFmtBreakItem &rBrk = pAttr->GetBreak();
+ const SwFmtPageDesc &rDesc = pAttr->GetPageDesc();
+ const SwPageDesc *pDesc = rDesc.GetPageDesc();
+
+ BOOL bBrk = nParagraphCnt > nMaxParaPerPage || rbBreakAfter;
+ rbBreakAfter = rBrk.GetBreak() == SVX_BREAK_PAGE_AFTER ||
+ rBrk.GetBreak() == SVX_BREAK_PAGE_BOTH;
+ if ( !bBrk )
+ bBrk = rBrk.GetBreak() == SVX_BREAK_PAGE_BEFORE ||
+ rBrk.GetBreak() == SVX_BREAK_PAGE_BOTH;
+
+ if ( bBrk || pDesc )
+ {
+ USHORT nPgNum = 0;
+ if ( !pDesc )
+ pDesc = rpPage->GetPageDesc()->GetFollow();
+ else
+ {
+ if ( 0 != (nPgNum = rDesc.GetNumOffset()) )
+ ((SwRootFrm*)rpPage->GetUpper())->SetVirtPageNum(TRUE);
+ }
+ BOOL bOdd = !rpPage->OnRightPage();
+ BOOL bInsertEmpty = FALSE;
+ if( nPgNum && bOdd != ( ( nPgNum % 2 ) != 0 ) )
+ {
+ bOdd = !bOdd;
+ bInsertEmpty = TRUE;
+ }
+ ::InsertNewPage( (SwPageDesc&)*pDesc, rpPage->GetUpper(),
+ bOdd, bInsertEmpty, FALSE, rpPage->GetNext() );
+ if ( bEnd )
+ {
+ ASSERT( rpPage->GetNext(), "Keine neue Seite?" );
+ do
+ { rpPage = (SwPageFrm*)rpPage->GetNext();
+ } while ( rpPage->GetNext() );
+ }
+ else
+ {
+ ASSERT( rpPage->GetNext(), "Keine neue Seite?" );
+ rpPage = (SwPageFrm*)rpPage->GetNext();
+ if ( rpPage->IsEmptyPage() )
+ {
+ ASSERT( rpPage->GetNext(), "Keine neue Seite?" );
+ rpPage = (SwPageFrm*)rpPage->GetNext();
+ }
+ }
+ rpLay = rpPage->FindBodyCont();
+ while( rpLay->Lower() )
+ rpLay = (SwLayoutFrm*)rpLay->Lower();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*-----------------28.5.2001 11:31------------------
+ * SwLayHelper::CheckInsert
+ * is the entry point for the _InsertCnt-function.
+ * The document content index is checked either it is
+ * in the layout cache either it's time to insert a page
+ * cause the maximal estimation of content per page is reached.
+ * A really big table or long paragraph may contains more than
+ * one page, in this case the needed count of pages will inserted.
+ * --------------------------------------------------*/
+
+BOOL SwLayHelper::CheckInsert( ULONG nNodeIndex )
+{
+ BOOL bRet = FALSE;
+ nNodeIndex -= nStartOfContent;
+ USHORT nRows;
+ if( rpFrm->IsTabFrm() )
+ {
+ //Inside a table counts every row as a paragraph
+ SwFrm *pLow = ((SwTabFrm*)rpFrm)->Lower();
+ nRows = 0;
+ do
+ {
+ ++nRows;
+ pLow = pLow->GetNext();
+ } while ( pLow );
+ nParagraphCnt += nRows;
+ }
+ else
+ ++nParagraphCnt;
+ if( bFirst && pImpl && nIndex < pImpl->Count() &&
+ pImpl->GetBreakIndex( nIndex ) == nNodeIndex &&
+ ( pImpl->GetBreakOfst( nIndex ) < STRING_LEN ||
+ ( ++nIndex < pImpl->Count() &&
+ pImpl->GetBreakIndex( nIndex ) == nNodeIndex ) ) )
+ bFirst = FALSE;
+ if( !bFirst )
+ {
+ ULONG nRowCount = 0;
+ do
+ {
+ if( pImpl )
+ {
+ xub_StrLen nOfst = STRING_LEN;
+ USHORT nType = SW_LAYCACHE_IO_REC_PAGES;
+ while( nIndex < pImpl->Count() &&
+ pImpl->GetBreakIndex(nIndex) < nNodeIndex)
+ nIndex += 2;
+ if( nIndex < pImpl->Count() &&
+ pImpl->GetBreakIndex(nIndex) == nNodeIndex )
+ {
+ nType = pImpl->GetBreakType( nIndex );
+ nOfst = pImpl->GetBreakOfst( nIndex++ );
+ rbBreakAfter = sal_True;
+ }
+ if( nOfst < STRING_LEN )
+ {
+ sal_Bool bSplit = sal_False;
+ sal_Bool bRepeat;
+ if( rpFrm->IsTxtFrm() && SW_LAYCACHE_IO_REC_PARA == nType &&
+ nOfst<((SwTxtFrm*)rpFrm)->GetTxtNode()->GetTxt().Len() )
+ bSplit = sal_True;
+ else if( rpFrm->IsTabFrm() && nRowCount < nOfst &&
+ SW_LAYCACHE_IO_REC_TABLE == nType )
+ {
+ bRepeat = ((SwTabFrm*)rpFrm)->
+ GetTable()->IsHeadlineRepeat();
+ bSplit = nOfst < nRows;
+ }
+ if( bSplit )
+ {
+ rpFrm->InsertBehind( rpLay, rpPrv );
+ rpFrm->Frm().Pos() = rpLay->Frm().Pos();
+ rpFrm->Frm().Pos().Y() += 1;
+ rpPrv = rpFrm;
+ if( rpFrm->IsTabFrm() )
+ {
+ SwTabFrm* pTab = (SwTabFrm*)rpFrm;
+ SwFrm *pRow = pTab->Lower();
+ SwTabFrm *pFoll = new SwTabFrm( *pTab );
+
+ SwFrm *pPrv;
+ if( bRepeat )
+ {
+ bDontCreateObjects = TRUE; //frmtool
+ SwRowFrm *pHeadline = new SwRowFrm(
+ *pTab->GetTable()->GetTabLines()[0] );
+ pHeadline->InsertBefore( pFoll, 0 );
+ bDontCreateObjects = FALSE;
+ pPrv = pFoll->Lower();
+ ++nRows;
+ }
+ else
+ pPrv = 0;
+ while( pRow && nRowCount < nOfst )
+ {
+ pRow = pRow->GetNext();
+ ++nRowCount;
+ }
+ while ( pRow )
+ {
+ SwFrm* pNxt = pRow->GetNext();
+ pRow->Remove();
+ pRow->InsertBehind( pFoll, pPrv );
+ pPrv = pRow;
+ pRow = pNxt;
+ }
+ rpFrm = pFoll;
+ }
+ else
+ {
+ SwTxtFrm *pNew = new SwTxtFrm( ((SwTxtFrm*)rpFrm)->
+ GetTxtNode() );
+ pNew->_SetIsFollow( sal_True );
+ pNew->ManipOfst( nOfst );
+ pNew->SetFollow( ((SwTxtFrm*)rpFrm)->GetFollow() );
+ ((SwTxtFrm*)rpFrm)->SetFollow( pNew );
+ rpFrm = pNew;
+ }
+ }
+ }
+
+#ifndef DEBUG
+ if( nIndex >= pImpl->Count() )
+ {
+ pImpl = NULL;
+ Cache()->UnlockImpl();
+ }
+#endif
+ }
+
+ if( CheckInsertPage() )
+ {
+ if( rpPrv && rpPrv->IsTxtFrm() && !rpPrv->GetValidSizeFlag() )
+ rpPrv->Frm().Height( rpPrv->GetUpper()->Prt().Height() );
+
+ bRet = TRUE;
+ rpPrv = 0;
+ nParagraphCnt = 0;
+
+ if ( rpActualSection )
+ {
+ //Hatte der SectionFrm ueberhaupt Inhalt? Wenn
+ //nicht kann er gleich umgehaengt werden.
+ SwSectionFrm *pSct;
+ if ( !rpActualSection->GetSectionFrm()->ContainsCntnt())
+ {
+ pSct = rpActualSection->GetSectionFrm();
+ pSct->Remove();
+ }
+ else
+ {
+ pSct = new SwSectionFrm(
+ *rpActualSection->GetSectionFrm(), FALSE );
+ rpActualSection->GetSectionFrm()->SimpleFormat();
+ pSct->Frm().Width( rpLay->Prt().Width() );
+ pSct->Prt().Width( rpLay->Prt().Width() );
+ }
+ rpActualSection->SetSectionFrm( pSct );
+ pSct->InsertBehind( rpLay, 0 );
+ pSct->Frm().Pos() = rpLay->Frm().Pos();
+ pSct->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
+
+ rpLay = pSct;
+ if ( rpLay->Lower() && rpLay->Lower()->IsLayoutFrm() )
+ rpLay = rpLay->GetNextLayoutLeaf();
+ }
+ }
+ } while( pImpl && nIndex < pImpl->Count() &&
+ (*pImpl)[ nIndex ] == nNodeIndex );
+ }
+ bFirst = FALSE;
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+SwLayCacheIoImpl::SwLayCacheIoImpl( SvStream& rStrm, BOOL bWrtMd ) :
+ pStream( &rStrm ),
+ nMajorVersion(SW_LAYCACHE_IO_VERSION_MAJOR),
+ nMinorVersion(SW_LAYCACHE_IO_VERSION_MINOR),
+ bWriteMode( bWrtMd ),
+ bError( FALSE )
+{
+ if( bWriteMode )
+ *pStream << nMajorVersion
+ << nMinorVersion;
+
+ else
+ *pStream >> nMajorVersion
+ >> nMinorVersion;
+}
+
+BOOL SwLayCacheIoImpl::OpenRec( BYTE cType )
+{
+ BOOL bRes = TRUE;
+ UINT16 nLvl = aRecTypes.Count();
+ ASSERT( nLvl == aRecSizes.Count(), "OpenRec: Level" );
+ UINT32 nPos = pStream->Tell();
+ if( bWriteMode )
+ {
+ aRecTypes.Insert( cType, nLvl );
+ aRecSizes.Insert( nPos, nLvl );
+ *pStream << (UINT32) 0;
+ }
+ else
+ {
+ UINT32 nVal;
+ *pStream >> nVal;
+ BYTE cRecTyp = (BYTE)nVal;
+ aRecTypes.Insert( cRecTyp, nLvl );
+ sal_uInt32 nSize = nVal >> 8;
+ aRecSizes.Insert( nPos + nSize, nLvl );
+ if( !nVal || cRecTyp != cType ||
+ pStream->GetErrorCode() != SVSTREAM_OK || pStream->IsEof() )
+ {
+ ASSERT( nVal, "OpenRec: Record-Header is 0" );
+ ASSERT( cRecTyp == cType,
+ "OpenRec: Wrong Record Type" );
+ aRecTypes[nLvl] = 0;
+ aRecSizes[nLvl] = pStream->Tell();
+ bRes = sal_False;
+ bError = TRUE;
+ }
+ }
+ return bRes;
+}
+
+// Close record
+
+BOOL SwLayCacheIoImpl::CloseRec( BYTE cType )
+{
+ BOOL bRes = TRUE;
+ UINT16 nLvl = aRecTypes.Count();
+ ASSERT( nLvl == aRecSizes.Count(), "CloseRec: wrong Level" );
+ ASSERT( nLvl, "CloseRec: no levels" );
+ if( nLvl )
+ {
+ nLvl--;
+ ASSERT( cType == aRecTypes[nLvl],
+ "CloseRec: Wrong Block-Header" );
+ UINT32 nPos = pStream->Tell();
+ if( bWriteMode )
+ {
+ UINT32 nBgn = aRecSizes[nLvl];
+ pStream->Seek( nBgn );
+ UINT32 nSize = nPos - nBgn;
+ UINT32 nVal = ( nSize << 8 ) | aRecTypes[nLvl];
+ *pStream << nVal;
+ pStream->Seek( nPos );
+ if( pStream->GetError() != SVSTREAM_OK )
+ bRes = FALSE;
+ }
+ else
+ {
+ UINT32 n = aRecSizes[nLvl];
+ ASSERT( n >= nPos, "CloseRec: to much data read" );
+ if( n != nPos )
+ {
+ pStream->Seek( n );
+ if( n < nPos )
+ bRes = FALSE;
+ }
+ if( pStream->GetErrorCode() != SVSTREAM_OK )
+ bRes = FALSE;
+ }
+
+ aRecTypes.Remove( nLvl, 1 );
+ aRecSizes.Remove( nLvl, 1 );
+ }
+
+ if( !bRes )
+ bError = TRUE;
+
+ return bRes;
+}
+
+UINT32 SwLayCacheIoImpl::BytesLeft()
+{
+ UINT16 nLvl = aRecSizes.Count();
+ UINT32 n = 0;
+ if( !bError && nLvl )
+ {
+ UINT32 nEndPos = aRecSizes[ nLvl-1 ];
+ UINT32 nPos = pStream->Tell();
+ if( nEndPos > nPos )
+ n = nEndPos - nPos;
+ }
+
+ return n;
+}
+
+BYTE SwLayCacheIoImpl::Peek()
+{
+ BYTE c = 0;
+ if( !bError )
+ {
+ UINT32 nPos = pStream->Tell();
+ *pStream >> c;
+ pStream->Seek( nPos );
+ if( pStream->GetErrorCode() != SVSTREAM_OK )
+ {
+ c = 0;
+ bError = TRUE;
+ }
+ }
+ return c;
+}
+
+void SwLayCacheIoImpl::SkipRec()
+{
+ BYTE c = Peek();
+ OpenRec( c );
+ pStream->Seek( aRecSizes[aRecSizes.Count()-1] );
+ CloseRec( c );
+}
+
+BYTE SwLayCacheIoImpl::OpenFlagRec()
+{
+ ASSERT( !bWriteMode, "OpenFlagRec illegal in write mode" );
+ BYTE cFlags;
+ *pStream >> cFlags;
+ nFlagRecEnd = pStream->Tell() + ( cFlags & 0x0F );
+ return (cFlags >> 4);
+}
+
+void SwLayCacheIoImpl::OpenFlagRec( BYTE nFlags, BYTE nLen )
+{
+ ASSERT( bWriteMode, "OpenFlagRec illegal in read mode" );
+ ASSERT( (nFlags & 0xF0) == 0, "illegal flags set" );
+ ASSERT( nLen < 16, "wrong flag record length" );
+ BYTE cFlags = (nFlags << 4) + nLen;
+ *pStream << cFlags;
+ nFlagRecEnd = pStream->Tell() + nLen;
+}
+
+void SwLayCacheIoImpl::CloseFlagRec()
+{
+ if( bWriteMode )
+ {
+ ASSERT( pStream->Tell() == nFlagRecEnd, "Wrong amount of data written" );
+ }
+ else
+ {
+ ASSERT( pStream->Tell() <= nFlagRecEnd, "To many data read" );
+ if( pStream->Tell() != nFlagRecEnd )
+ pStream->Seek( nFlagRecEnd );
+ }
+}
diff --git a/sw/source/core/layout/layhelp.hxx b/sw/source/core/layout/layhelp.hxx
new file mode 100644
index 000000000000..e47784a9e24b
--- /dev/null
+++ b/sw/source/core/layout/layhelp.hxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * $RCSfile: layhelp.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: ama $ $Date: 2001-05-29 12:41:00 $
+ *
+ * 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): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _LAYHELP_HXX
+#define _LAYHELP_HXX
+
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_USHORTS
+#define _SVSTDARR_ULONGS
+#define _SVSTDARR_BYTES
+#define _SVSTDARR_XUB_STRLEN
+#include <svtools/svstdarr.hxx>
+#endif
+
+class SwDoc;
+class SwFrm;
+class SwLayoutFrm;
+class SwPageFrm;
+class SwSectionFrm;
+class SwSectionNode;
+class SwLayoutCache;
+class SvStream;
+
+/*************************************************************************
+ * class SwLayCacheImpl
+ * contains the page break information of the document (after loading)
+ * and is used inside the constructor of the layout rootframe to
+ * insert content at the right pages.
+ * For every page of the main text (body content, no footnotes, text frames etc.)
+ * we have the nodeindex of the first content at the page,
+ * the type of content ( table or paragraph )
+ * and if it's not the first part of the table/paragraph,
+ * the row/character-offset inside the table/paragraph.
+ *************************************************************************/
+
+class SwLayCacheImpl : public SvULongs
+{
+ SvXub_StrLens aOffset;
+ SvUShorts aType;
+
+ void Insert( USHORT nType, ULONG nIndex, xub_StrLen nOffset );
+
+public:
+ SwLayCacheImpl() : SvULongs( 20, 10 ), aOffset( 20, 10 ), aType( 20, 10 ) {}
+ BOOL Read( SvStream& rStream );
+
+ ULONG GetBreakIndex( USHORT nIdx ) const { return GetObject( nIdx ); }
+ xub_StrLen GetBreakOfst( USHORT nIdx ) const { return aOffset[ nIdx ]; }
+ USHORT GetBreakType( USHORT nIdx ) const { return aType[ nIdx ]; }
+};
+
+/*************************************************************************
+ * class SwActualSection
+ * helps to create the sectionframes during the _InsertCnt-function
+ * by controlling nested sections.
+ *************************************************************************/
+
+class SwActualSection
+{
+ SwActualSection *pUpper;
+ SwSectionFrm *pSectFrm;
+ SwSectionNode *pSectNode;
+public:
+ SwActualSection( SwActualSection *pUpper,
+ SwSectionFrm *pSect,
+ SwSectionNode *pNd );
+
+ SwSectionFrm *GetSectionFrm() { return pSectFrm; }
+ void SetSectionFrm( SwSectionFrm *p ) { pSectFrm = p; }
+ SwSectionNode *GetSectionNode() { return pSectNode;}
+ SwActualSection *GetUpper() { return pUpper; }
+};
+
+/*************************************************************************
+ * class SwLayHelper
+ * helps during the _InsertCnt-function to create new pages.
+ * If there's a layoutcache available, this information is used.
+ *************************************************************************/
+
+class SwLayHelper
+{
+ SwFrm* &rpFrm;
+ SwFrm* &rpPrv;
+ SwPageFrm* &rpPage;
+ SwLayoutFrm* &rpLay;
+ SwActualSection* &rpActualSection;
+ BOOL &rbBreakAfter;
+ SwDoc* pDoc;
+ SwLayCacheImpl* pImpl;
+ ULONG nMaxParaPerPage;
+ ULONG nParagraphCnt;
+ ULONG nStartOfContent;
+ USHORT nIndex;
+ BOOL bFirst : 1;
+public:
+ SwLayHelper( SwDoc *pD, SwFrm* &rpF, SwFrm* &rpP, SwPageFrm* &rpPg,
+ SwLayoutFrm* &rpL, SwActualSection* &rpA, BOOL &rBrk,
+ ULONG nNodeIndex, BOOL bCache );
+ ~SwLayHelper();
+ ULONG CalcPageCount();
+ BOOL CheckInsert( ULONG nNodeIndex );
+
+ BOOL BreakPage( xub_StrLen& rOffs, ULONG nNodeIndex );
+ BOOL CheckInsertPage();
+
+};
+
+/*************************************************************************
+ * class SwLayCacheIoImpl
+ * contains the data structures that are required to read and write a
+ * layout cache.
+ *************************************************************************/
+
+#define SW_LAYCACHE_IO_REC_PAGES 'p'
+#define SW_LAYCACHE_IO_REC_PARA 'P'
+#define SW_LAYCACHE_IO_REC_TABLE 'T'
+
+#define SW_LAYCACHE_IO_VERSION_MAJOR 1
+#define SW_LAYCACHE_IO_VERSION_MINOR 0
+
+class SwLayCacheIoImpl
+{
+ SvBytes aRecTypes;
+ SvULongs aRecSizes;
+
+ SvStream *pStream;
+
+ ULONG nFlagRecEnd;
+
+ USHORT nMajorVersion;
+ USHORT nMinorVersion;
+
+ BOOL bWriteMode : 1;
+ BOOL bError : 1;
+
+public:
+ SwLayCacheIoImpl( SvStream& rStrm, BOOL bWrtMd );
+
+ // Get input or output stream
+ SvStream& GetStream() const { return *pStream; }
+
+ // Open a record of type "nType"
+ BOOL OpenRec( BYTE nType );
+
+ // Close a record of type "nType". This skips any unread data that
+ // remains in the record.
+ BOOL CloseRec( BYTE nType );
+
+ // Return the number of bytes contained in the current record that
+ // haven't been read by now.
+ UINT32 BytesLeft();
+
+ // Return the current record's type
+ BYTE Peek();
+
+ // Skip the current record
+ void SkipRec();
+
+ // Open a flag record for reading. The uppermost four bits are flags,
+ // while the lowermost are the flag record's size. Flag records cannot
+ // be nested.
+ BYTE OpenFlagRec();
+
+ // Open flag record for writing;
+ void OpenFlagRec( BYTE nFlags, BYTE nLen );
+
+ // Close a flag record. Any bytes left are skipped.
+ void CloseFlagRec();
+
+ BOOL HasError() const { return bError; }
+
+ USHORT GetMajorVersion() const { return nMajorVersion; }
+ USHORT GetMinorVersion() const { return nMinorVersion; }
+};
+
+#endif
diff --git a/sw/source/core/layout/makefile.mk b/sw/source/core/layout/makefile.mk
index 3ecc152ebb29..9f343d18b93e 100644
--- a/sw/source/core/layout/makefile.mk
+++ b/sw/source/core/layout/makefile.mk
@@ -2,9 +2,9 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.2 $
+# $Revision: 1.3 $
#
-# last change: $Author: cmc $ $Date: 2001-02-08 13:32:02 $
+# last change: $Author: ama $ $Date: 2001-05-29 12:38:15 $
#
# The Contents of this file are made available subject to the terms of
# either of the following licenses
@@ -112,6 +112,7 @@ CXXFILES = \
ftnfrm.cxx \
hffrm.cxx \
layact.cxx \
+ laycache.cxx \
layouter.cxx \
newfrm.cxx \
pagechg.cxx \
@@ -143,6 +144,7 @@ SLOFILES = \
$(SLO)$/ftnfrm.obj \
$(SLO)$/hffrm.obj \
$(SLO)$/layact.obj \
+ $(SLO)$/laycache.obj \
$(SLO)$/layouter.obj \
$(SLO)$/newfrm.obj \
$(SLO)$/pagechg.obj \