xref: /AOO41X/main/sw/source/core/text/frmform.cxx (revision 4d7c9de063a797b8b4f3d45e3561e82ad1f8ef1f)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <hintids.hxx>
29cdf0e10cSrcweir #include <editeng/keepitem.hxx>
30cdf0e10cSrcweir #include <editeng/hyznitem.hxx>
31cdf0e10cSrcweir #include <pagefrm.hxx>		// ChangeFtnRef
32cdf0e10cSrcweir #include <ndtxt.hxx>		// MakeFrm()
33cdf0e10cSrcweir #include <dcontact.hxx>		// SwDrawContact
34cdf0e10cSrcweir #include <dflyobj.hxx>		// SwVirtFlyDrawObj
35cdf0e10cSrcweir #include <flyfrm.hxx>
36cdf0e10cSrcweir #include <ftnfrm.hxx>		// SwFtnFrm
37cdf0e10cSrcweir #include <txtftn.hxx>
38cdf0e10cSrcweir #include <fmtftn.hxx>
39cdf0e10cSrcweir #include <paratr.hxx>
40cdf0e10cSrcweir #include <viewopt.hxx>		// SwViewOptions
41cdf0e10cSrcweir #include <viewsh.hxx>	  	// ViewShell
42cdf0e10cSrcweir #include <frmatr.hxx>
43cdf0e10cSrcweir #include <pam.hxx>
44cdf0e10cSrcweir #include <flyfrms.hxx>
45cdf0e10cSrcweir #include <fmtanchr.hxx>
46cdf0e10cSrcweir #include <txtcfg.hxx>
47cdf0e10cSrcweir #include <itrform2.hxx> 	// SwTxtFormatter
48cdf0e10cSrcweir #include <widorp.hxx>		// Widows and Orphans
49cdf0e10cSrcweir #include <txtcache.hxx>
50cdf0e10cSrcweir #include <porrst.hxx>		// SwEmptyPortion
51cdf0e10cSrcweir #include <blink.hxx>		// pBlink
52cdf0e10cSrcweir #include <porfld.hxx>		// SwFldPortion
53cdf0e10cSrcweir #include <sectfrm.hxx>		// SwSectionFrm
54cdf0e10cSrcweir #include <pormulti.hxx> 	// SwMultiPortion
55cdf0e10cSrcweir 
56cdf0e10cSrcweir #include <rootfrm.hxx>
57cdf0e10cSrcweir #include <frmfmt.hxx>	  	// SwFrmFmt
58cdf0e10cSrcweir // OD 2004-05-24 #i28701#
59cdf0e10cSrcweir #include <sortedobjs.hxx>
60*ca62e2c2SSteve Yin #include <portab.hxx>
61*ca62e2c2SSteve Yin #include <editeng/lrspitem.hxx>
62*ca62e2c2SSteve Yin #include <editeng/tstpitem.hxx>
63cdf0e10cSrcweir 
64cdf0e10cSrcweir class FormatLevel
65cdf0e10cSrcweir {
66cdf0e10cSrcweir 	static MSHORT nLevel;
67cdf0e10cSrcweir public:
FormatLevel()68cdf0e10cSrcweir 	inline FormatLevel()  { ++nLevel; }
~FormatLevel()69cdf0e10cSrcweir 	inline ~FormatLevel() { --nLevel; }
GetLevel() const70cdf0e10cSrcweir 	inline MSHORT GetLevel() const { return nLevel; }
LastLevel()71cdf0e10cSrcweir 	static sal_Bool LastLevel() { return 10 < nLevel; }
72cdf0e10cSrcweir };
73cdf0e10cSrcweir MSHORT FormatLevel::nLevel = 0;
74cdf0e10cSrcweir 
75cdf0e10cSrcweir /*************************************************************************
76cdf0e10cSrcweir  *							ValidateTxt/Frm()
77cdf0e10cSrcweir  *************************************************************************/
78cdf0e10cSrcweir 
ValidateTxt(SwFrm * pFrm)79cdf0e10cSrcweir void ValidateTxt( SwFrm *pFrm )		// Freund vom Frame
80cdf0e10cSrcweir {
81cdf0e10cSrcweir     if ( ( ! pFrm->IsVertical() &&
82cdf0e10cSrcweir              pFrm->Frm().Width() == pFrm->GetUpper()->Prt().Width() ) ||
83cdf0e10cSrcweir          (   pFrm->IsVertical() &&
84cdf0e10cSrcweir              pFrm->Frm().Height() == pFrm->GetUpper()->Prt().Height() ) )
85cdf0e10cSrcweir 		pFrm->bValidSize = sal_True;
86cdf0e10cSrcweir /*
87cdf0e10cSrcweir 	pFrm->bValidPrtArea = sal_True;
88cdf0e10cSrcweir 	//Die Position validieren um nicht unnoetige (Test-)Moves zu provozieren.
89cdf0e10cSrcweir 	//Dabei darf allerdings nicht eine tatsaechlich falsche Coordinate
90cdf0e10cSrcweir 	//validiert werden.
91cdf0e10cSrcweir 	if ( !pFrm->bValidPos )
92cdf0e10cSrcweir 	{
93cdf0e10cSrcweir 		//Leider muessen wir dazu die korrekte Position berechnen.
94cdf0e10cSrcweir 		Point aOld( pFrm->Frm().Pos() );
95cdf0e10cSrcweir 		pFrm->MakePos();
96cdf0e10cSrcweir 		if ( aOld != pFrm->Pos() )
97cdf0e10cSrcweir 		{
98cdf0e10cSrcweir 			pFrm->Frm().Pos( aOld );
99cdf0e10cSrcweir 			pFrm->bValidPos = sal_False;
100cdf0e10cSrcweir 		}
101cdf0e10cSrcweir 	}
102cdf0e10cSrcweir */
103cdf0e10cSrcweir }
104cdf0e10cSrcweir 
ValidateFrm()105cdf0e10cSrcweir void SwTxtFrm::ValidateFrm()
106cdf0e10cSrcweir {
107cdf0e10cSrcweir 	// Umgebung validieren, um Oszillationen zu verhindern.
108cdf0e10cSrcweir     SWAP_IF_SWAPPED( this )
109cdf0e10cSrcweir 
110cdf0e10cSrcweir     if ( !IsInFly() && !IsInTab() )
111cdf0e10cSrcweir 	{	//Innerhalb eines Flys nur this validieren, der Rest sollte eigentlich
112cdf0e10cSrcweir 		//nur fuer Fussnoten notwendig sein und die gibt es innerhalb von
113cdf0e10cSrcweir 		//Flys nicht. Fix fuer 5544
114cdf0e10cSrcweir 		SwSectionFrm* pSct = FindSctFrm();
115cdf0e10cSrcweir 		if( pSct )
116cdf0e10cSrcweir 		{
117cdf0e10cSrcweir 			if( !pSct->IsColLocked() )
118cdf0e10cSrcweir 				pSct->ColLock();
119cdf0e10cSrcweir 			else
120cdf0e10cSrcweir 				pSct = NULL;
121cdf0e10cSrcweir 		}
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 		SwFrm *pUp = GetUpper();
124cdf0e10cSrcweir 		pUp->Calc();
125cdf0e10cSrcweir 		if( pSct )
126cdf0e10cSrcweir 			pSct->ColUnlock();
127cdf0e10cSrcweir 	}
128cdf0e10cSrcweir 	ValidateTxt( this );
129cdf0e10cSrcweir 
130cdf0e10cSrcweir 	//MA: mindestens das MustFit-Flag muessen wir retten!
131cdf0e10cSrcweir 	ASSERT( HasPara(), "ResetPreps(), missing ParaPortion." );
132cdf0e10cSrcweir 	SwParaPortion *pPara = GetPara();
133cdf0e10cSrcweir 	const sal_Bool bMustFit = pPara->IsPrepMustFit();
134cdf0e10cSrcweir 	ResetPreps();
135cdf0e10cSrcweir 	pPara->SetPrepMustFit( bMustFit );
136cdf0e10cSrcweir 
137cdf0e10cSrcweir     UNDO_SWAP( this )
138cdf0e10cSrcweir }
139cdf0e10cSrcweir 
140cdf0e10cSrcweir /*************************************************************************
141cdf0e10cSrcweir  *							ValidateBodyFrm()
142cdf0e10cSrcweir  *************************************************************************/
143cdf0e10cSrcweir 
144cdf0e10cSrcweir // nach einem RemoveFtn muss der BodyFrm und alle innenliegenden kalkuliert
145cdf0e10cSrcweir // werden, damit die DeadLine richtig sitzt.
146cdf0e10cSrcweir // Erst wird nach aussen hin gesucht, beim Rueckweg werden alle kalkuliert.
147cdf0e10cSrcweir 
_ValidateBodyFrm(SwFrm * pFrm)148cdf0e10cSrcweir void _ValidateBodyFrm( SwFrm *pFrm )
149cdf0e10cSrcweir {
150cdf0e10cSrcweir     if( pFrm && !pFrm->IsCellFrm() )
151cdf0e10cSrcweir 	{
152cdf0e10cSrcweir         if( !pFrm->IsBodyFrm() && pFrm->GetUpper() )
153cdf0e10cSrcweir 			_ValidateBodyFrm( pFrm->GetUpper() );
154cdf0e10cSrcweir 		if( !pFrm->IsSctFrm() )
155cdf0e10cSrcweir 			pFrm->Calc();
156cdf0e10cSrcweir 		else
157cdf0e10cSrcweir 		{
158cdf0e10cSrcweir 			sal_Bool bOld = ((SwSectionFrm*)pFrm)->IsCntntLocked();
159cdf0e10cSrcweir 			((SwSectionFrm*)pFrm)->SetCntntLock( sal_True );
160cdf0e10cSrcweir 			pFrm->Calc();
161cdf0e10cSrcweir 			if( !bOld )
162cdf0e10cSrcweir 				((SwSectionFrm*)pFrm)->SetCntntLock( sal_False );
163cdf0e10cSrcweir 		}
164cdf0e10cSrcweir 	}
165cdf0e10cSrcweir }
166cdf0e10cSrcweir 
ValidateBodyFrm()167cdf0e10cSrcweir void SwTxtFrm::ValidateBodyFrm()
168cdf0e10cSrcweir {
169cdf0e10cSrcweir     SWAP_IF_SWAPPED( this )
170cdf0e10cSrcweir 
171cdf0e10cSrcweir      //siehe Kommtar in ValidateFrm()
172cdf0e10cSrcweir     if ( !IsInFly() && !IsInTab() &&
173cdf0e10cSrcweir          !( IsInSct() && FindSctFrm()->Lower()->IsColumnFrm() ) )
174cdf0e10cSrcweir 		_ValidateBodyFrm( GetUpper() );
175cdf0e10cSrcweir 
176cdf0e10cSrcweir     UNDO_SWAP( this )
177cdf0e10cSrcweir }
178cdf0e10cSrcweir 
179cdf0e10cSrcweir /*************************************************************************
180cdf0e10cSrcweir  *						SwTxtFrm::FindBodyFrm()
181cdf0e10cSrcweir  *************************************************************************/
182cdf0e10cSrcweir 
_GetDropRect(SwRect & rRect) const183cdf0e10cSrcweir sal_Bool SwTxtFrm::_GetDropRect( SwRect &rRect ) const
184cdf0e10cSrcweir {
185cdf0e10cSrcweir     SWAP_IF_NOT_SWAPPED( this )
186cdf0e10cSrcweir 
187cdf0e10cSrcweir 	ASSERT( HasPara(), "SwTxtFrm::_GetDropRect: try again next year." );
188cdf0e10cSrcweir 	SwTxtSizeInfo aInf( (SwTxtFrm*)this );
189cdf0e10cSrcweir 	SwTxtMargin aLine( (SwTxtFrm*)this, &aInf );
190cdf0e10cSrcweir 	if( aLine.GetDropLines() )
191cdf0e10cSrcweir 	{
192cdf0e10cSrcweir 		rRect.Top( aLine.Y() );
193cdf0e10cSrcweir 		rRect.Left( aLine.GetLineStart() );
194cdf0e10cSrcweir 		rRect.Height( aLine.GetDropHeight() );
195cdf0e10cSrcweir 		rRect.Width( aLine.GetDropLeft() );
196cdf0e10cSrcweir 
197cdf0e10cSrcweir         if ( IsRightToLeft() )
198cdf0e10cSrcweir             SwitchLTRtoRTL( rRect );
199cdf0e10cSrcweir 
200cdf0e10cSrcweir         if ( IsVertical() )
201cdf0e10cSrcweir             SwitchHorizontalToVertical( rRect );
202cdf0e10cSrcweir         UNDO_SWAP( this )
203cdf0e10cSrcweir 		return sal_True;
204cdf0e10cSrcweir 	}
205cdf0e10cSrcweir 
206cdf0e10cSrcweir     UNDO_SWAP( this )
207cdf0e10cSrcweir 
208cdf0e10cSrcweir     return sal_False;
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
211cdf0e10cSrcweir /*************************************************************************
212cdf0e10cSrcweir  *						SwTxtFrm::FindBodyFrm()
213cdf0e10cSrcweir  *************************************************************************/
214cdf0e10cSrcweir 
FindBodyFrm() const215cdf0e10cSrcweir const SwBodyFrm *SwTxtFrm::FindBodyFrm() const
216cdf0e10cSrcweir {
217cdf0e10cSrcweir 	if ( IsInDocBody() )
218cdf0e10cSrcweir 	{
219cdf0e10cSrcweir 		const SwFrm *pFrm = GetUpper();
220cdf0e10cSrcweir 		while( pFrm && !pFrm->IsBodyFrm() )
221cdf0e10cSrcweir 			pFrm = pFrm->GetUpper();
222cdf0e10cSrcweir 		return (const SwBodyFrm*)pFrm;
223cdf0e10cSrcweir 	}
224cdf0e10cSrcweir 	return 0;
225cdf0e10cSrcweir }
226cdf0e10cSrcweir 
227cdf0e10cSrcweir /*************************************************************************
228cdf0e10cSrcweir  *						SwTxtFrm::CalcFollow()
229cdf0e10cSrcweir  *************************************************************************/
230cdf0e10cSrcweir 
CalcFollow(const xub_StrLen nTxtOfst)231cdf0e10cSrcweir sal_Bool SwTxtFrm::CalcFollow( const xub_StrLen nTxtOfst )
232cdf0e10cSrcweir {
233cdf0e10cSrcweir     SWAP_IF_SWAPPED( this )
234cdf0e10cSrcweir 
235cdf0e10cSrcweir     ASSERT( HasFollow(), "CalcFollow: missing Follow." );
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     SwTxtFrm* pMyFollow = GetFollow();
238cdf0e10cSrcweir 
239cdf0e10cSrcweir 	SwParaPortion *pPara = GetPara();
240cdf0e10cSrcweir 	sal_Bool bFollowFld = pPara ? pPara->IsFollowField() : sal_False;
241cdf0e10cSrcweir 
242cdf0e10cSrcweir     if( !pMyFollow->GetOfst() || pMyFollow->GetOfst() != nTxtOfst ||
243cdf0e10cSrcweir         bFollowFld || pMyFollow->IsFieldFollow() ||
244cdf0e10cSrcweir         ( pMyFollow->IsVertical() && !pMyFollow->Prt().Width() ) ||
245cdf0e10cSrcweir         ( ! pMyFollow->IsVertical() && !pMyFollow->Prt().Height() ) )
246cdf0e10cSrcweir 	{
247cdf0e10cSrcweir #ifdef DBG_UTIL
248cdf0e10cSrcweir 		const SwFrm *pOldUp = GetUpper();
249cdf0e10cSrcweir #endif
250cdf0e10cSrcweir 
251cdf0e10cSrcweir         SWRECTFN ( this )
252cdf0e10cSrcweir         SwTwips nOldBottom = (GetUpper()->Frm().*fnRect->fnGetBottom)();
253cdf0e10cSrcweir         SwTwips nMyPos = (Frm().*fnRect->fnGetTop)();
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 		const SwPageFrm *pPage = 0;
256cdf0e10cSrcweir         sal_Bool  bOldInvaCntnt = sal_True;
257cdf0e10cSrcweir         if ( !IsInFly() && GetNext() )
258cdf0e10cSrcweir 		{
259cdf0e10cSrcweir 			pPage = FindPageFrm();
260cdf0e10cSrcweir 			//Minimieren - sprich ggf. zuruecksetzen - der Invalidierungen s.u.
261cdf0e10cSrcweir 			bOldInvaCntnt  = pPage->IsInvalidCntnt();
262cdf0e10cSrcweir         }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir         pMyFollow->_SetOfst( nTxtOfst );
265cdf0e10cSrcweir         pMyFollow->SetFieldFollow( bFollowFld );
266cdf0e10cSrcweir         if( HasFtn() || pMyFollow->HasFtn() )
267cdf0e10cSrcweir 		{
268cdf0e10cSrcweir 			ValidateFrm();
269cdf0e10cSrcweir 			ValidateBodyFrm();
270cdf0e10cSrcweir 			if( pPara )
271cdf0e10cSrcweir 			{
272cdf0e10cSrcweir 				*(pPara->GetReformat()) = SwCharRange();
273cdf0e10cSrcweir 				*(pPara->GetDelta()) = 0;
274cdf0e10cSrcweir 			}
275cdf0e10cSrcweir 		}
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 		//Der Fussnotenbereich darf sich keinesfalls vergrossern.
278cdf0e10cSrcweir 		SwSaveFtnHeight aSave( FindFtnBossFrm( sal_True ), LONG_MAX );
279cdf0e10cSrcweir 
280cdf0e10cSrcweir         pMyFollow->CalcFtnFlag();
281cdf0e10cSrcweir         if ( !pMyFollow->GetNext() && !pMyFollow->HasFtn() )
282cdf0e10cSrcweir             nOldBottom = bVert ? 0 : LONG_MAX;
283cdf0e10cSrcweir 
284cdf0e10cSrcweir 		while( sal_True )
285cdf0e10cSrcweir 		{
286cdf0e10cSrcweir 			if( !FormatLevel::LastLevel() )
287cdf0e10cSrcweir 			{
288cdf0e10cSrcweir 				// Weenn der Follow in einem spaltigen Bereich oder einem
289cdf0e10cSrcweir 				// spaltigen Rahmen steckt, muss zunaechst dieser kalkuliert
290cdf0e10cSrcweir 				// werden, da das FormatWidthCols() nicht funktioniert, wenn
291cdf0e10cSrcweir 				// es aus dem MakeAll des _gelockten_ Follows heraus gerufen
292cdf0e10cSrcweir 				// wird.
293cdf0e10cSrcweir                 SwSectionFrm* pSct = pMyFollow->FindSctFrm();
294cdf0e10cSrcweir 				if( pSct && !pSct->IsAnLower( this ) )
295cdf0e10cSrcweir 				{
296cdf0e10cSrcweir 					if( pSct->GetFollow() )
297cdf0e10cSrcweir 						pSct->SimpleFormat();
298cdf0e10cSrcweir                     else if( ( pSct->IsVertical() && !pSct->Frm().Width() ) ||
299cdf0e10cSrcweir                              ( ! pSct->IsVertical() && !pSct->Frm().Height() ) )
300cdf0e10cSrcweir 						break;
301cdf0e10cSrcweir 				}
302cdf0e10cSrcweir                 // OD 14.03.2003 #i11760# - intrinsic format of follow is controlled.
303cdf0e10cSrcweir                 if ( FollowFormatAllowed() )
304cdf0e10cSrcweir                 {
305cdf0e10cSrcweir                     // OD 14.03.2003 #i11760# - no nested format of follows, if
306cdf0e10cSrcweir                     // text frame is contained in a column frame.
307cdf0e10cSrcweir                     // Thus, forbid intrinsic format of follow.
308cdf0e10cSrcweir                     {
309cdf0e10cSrcweir                         bool bIsFollowInColumn = false;
310cdf0e10cSrcweir                         SwFrm* pFollowUpper = pMyFollow->GetUpper();
311cdf0e10cSrcweir                         while ( pFollowUpper )
312cdf0e10cSrcweir                         {
313cdf0e10cSrcweir                             if ( pFollowUpper->IsColumnFrm() )
314cdf0e10cSrcweir                             {
315cdf0e10cSrcweir                                 bIsFollowInColumn = true;
316cdf0e10cSrcweir                                 break;
317cdf0e10cSrcweir                             }
318cdf0e10cSrcweir                             if ( pFollowUpper->IsPageFrm() ||
319cdf0e10cSrcweir                                  pFollowUpper->IsFlyFrm() )
320cdf0e10cSrcweir                             {
321cdf0e10cSrcweir                                 break;
322cdf0e10cSrcweir                             }
323cdf0e10cSrcweir                             pFollowUpper = pFollowUpper->GetUpper();
324cdf0e10cSrcweir                         }
325cdf0e10cSrcweir                         if ( bIsFollowInColumn )
326cdf0e10cSrcweir                         {
327cdf0e10cSrcweir                             pMyFollow->ForbidFollowFormat();
328cdf0e10cSrcweir                         }
329cdf0e10cSrcweir                     }
330cdf0e10cSrcweir 
331cdf0e10cSrcweir                     pMyFollow->Calc();
332cdf0e10cSrcweir                     // Der Follow merkt anhand seiner Frm().Height(), dass was schief
333cdf0e10cSrcweir                     // gelaufen ist.
334cdf0e10cSrcweir                     ASSERT( !pMyFollow->GetPrev(), "SwTxtFrm::CalcFollow: cheesy follow" );
335cdf0e10cSrcweir                     if( pMyFollow->GetPrev() )
336cdf0e10cSrcweir                     {
337cdf0e10cSrcweir                         pMyFollow->Prepare( PREP_CLEAR );
338cdf0e10cSrcweir                         pMyFollow->Calc();
339cdf0e10cSrcweir                         ASSERT( !pMyFollow->GetPrev(), "SwTxtFrm::CalcFollow: very cheesy follow" );
340cdf0e10cSrcweir                     }
341cdf0e10cSrcweir 
342cdf0e10cSrcweir                     // OD 14.03.2003 #i11760# - reset control flag for follow format.
343cdf0e10cSrcweir                     pMyFollow->AllowFollowFormat();
344cdf0e10cSrcweir                 }
345cdf0e10cSrcweir 
346cdf0e10cSrcweir 				//Sicherstellen, dass der Follow gepaintet wird.
347cdf0e10cSrcweir                 pMyFollow->SetCompletePaint();
348cdf0e10cSrcweir 			}
349cdf0e10cSrcweir 
350cdf0e10cSrcweir 			pPara = GetPara();
351cdf0e10cSrcweir 			//Solange der Follow wg. Orphans Zeilen angefordert, bekommt er
352cdf0e10cSrcweir 			//diese und wird erneut formatiert, falls moeglich.
353cdf0e10cSrcweir 			if( pPara && pPara->IsPrepWidows() )
354cdf0e10cSrcweir 				CalcPreps();
355cdf0e10cSrcweir 			else
356cdf0e10cSrcweir 				break;
357cdf0e10cSrcweir 		}
358cdf0e10cSrcweir 
359cdf0e10cSrcweir         if( HasFtn() || pMyFollow->HasFtn() )
360cdf0e10cSrcweir 		{
361cdf0e10cSrcweir 			ValidateBodyFrm();
362cdf0e10cSrcweir 			ValidateFrm();
363cdf0e10cSrcweir 			if( pPara )
364cdf0e10cSrcweir 			{
365cdf0e10cSrcweir 				*(pPara->GetReformat()) = SwCharRange();
366cdf0e10cSrcweir 				*(pPara->GetDelta()) = 0;
367cdf0e10cSrcweir 			}
368cdf0e10cSrcweir 		}
369cdf0e10cSrcweir 
370cdf0e10cSrcweir         if ( pPage )
371cdf0e10cSrcweir 		{
372cdf0e10cSrcweir 			if ( !bOldInvaCntnt )
373cdf0e10cSrcweir 				pPage->ValidateCntnt();
374cdf0e10cSrcweir         }
375cdf0e10cSrcweir 
376cdf0e10cSrcweir #ifdef DBG_UTIL
377cdf0e10cSrcweir 		ASSERT( pOldUp == GetUpper(), "SwTxtFrm::CalcFollow: heavy follow" );
378cdf0e10cSrcweir #endif
379cdf0e10cSrcweir 
380cdf0e10cSrcweir         const long nRemaining =
381cdf0e10cSrcweir                  - (GetUpper()->Frm().*fnRect->fnBottomDist)( nOldBottom );
382cdf0e10cSrcweir         if (  nRemaining > 0 && !GetUpper()->IsSctFrm() &&
383cdf0e10cSrcweir               nRemaining != ( bVert ?
384cdf0e10cSrcweir                               nMyPos - Frm().Right() :
385cdf0e10cSrcweir                               Frm().Top() - nMyPos ) )
386cdf0e10cSrcweir         {
387cdf0e10cSrcweir             UNDO_SWAP( this )
388cdf0e10cSrcweir             return sal_True;
389cdf0e10cSrcweir         }
390cdf0e10cSrcweir 	}
391cdf0e10cSrcweir 
392cdf0e10cSrcweir     UNDO_SWAP( this )
393cdf0e10cSrcweir 
394cdf0e10cSrcweir     return sal_False;
395cdf0e10cSrcweir }
396cdf0e10cSrcweir 
397cdf0e10cSrcweir /*************************************************************************
398cdf0e10cSrcweir  *						SwTxtFrm::AdjustFrm()
399cdf0e10cSrcweir  *************************************************************************/
400cdf0e10cSrcweir 
AdjustFrm(const SwTwips nChgHght,sal_Bool bHasToFit)401cdf0e10cSrcweir void SwTxtFrm::AdjustFrm( const SwTwips nChgHght, sal_Bool bHasToFit )
402cdf0e10cSrcweir {
403cdf0e10cSrcweir     if( IsUndersized() )
404cdf0e10cSrcweir 	{
405cdf0e10cSrcweir 		if( GetOfst() && !IsFollow() ) // ein gescrollter Absatz (undersized)
406cdf0e10cSrcweir 			return;
407cdf0e10cSrcweir 		SetUndersized( nChgHght == 0 || bHasToFit );
408cdf0e10cSrcweir 	}
409cdf0e10cSrcweir 
410cdf0e10cSrcweir     // AdjustFrm is called with a swapped frame during
411cdf0e10cSrcweir     // formatting but the frame is not swapped during FormatEmpty
412cdf0e10cSrcweir     SWAP_IF_SWAPPED( this )
413cdf0e10cSrcweir     SWRECTFN ( this )
414cdf0e10cSrcweir 
415cdf0e10cSrcweir     // Die Size-Variable des Frames wird durch Grow inkrementiert
416cdf0e10cSrcweir 	// oder durch Shrink dekrementiert. Wenn die Groesse
417cdf0e10cSrcweir 	// unveraendert ist, soll nichts passieren!
418cdf0e10cSrcweir 	if( nChgHght >= 0)
419cdf0e10cSrcweir 	{
420cdf0e10cSrcweir         SwTwips nChgHeight = nChgHght;
421cdf0e10cSrcweir 		if( nChgHght && !bHasToFit )
422cdf0e10cSrcweir 		{
423cdf0e10cSrcweir 			if( IsInFtn() && !IsInSct() )
424cdf0e10cSrcweir 			{
425cdf0e10cSrcweir                 SwTwips nReal = Grow( nChgHght, sal_True );
426cdf0e10cSrcweir 				if( nReal < nChgHght )
427cdf0e10cSrcweir 				{
428cdf0e10cSrcweir                     SwTwips nBot = (*fnRect->fnYInc)( (Frm().*fnRect->fnGetBottom)(),
429cdf0e10cSrcweir                                                       nChgHght - nReal );
430cdf0e10cSrcweir 					SwFrm* pCont = FindFtnFrm()->GetUpper();
431cdf0e10cSrcweir 
432cdf0e10cSrcweir                     if( (pCont->Frm().*fnRect->fnBottomDist)( nBot ) > 0 )
433cdf0e10cSrcweir 					{
434cdf0e10cSrcweir                         (Frm().*fnRect->fnAddBottom)( nChgHght );
435cdf0e10cSrcweir                         if( bVert )
436cdf0e10cSrcweir                             Prt().SSize().Width() += nChgHght;
437cdf0e10cSrcweir                         else
438cdf0e10cSrcweir 						Prt().SSize().Height() += nChgHght;
439cdf0e10cSrcweir                         UNDO_SWAP( this )
440cdf0e10cSrcweir                         return;
441cdf0e10cSrcweir 					}
442cdf0e10cSrcweir 				}
443cdf0e10cSrcweir 			}
444cdf0e10cSrcweir 
445cdf0e10cSrcweir             Grow( nChgHght );
446cdf0e10cSrcweir 
447cdf0e10cSrcweir 			if ( IsInFly() )
448cdf0e10cSrcweir 			{
449cdf0e10cSrcweir 				//MA 06. May. 93: Wenn einer der Upper ein Fly ist, so ist es
450cdf0e10cSrcweir 				//sehr wahrscheinlich, dass dieser Fly durch das Grow seine
451cdf0e10cSrcweir 				//Position veraendert - also muss auch meine Position korrigiert
452cdf0e10cSrcweir 				//werden (sonst ist die Pruefung s.u. nicht aussagekraeftig).
453cdf0e10cSrcweir 				//Die Vorgaenger muessen berechnet werden, damit die Position
454cdf0e10cSrcweir 				//korrekt berechnet werden kann.
455cdf0e10cSrcweir 				if ( GetPrev() )
456cdf0e10cSrcweir 				{
457cdf0e10cSrcweir 					SwFrm *pPre = GetUpper()->Lower();
458cdf0e10cSrcweir 					do
459cdf0e10cSrcweir 					{	pPre->Calc();
460cdf0e10cSrcweir 						pPre = pPre->GetNext();
461cdf0e10cSrcweir 					} while ( pPre && pPre != this );
462cdf0e10cSrcweir 				}
463cdf0e10cSrcweir 				const Point aOldPos( Frm().Pos() );
464cdf0e10cSrcweir 				MakePos();
465cdf0e10cSrcweir 				if ( aOldPos != Frm().Pos() )
466cdf0e10cSrcweir                 {
467cdf0e10cSrcweir                     // OD 2004-07-01 #i28701# - use new method <SwFrm::InvalidateObjs(..)>
468cdf0e10cSrcweir                     // No format is performed for the floating screen objects.
469cdf0e10cSrcweir                     InvalidateObjs( true );
470cdf0e10cSrcweir                 }
471cdf0e10cSrcweir 			}
472cdf0e10cSrcweir             nChgHeight = 0;
473cdf0e10cSrcweir         }
474cdf0e10cSrcweir 		// Ein Grow() wird von der Layout-Seite immer akzeptiert,
475cdf0e10cSrcweir 		// also auch, wenn die FixSize des umgebenden Layoutframes
476cdf0e10cSrcweir 		// dies nicht zulassen sollte. Wir ueberpruefen diesen
477cdf0e10cSrcweir 		// Fall und korrigieren die Werte.
478cdf0e10cSrcweir 		// MA 06. May. 93: Der Frm darf allerdings auch im Notfall nicht
479cdf0e10cSrcweir 		// weiter geschrumpft werden als es seine Groesse zulaesst.
480cdf0e10cSrcweir         SwTwips nRstHeight;
481cdf0e10cSrcweir         if ( IsVertical() )
482cdf0e10cSrcweir         {
483cdf0e10cSrcweir             ASSERT( ! IsSwapped(),"Swapped frame while calculating nRstHeight" );
484cdf0e10cSrcweir 
485cdf0e10cSrcweir             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
486cdf0e10cSrcweir             if ( IsVertLR() )
487cdf0e10cSrcweir             		nRstHeight = GetUpper()->Frm().Left()
488cdf0e10cSrcweir                        		+ GetUpper()->Prt().Left()
489cdf0e10cSrcweir                        		+ GetUpper()->Prt().Width()
490cdf0e10cSrcweir                        		- Frm().Left();
491cdf0e10cSrcweir             else
492cdf0e10cSrcweir     			nRstHeight = Frm().Left() + Frm().Width() -
493cdf0e10cSrcweir                         	( GetUpper()->Frm().Left() + GetUpper()->Prt().Left() );
494cdf0e10cSrcweir          }
495cdf0e10cSrcweir         else
496cdf0e10cSrcweir             nRstHeight = GetUpper()->Frm().Top()
497cdf0e10cSrcweir                        + GetUpper()->Prt().Top()
498cdf0e10cSrcweir                        + GetUpper()->Prt().Height()
499cdf0e10cSrcweir                        - Frm().Top();
500cdf0e10cSrcweir 
501cdf0e10cSrcweir 		//In Tabellenzellen kann ich mir evtl. noch ein wenig dazuholen, weil
502cdf0e10cSrcweir 		//durch eine vertikale Ausrichtung auch oben noch Raum sein kann.
503cdf0e10cSrcweir         // --> OD 2004-11-25 #115759# - assure, that first lower in upper
504cdf0e10cSrcweir         // is the current one or is valid.
505cdf0e10cSrcweir         if ( IsInTab() &&
506cdf0e10cSrcweir              ( GetUpper()->Lower() == this ||
507cdf0e10cSrcweir                GetUpper()->Lower()->IsValid() ) )
508cdf0e10cSrcweir         // <--
509cdf0e10cSrcweir 		{
510cdf0e10cSrcweir             long nAdd = (*fnRect->fnYDiff)( (GetUpper()->Lower()->Frm().*fnRect->fnGetTop)(),
511cdf0e10cSrcweir                                             (GetUpper()->*fnRect->fnGetPrtTop)() );
512cdf0e10cSrcweir             ASSERT( nAdd >= 0, "Ey" );
513cdf0e10cSrcweir 			nRstHeight += nAdd;
514cdf0e10cSrcweir 		}
515cdf0e10cSrcweir 
516cdf0e10cSrcweir /* ------------------------------------
517cdf0e10cSrcweir  * #50964#: nRstHeight < 0 bedeutet, dass der TxtFrm komplett ausserhalb seines
518cdf0e10cSrcweir  * Upper liegt. Dies kann passieren, wenn er innerhalb eines FlyAtCntFrm liegt, der
519cdf0e10cSrcweir  * durch das Grow() die Seite gewechselt hat. In so einem Fall ist es falsch, der
520cdf0e10cSrcweir  * folgenden Grow-Versuch durchzufuehren. Im Bugfall fuehrte dies sogar zur
521cdf0e10cSrcweir  * Endlosschleife.
522cdf0e10cSrcweir  * -----------------------------------*/
523cdf0e10cSrcweir         SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
524cdf0e10cSrcweir         SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
525cdf0e10cSrcweir 
526cdf0e10cSrcweir         if( nRstHeight < nFrmHeight )
527cdf0e10cSrcweir 		{
528cdf0e10cSrcweir 			//Kann sein, dass ich die richtige Grosse habe, der Upper aber zu
529cdf0e10cSrcweir 			//klein ist und der Upper noch Platz schaffen kann.
530cdf0e10cSrcweir             if( ( nRstHeight >= 0 || ( IsInFtn() && IsInSct() ) ) && !bHasToFit )
531cdf0e10cSrcweir                 nRstHeight += GetUpper()->Grow( nFrmHeight - nRstHeight );
532cdf0e10cSrcweir             // In spaltigen Bereichen wollen wir moeglichst nicht zu gross werden, damit
533cdf0e10cSrcweir 			// nicht ueber GetNextSctLeaf weitere Bereiche angelegt werden. Stattdessen
534cdf0e10cSrcweir 			// schrumpfen wir und notieren bUndersized, damit FormatWidthCols die richtige
535cdf0e10cSrcweir 			// Spaltengroesse ermitteln kann.
536cdf0e10cSrcweir             if ( nRstHeight < nFrmHeight )
537cdf0e10cSrcweir 			{
538cdf0e10cSrcweir 				if(	bHasToFit || !IsMoveable() ||
539cdf0e10cSrcweir 					( IsInSct() && !FindSctFrm()->MoveAllowed(this) ) )
540cdf0e10cSrcweir 				{
541cdf0e10cSrcweir 					SetUndersized( sal_True );
542cdf0e10cSrcweir                     Shrink( Min( ( nFrmHeight - nRstHeight), nPrtHeight ) );
543cdf0e10cSrcweir 				}
544cdf0e10cSrcweir 				else
545cdf0e10cSrcweir 					SetUndersized( sal_False );
546cdf0e10cSrcweir 			}
547cdf0e10cSrcweir 		}
548cdf0e10cSrcweir         else if( nChgHeight )
549cdf0e10cSrcweir         {
550cdf0e10cSrcweir             if( nRstHeight - nFrmHeight < nChgHeight )
551cdf0e10cSrcweir                 nChgHeight = nRstHeight - nFrmHeight;
552cdf0e10cSrcweir             if( nChgHeight )
553cdf0e10cSrcweir                 Grow( nChgHeight );
554cdf0e10cSrcweir         }
555cdf0e10cSrcweir     }
556cdf0e10cSrcweir     else
557cdf0e10cSrcweir         Shrink( -nChgHght );
558cdf0e10cSrcweir 
559cdf0e10cSrcweir     UNDO_SWAP( this )
560cdf0e10cSrcweir }
561cdf0e10cSrcweir 
GetTabStopInfo(SwTwips CurrentPos)562*ca62e2c2SSteve Yin com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > SwTxtFrm::GetTabStopInfo( SwTwips CurrentPos )
563*ca62e2c2SSteve Yin {
564*ca62e2c2SSteve Yin 	com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > tabs(1);
565*ca62e2c2SSteve Yin 	::com::sun::star::style::TabStop ts;
566*ca62e2c2SSteve Yin 
567*ca62e2c2SSteve Yin 	SwTxtFormatInfo 	aInf( this );
568*ca62e2c2SSteve Yin 	SwTxtFormatter		aLine( this, &aInf );
569*ca62e2c2SSteve Yin 	SwTxtCursor  		TxtCursor( this, &aInf );
570*ca62e2c2SSteve Yin 	const Point aCharPos( TxtCursor.GetTopLeft() );
571*ca62e2c2SSteve Yin 
572*ca62e2c2SSteve Yin 
573*ca62e2c2SSteve Yin 	SwTwips nRight = aLine.Right();
574*ca62e2c2SSteve Yin 	CurrentPos -= aCharPos.X();
575*ca62e2c2SSteve Yin 
576*ca62e2c2SSteve Yin 	// get current tab stop information stored in the Frm
577*ca62e2c2SSteve Yin 	const SvxTabStop *pTS = aLine.GetLineInfo().GetTabStop( CurrentPos, nRight );
578*ca62e2c2SSteve Yin 
579*ca62e2c2SSteve Yin 	if( !pTS )
580*ca62e2c2SSteve Yin 	{
581*ca62e2c2SSteve Yin 		return com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop >();
582*ca62e2c2SSteve Yin 	}
583*ca62e2c2SSteve Yin 
584*ca62e2c2SSteve Yin 	// copy tab stop information into a Sequence, which only contains one element.
585*ca62e2c2SSteve Yin 	ts.Position = pTS->GetTabPos();
586*ca62e2c2SSteve Yin 	ts.DecimalChar = pTS->GetDecimal();
587*ca62e2c2SSteve Yin 	ts.FillChar = pTS->GetFill();
588*ca62e2c2SSteve Yin     switch( pTS->GetAdjustment() )
589*ca62e2c2SSteve Yin     {
590*ca62e2c2SSteve Yin     case SVX_TAB_ADJUST_LEFT   : ts.Alignment = ::com::sun::star::style::TabAlign_LEFT; break;
591*ca62e2c2SSteve Yin     case SVX_TAB_ADJUST_CENTER : ts.Alignment = ::com::sun::star::style::TabAlign_CENTER; break;
592*ca62e2c2SSteve Yin     case SVX_TAB_ADJUST_RIGHT  : ts.Alignment = ::com::sun::star::style::TabAlign_RIGHT; break;
593*ca62e2c2SSteve Yin     case SVX_TAB_ADJUST_DECIMAL: ts.Alignment = ::com::sun::star::style::TabAlign_DECIMAL; break;
594*ca62e2c2SSteve Yin     case SVX_TAB_ADJUST_DEFAULT: ts.Alignment = ::com::sun::star::style::TabAlign_DEFAULT; break;
595*ca62e2c2SSteve Yin     default: break; // prevent warning
596*ca62e2c2SSteve Yin     }
597*ca62e2c2SSteve Yin 
598*ca62e2c2SSteve Yin 	tabs[0] = ts;
599*ca62e2c2SSteve Yin 	return tabs;
600*ca62e2c2SSteve Yin }
601cdf0e10cSrcweir /*************************************************************************
602cdf0e10cSrcweir  *						SwTxtFrm::AdjustFollow()
603cdf0e10cSrcweir  *************************************************************************/
604cdf0e10cSrcweir 
605cdf0e10cSrcweir /* AdjustFollow erwartet folgende Situation:
606cdf0e10cSrcweir  * Der SwTxtIter steht am unteren Ende des Masters, der Offset wird
607cdf0e10cSrcweir  * im Follow eingestellt.
608cdf0e10cSrcweir  * nOffset haelt den Offset im Textstring, ab dem der Master abschliesst
609cdf0e10cSrcweir  * und der Follow beginnt. Wenn er 0 ist, wird der FolgeFrame geloescht.
610cdf0e10cSrcweir  */
611cdf0e10cSrcweir 
_AdjustFollow(SwTxtFormatter & rLine,const xub_StrLen nOffset,const xub_StrLen nEnd,const sal_uInt8 nMode)612cdf0e10cSrcweir void SwTxtFrm::_AdjustFollow( SwTxtFormatter &rLine,
613cdf0e10cSrcweir 							 const xub_StrLen nOffset, const xub_StrLen nEnd,
614cdf0e10cSrcweir 							 const sal_uInt8 nMode )
615cdf0e10cSrcweir {
616cdf0e10cSrcweir     SwFrmSwapper aSwapper( this, sal_False );
617cdf0e10cSrcweir 
618cdf0e10cSrcweir     // Wir haben den Rest der Textmasse: alle Follows loeschen
619cdf0e10cSrcweir     // Sonderfall sind DummyPortions()
620cdf0e10cSrcweir     // - special cases are controlled by parameter <nMode>.
621cdf0e10cSrcweir     if( HasFollow() && !(nMode & 1) && nOffset == nEnd )
622cdf0e10cSrcweir 	{
623cdf0e10cSrcweir         while( GetFollow() )
624cdf0e10cSrcweir 		{
625cdf0e10cSrcweir 			if( ((SwTxtFrm*)GetFollow())->IsLocked() )
626cdf0e10cSrcweir 			{
627cdf0e10cSrcweir 				ASSERT( sal_False, "+SwTxtFrm::JoinFrm: Follow ist locked." );
628cdf0e10cSrcweir                 return;
629cdf0e10cSrcweir 			}
630cdf0e10cSrcweir 			JoinFrm();
631cdf0e10cSrcweir 		}
632cdf0e10cSrcweir 
633cdf0e10cSrcweir         return;
634cdf0e10cSrcweir 	}
635cdf0e10cSrcweir 
636cdf0e10cSrcweir 	// Tanz auf dem Vulkan: Wir formatieren eben schnell noch einmal
637cdf0e10cSrcweir 	// die letzte Zeile fuer das QuoVadis-Geraffel. Selbstverstaendlich
638cdf0e10cSrcweir 	// kann sich dadurch auch der Offset verschieben:
639cdf0e10cSrcweir 	const xub_StrLen nNewOfst = ( IsInFtn() && ( !GetIndNext() || HasFollow() ) ) ?
640cdf0e10cSrcweir 							rLine.FormatQuoVadis(nOffset) : nOffset;
641cdf0e10cSrcweir 
642cdf0e10cSrcweir 	if( !(nMode & 1) )
643cdf0e10cSrcweir 	{
644cdf0e10cSrcweir 		// Wir klauen unseren Follows Textmasse, dabei kann es passieren,
645cdf0e10cSrcweir 		// dass wir einige Follows Joinen muessen.
646cdf0e10cSrcweir 		while( GetFollow() && GetFollow()->GetFollow() &&
647cdf0e10cSrcweir 			   nNewOfst >= GetFollow()->GetFollow()->GetOfst() )
648cdf0e10cSrcweir 		{
649cdf0e10cSrcweir 			DBG_LOOP;
650cdf0e10cSrcweir 			JoinFrm();
651cdf0e10cSrcweir 		}
652cdf0e10cSrcweir 	}
653cdf0e10cSrcweir 
654cdf0e10cSrcweir 	// Der Ofst hat sich verschoben.
655cdf0e10cSrcweir 	if( GetFollow() )
656cdf0e10cSrcweir 	{
657cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
658cdf0e10cSrcweir 		static sal_Bool bTest = sal_False;
659cdf0e10cSrcweir 		if( !bTest || ( nMode & 1 ) )
660cdf0e10cSrcweir #endif
661cdf0e10cSrcweir 		if ( nMode )
662cdf0e10cSrcweir 			GetFollow()->ManipOfst( 0 );
663cdf0e10cSrcweir 
664cdf0e10cSrcweir 		if ( CalcFollow( nNewOfst ) )	// CalcFollow erst zum Schluss, dort erfolgt ein SetOfst
665cdf0e10cSrcweir 			rLine.SetOnceMore( sal_True );
666cdf0e10cSrcweir 	}
667cdf0e10cSrcweir }
668cdf0e10cSrcweir 
669cdf0e10cSrcweir /*************************************************************************
670cdf0e10cSrcweir  *						SwTxtFrm::JoinFrm()
671cdf0e10cSrcweir  *************************************************************************/
672cdf0e10cSrcweir 
JoinFrm()673cdf0e10cSrcweir SwCntntFrm *SwTxtFrm::JoinFrm()
674cdf0e10cSrcweir {
675cdf0e10cSrcweir 	ASSERT( GetFollow(), "+SwTxtFrm::JoinFrm: no follow" );
676cdf0e10cSrcweir 	SwTxtFrm  *pFoll = GetFollow();
677cdf0e10cSrcweir 
678cdf0e10cSrcweir 	SwTxtFrm *pNxt = pFoll->GetFollow();
679cdf0e10cSrcweir 
680cdf0e10cSrcweir 	// Alle Fussnoten des zu zerstoerenden Follows werden auf uns
681cdf0e10cSrcweir 	// umgehaengt.
682cdf0e10cSrcweir 	xub_StrLen nStart = pFoll->GetOfst();
683cdf0e10cSrcweir 	if ( pFoll->HasFtn() )
684cdf0e10cSrcweir 	{
685cdf0e10cSrcweir 		const SwpHints *pHints = pFoll->GetTxtNode()->GetpSwpHints();
686cdf0e10cSrcweir 		if( pHints )
687cdf0e10cSrcweir 		{
688cdf0e10cSrcweir 			SwFtnBossFrm *pFtnBoss = 0;
689cdf0e10cSrcweir 			SwFtnBossFrm *pEndBoss = 0;
690cdf0e10cSrcweir             for ( sal_uInt16 i = 0; i < pHints->Count(); ++i )
691cdf0e10cSrcweir             {
692cdf0e10cSrcweir 				const SwTxtAttr *pHt = (*pHints)[i];
693cdf0e10cSrcweir 				if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nStart )
694cdf0e10cSrcweir 				{
695cdf0e10cSrcweir 					if( pHt->GetFtn().IsEndNote() )
696cdf0e10cSrcweir 					{
697cdf0e10cSrcweir 						if( !pEndBoss )
698cdf0e10cSrcweir 							pEndBoss = pFoll->FindFtnBossFrm();
699cdf0e10cSrcweir 						pEndBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
700cdf0e10cSrcweir 					}
701cdf0e10cSrcweir 					else
702cdf0e10cSrcweir 					{
703cdf0e10cSrcweir 						if( !pFtnBoss )
704cdf0e10cSrcweir 							pFtnBoss = pFoll->FindFtnBossFrm( sal_True );
705cdf0e10cSrcweir 						pFtnBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
706cdf0e10cSrcweir 					}
707cdf0e10cSrcweir 					SetFtn( sal_True );
708cdf0e10cSrcweir 				}
709cdf0e10cSrcweir 			}
710cdf0e10cSrcweir 		}
711cdf0e10cSrcweir 	}
712cdf0e10cSrcweir 
713cdf0e10cSrcweir #ifdef DBG_UTIL
714cdf0e10cSrcweir     else if ( pFoll->GetValidPrtAreaFlag() ||
715cdf0e10cSrcweir               pFoll->GetValidSizeFlag() )
716cdf0e10cSrcweir     {
717cdf0e10cSrcweir 		pFoll->CalcFtnFlag();
718cdf0e10cSrcweir 		ASSERT( !pFoll->HasFtn(), "Missing FtnFlag." );
719cdf0e10cSrcweir 	}
720cdf0e10cSrcweir #endif
721cdf0e10cSrcweir 
722cdf0e10cSrcweir 	pFoll->MoveFlyInCnt( this, nStart, STRING_LEN );
723cdf0e10cSrcweir     pFoll->SetFtn( sal_False );
724cdf0e10cSrcweir     // --> OD 2005-12-01 #i27138#
725cdf0e10cSrcweir     // notify accessibility paragraphs objects about changed CONTENT_FLOWS_FROM/_TO relation.
726cdf0e10cSrcweir     // Relation CONTENT_FLOWS_FROM for current next paragraph will change
727cdf0e10cSrcweir     // and relation CONTENT_FLOWS_TO for current previous paragraph, which
728cdf0e10cSrcweir     // is <this>, will change.
729cdf0e10cSrcweir     {
730cdf0e10cSrcweir         ViewShell* pViewShell( pFoll->getRootFrm()->GetCurrShell() );
731cdf0e10cSrcweir         if ( pViewShell && pViewShell->GetLayout() &&
732cdf0e10cSrcweir              pViewShell->GetLayout()->IsAnyShellAccessible() )
733cdf0e10cSrcweir         {
734cdf0e10cSrcweir             pViewShell->InvalidateAccessibleParaFlowRelation(
735cdf0e10cSrcweir                             dynamic_cast<SwTxtFrm*>(pFoll->FindNextCnt( true )),
736cdf0e10cSrcweir                             this );
737cdf0e10cSrcweir         }
738cdf0e10cSrcweir     }
739cdf0e10cSrcweir     // <--
740cdf0e10cSrcweir     pFoll->Cut();
741cdf0e10cSrcweir 	delete pFoll;
742cdf0e10cSrcweir 	pFollow = pNxt;
743cdf0e10cSrcweir 	return pNxt;
744cdf0e10cSrcweir }
745cdf0e10cSrcweir 
746cdf0e10cSrcweir /*************************************************************************
747cdf0e10cSrcweir  *						SwTxtFrm::SplitFrm()
748cdf0e10cSrcweir  *************************************************************************/
749cdf0e10cSrcweir 
SplitFrm(const xub_StrLen nTxtPos)750cdf0e10cSrcweir SwCntntFrm *SwTxtFrm::SplitFrm( const xub_StrLen nTxtPos )
751cdf0e10cSrcweir {
752cdf0e10cSrcweir     SWAP_IF_SWAPPED( this )
753cdf0e10cSrcweir 
754cdf0e10cSrcweir 	// Durch das Paste wird ein Modify() an mich verschickt.
755cdf0e10cSrcweir 	// Damit meine Daten nicht verschwinden, locke ich mich.
756cdf0e10cSrcweir 	SwTxtFrmLocker aLock( this );
757cdf0e10cSrcweir 	SwTxtFrm *pNew = (SwTxtFrm *)(GetTxtNode()->MakeFrm( this ));
758cdf0e10cSrcweir 	pNew->bIsFollow = sal_True;
759cdf0e10cSrcweir 
760cdf0e10cSrcweir 	pNew->SetFollow( GetFollow() );
761cdf0e10cSrcweir 	SetFollow( pNew );
762cdf0e10cSrcweir 
763cdf0e10cSrcweir 	pNew->Paste( GetUpper(), GetNext() );
764cdf0e10cSrcweir     // --> OD 2005-12-01 #i27138#
765cdf0e10cSrcweir     // notify accessibility paragraphs objects about changed CONTENT_FLOWS_FROM/_TO relation.
766cdf0e10cSrcweir     // Relation CONTENT_FLOWS_FROM for current next paragraph will change
767cdf0e10cSrcweir     // and relation CONTENT_FLOWS_TO for current previous paragraph, which
768cdf0e10cSrcweir     // is <this>, will change.
769cdf0e10cSrcweir     {
770cdf0e10cSrcweir         ViewShell* pViewShell( pNew->getRootFrm()->GetCurrShell() );
771cdf0e10cSrcweir         if ( pViewShell && pViewShell->GetLayout() &&
772cdf0e10cSrcweir              pViewShell->GetLayout()->IsAnyShellAccessible() )
773cdf0e10cSrcweir         {
774cdf0e10cSrcweir             pViewShell->InvalidateAccessibleParaFlowRelation(
775cdf0e10cSrcweir                             dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )),
776cdf0e10cSrcweir                             this );
777cdf0e10cSrcweir         }
778cdf0e10cSrcweir     }
779cdf0e10cSrcweir     // <--
780cdf0e10cSrcweir 
781cdf0e10cSrcweir 	// Wenn durch unsere Aktionen Fussnoten in pNew landen,
782cdf0e10cSrcweir 	// so muessen sie umgemeldet werden.
783cdf0e10cSrcweir 	if ( HasFtn() )
784cdf0e10cSrcweir 	{
785cdf0e10cSrcweir 		const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
786cdf0e10cSrcweir 		if( pHints )
787cdf0e10cSrcweir 		{
788cdf0e10cSrcweir 			SwFtnBossFrm *pFtnBoss = 0;
789cdf0e10cSrcweir 			SwFtnBossFrm *pEndBoss = 0;
790cdf0e10cSrcweir             for ( sal_uInt16 i = 0; i < pHints->Count(); ++i )
791cdf0e10cSrcweir             {
792cdf0e10cSrcweir 				const SwTxtAttr *pHt = (*pHints)[i];
793cdf0e10cSrcweir 				if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nTxtPos )
794cdf0e10cSrcweir 				{
795cdf0e10cSrcweir 					if( pHt->GetFtn().IsEndNote() )
796cdf0e10cSrcweir 					{
797cdf0e10cSrcweir 						if( !pEndBoss )
798cdf0e10cSrcweir 							pEndBoss = FindFtnBossFrm();
799cdf0e10cSrcweir 						pEndBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
800cdf0e10cSrcweir 					}
801cdf0e10cSrcweir 					else
802cdf0e10cSrcweir 					{
803cdf0e10cSrcweir 						if( !pFtnBoss )
804cdf0e10cSrcweir 							pFtnBoss = FindFtnBossFrm( sal_True );
805cdf0e10cSrcweir 						pFtnBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
806cdf0e10cSrcweir 					}
807cdf0e10cSrcweir 					pNew->SetFtn( sal_True );
808cdf0e10cSrcweir 				}
809cdf0e10cSrcweir 			}
810cdf0e10cSrcweir 		}
811cdf0e10cSrcweir 	}
812cdf0e10cSrcweir 
813cdf0e10cSrcweir #ifdef DBG_UTIL
814cdf0e10cSrcweir 	else
815cdf0e10cSrcweir 	{
816cdf0e10cSrcweir 		CalcFtnFlag( nTxtPos-1 );
817cdf0e10cSrcweir 		ASSERT( !HasFtn(), "Missing FtnFlag." );
818cdf0e10cSrcweir 	}
819cdf0e10cSrcweir #endif
820cdf0e10cSrcweir 
821cdf0e10cSrcweir 	MoveFlyInCnt( pNew, nTxtPos, STRING_LEN );
822cdf0e10cSrcweir 
823cdf0e10cSrcweir 	// Kein SetOfst oder CalcFollow, weil gleich ohnehin ein AdjustFollow folgt.
824cdf0e10cSrcweir 
825cdf0e10cSrcweir 	pNew->ManipOfst( nTxtPos );
826cdf0e10cSrcweir 
827cdf0e10cSrcweir     UNDO_SWAP( this )
828cdf0e10cSrcweir 	return pNew;
829cdf0e10cSrcweir }
830cdf0e10cSrcweir 
831cdf0e10cSrcweir 
832cdf0e10cSrcweir /*************************************************************************
833cdf0e10cSrcweir  *						virtual SwTxtFrm::SetOfst()
834cdf0e10cSrcweir  *************************************************************************/
835cdf0e10cSrcweir 
_SetOfst(const xub_StrLen nNewOfst)836cdf0e10cSrcweir void SwTxtFrm::_SetOfst( const xub_StrLen nNewOfst )
837cdf0e10cSrcweir {
838cdf0e10cSrcweir #ifdef DBGTXT
839cdf0e10cSrcweir 	// Es gibt tatsaechlich einen Sonderfall, in dem ein SetOfst(0)
840cdf0e10cSrcweir 	// zulaessig ist: bug 3496
841cdf0e10cSrcweir 	ASSERT( nNewOfst, "!SwTxtFrm::SetOfst: missing JoinFrm()." );
842cdf0e10cSrcweir #endif
843cdf0e10cSrcweir 
844cdf0e10cSrcweir 	// Die Invalidierung unseres Follows ist nicht noetig.
845cdf0e10cSrcweir 	// Wir sind ein Follow, werden gleich formatiert und
846cdf0e10cSrcweir 	// rufen von dort aus das SetOfst() !
847cdf0e10cSrcweir 	nOfst = nNewOfst;
848cdf0e10cSrcweir 	SwParaPortion *pPara = GetPara();
849cdf0e10cSrcweir 	if( pPara )
850cdf0e10cSrcweir 	{
851cdf0e10cSrcweir 		SwCharRange &rReformat = *(pPara->GetReformat());
852cdf0e10cSrcweir 		rReformat.Start() = 0;
853cdf0e10cSrcweir 		rReformat.Len() = GetTxt().Len();
854cdf0e10cSrcweir 		*(pPara->GetDelta()) = rReformat.Len();
855cdf0e10cSrcweir 	}
856cdf0e10cSrcweir 	InvalidateSize();
857cdf0e10cSrcweir }
858cdf0e10cSrcweir 
859cdf0e10cSrcweir /*************************************************************************
860cdf0e10cSrcweir  *						SwTxtFrm::CalcPreps
861cdf0e10cSrcweir  *************************************************************************/
862cdf0e10cSrcweir 
CalcPreps()863cdf0e10cSrcweir sal_Bool SwTxtFrm::CalcPreps()
864cdf0e10cSrcweir {
865cdf0e10cSrcweir     ASSERT( ! IsVertical() || ! IsSwapped(), "SwTxtFrm::CalcPreps with swapped frame" );
866cdf0e10cSrcweir     SWRECTFN( this );
867cdf0e10cSrcweir 
868cdf0e10cSrcweir     SwParaPortion *pPara = GetPara();
869cdf0e10cSrcweir 	if ( !pPara )
870cdf0e10cSrcweir 		return sal_False;
871cdf0e10cSrcweir 	sal_Bool bPrep = pPara->IsPrep();
872cdf0e10cSrcweir 	sal_Bool bPrepWidows = pPara->IsPrepWidows();
873cdf0e10cSrcweir 	sal_Bool bPrepAdjust = pPara->IsPrepAdjust();
874cdf0e10cSrcweir 	sal_Bool bPrepMustFit = pPara->IsPrepMustFit();
875cdf0e10cSrcweir 	ResetPreps();
876cdf0e10cSrcweir 
877cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
878cdf0e10cSrcweir 	if( bPrep && !pPara->GetReformat()->Len() )
879cdf0e10cSrcweir 	{
880cdf0e10cSrcweir 		// PREP_WIDOWS bedeutet, dass im Follow die Orphans-Regel
881cdf0e10cSrcweir 		// zuschlug.
882cdf0e10cSrcweir 		// Es kann in unguenstigen Faellen vorkommen, dass auch ein
883cdf0e10cSrcweir 		// PrepAdjust vorliegt (3680)!
884cdf0e10cSrcweir 		if( bPrepWidows )
885cdf0e10cSrcweir 		{
886cdf0e10cSrcweir 			if( !GetFollow() )
887cdf0e10cSrcweir 			{
888cdf0e10cSrcweir 				ASSERT( GetFollow(), "+SwTxtFrm::CalcPreps: no credits" );
889cdf0e10cSrcweir 				return sal_False;
890cdf0e10cSrcweir 			}
891cdf0e10cSrcweir 
892cdf0e10cSrcweir 			// Wir muessen uns auf zwei Faelle einstellen:
893cdf0e10cSrcweir 			// Wir konnten dem Follow noch ein paar Zeilen abgeben,
894cdf0e10cSrcweir 			// -> dann muessen wir schrumpfen
895cdf0e10cSrcweir 			// oder wir muessen auf die naechste Seite
896cdf0e10cSrcweir 			// -> dann lassen wir unseren Frame zu gross werden.
897cdf0e10cSrcweir 
898cdf0e10cSrcweir 			SwTwips nChgHeight = GetParHeight();
899cdf0e10cSrcweir             if( nChgHeight >= (Prt().*fnRect->fnGetHeight)() )
900cdf0e10cSrcweir 			{
901cdf0e10cSrcweir 				if( bPrepMustFit )
902cdf0e10cSrcweir 				{
903cdf0e10cSrcweir 					GetFollow()->SetJustWidow( sal_True );
904cdf0e10cSrcweir 					GetFollow()->Prepare( PREP_CLEAR );
905cdf0e10cSrcweir 				}
906cdf0e10cSrcweir                 else if ( bVert )
907cdf0e10cSrcweir 				{
908cdf0e10cSrcweir                     Frm().Width( Frm().Width() + Frm().Left() );
909cdf0e10cSrcweir                     Prt().Width( Prt().Width() + Frm().Left() );
910cdf0e10cSrcweir                     Frm().Left( 0 );
911cdf0e10cSrcweir 					SetWidow( sal_True );
912cdf0e10cSrcweir 				}
913cdf0e10cSrcweir                 else
914cdf0e10cSrcweir 				{
915cdf0e10cSrcweir 					SwTwips nTmp  = LONG_MAX - (Frm().Top()+10000);
916cdf0e10cSrcweir 					SwTwips nDiff = nTmp - Frm().Height();
917cdf0e10cSrcweir 					Frm().Height( nTmp );
918cdf0e10cSrcweir 					Prt().Height( Prt().Height() + nDiff );
919cdf0e10cSrcweir 					SetWidow( sal_True );
920cdf0e10cSrcweir 				}
921cdf0e10cSrcweir 			}
922cdf0e10cSrcweir 			else
923cdf0e10cSrcweir 			{
924cdf0e10cSrcweir                 ASSERT( nChgHeight < (Prt().*fnRect->fnGetHeight)(),
925cdf0e10cSrcweir 						"+SwTxtFrm::CalcPrep: wanna shrink" );
926cdf0e10cSrcweir 
927cdf0e10cSrcweir                 nChgHeight = (Prt().*fnRect->fnGetHeight)() - nChgHeight;
928cdf0e10cSrcweir 
929cdf0e10cSrcweir 				GetFollow()->SetJustWidow( sal_True );
930cdf0e10cSrcweir 				GetFollow()->Prepare( PREP_CLEAR );
931cdf0e10cSrcweir                 Shrink( nChgHeight );
932cdf0e10cSrcweir 				SwRect &rRepaint = *(pPara->GetRepaint());
933cdf0e10cSrcweir 
934cdf0e10cSrcweir                 if ( bVert )
935cdf0e10cSrcweir                 {
936cdf0e10cSrcweir                     SwRect aRepaint( Frm().Pos() + Prt().Pos(), Prt().SSize() );
937cdf0e10cSrcweir                     SwitchVerticalToHorizontal( aRepaint );
938cdf0e10cSrcweir                     rRepaint.Chg( aRepaint.Pos(), aRepaint.SSize() );
939cdf0e10cSrcweir                 }
940cdf0e10cSrcweir                 else
941cdf0e10cSrcweir                     rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
942cdf0e10cSrcweir 
943cdf0e10cSrcweir 				// 6792: Rrand < LRand und Repaint
944cdf0e10cSrcweir                 if( 0 >= rRepaint.Width() )
945cdf0e10cSrcweir 					rRepaint.Width(1);
946cdf0e10cSrcweir 			}
947cdf0e10cSrcweir 			bRet = sal_True;
948cdf0e10cSrcweir 		}
949cdf0e10cSrcweir 
950cdf0e10cSrcweir 		else if ( bPrepAdjust )
951cdf0e10cSrcweir 		{
952cdf0e10cSrcweir 			if ( HasFtn() )
953cdf0e10cSrcweir 			{
954cdf0e10cSrcweir 				if( !CalcPrepFtnAdjust() )
955cdf0e10cSrcweir 				{
956cdf0e10cSrcweir 					if( bPrepMustFit )
957cdf0e10cSrcweir 					{
958cdf0e10cSrcweir 						SwTxtLineAccess aAccess( this );
959cdf0e10cSrcweir 						aAccess.GetPara()->SetPrepMustFit( sal_True );
960cdf0e10cSrcweir 					}
961cdf0e10cSrcweir 					return sal_False;
962cdf0e10cSrcweir 				}
963cdf0e10cSrcweir 			}
964cdf0e10cSrcweir 
965cdf0e10cSrcweir             SWAP_IF_NOT_SWAPPED( this )
966cdf0e10cSrcweir 
967cdf0e10cSrcweir 			SwTxtFormatInfo aInf( this );
968cdf0e10cSrcweir 			SwTxtFormatter aLine( this, &aInf );
969cdf0e10cSrcweir 
970cdf0e10cSrcweir 			WidowsAndOrphans aFrmBreak( this );
971cdf0e10cSrcweir 			// Egal was die Attribute meinen, bei MustFit wird
972cdf0e10cSrcweir 			// der Absatz im Notfall trotzdem gesplittet...
973cdf0e10cSrcweir 			if( bPrepMustFit )
974cdf0e10cSrcweir 			{
975cdf0e10cSrcweir 				aFrmBreak.SetKeep( sal_False );
976cdf0e10cSrcweir 				aFrmBreak.ClrOrphLines();
977cdf0e10cSrcweir 			}
978cdf0e10cSrcweir 			// Bevor wir FormatAdjust aufrufen muessen wir dafuer
979cdf0e10cSrcweir 			// sorgen, dass die Zeilen, die unten raushaengen
980cdf0e10cSrcweir 			// auch tatsaechlich abgeschnitten werden.
981cdf0e10cSrcweir             // OD 2004-02-25 #i16128# - method renamed
982cdf0e10cSrcweir             sal_Bool bBreak = aFrmBreak.IsBreakNowWidAndOrp( aLine );
983cdf0e10cSrcweir 			bRet = sal_True;
984cdf0e10cSrcweir 			while( !bBreak && aLine.Next() )
985cdf0e10cSrcweir             {
986cdf0e10cSrcweir                 // OD 2004-02-25 #i16128# - method renamed
987cdf0e10cSrcweir                 bBreak = aFrmBreak.IsBreakNowWidAndOrp( aLine );
988cdf0e10cSrcweir             }
989cdf0e10cSrcweir 			if( bBreak )
990cdf0e10cSrcweir 			{
991cdf0e10cSrcweir 				// Es gibt Komplikationen: wenn TruncLines gerufen wird,
992cdf0e10cSrcweir 				// veraendern sich ploetzlich die Bedingungen in
993cdf0e10cSrcweir 				// IsInside, so dass IsBreakNow andere Ergebnisse
994cdf0e10cSrcweir 				// liefern kann. Aus diesem Grund wird rFrmBreak bekannt
995cdf0e10cSrcweir 				// gegeben, dass da wo rLine steht, das Ende erreicht
996cdf0e10cSrcweir 				// ist. Mal sehen, ob's klappt ...
997cdf0e10cSrcweir 				aLine.TruncLines();
998cdf0e10cSrcweir 				aFrmBreak.SetRstHeight( aLine );
999cdf0e10cSrcweir                 FormatAdjust( aLine, aFrmBreak, aInf.GetTxt().Len(), aInf.IsStop() );
1000cdf0e10cSrcweir 			}
1001cdf0e10cSrcweir 			else
1002cdf0e10cSrcweir 			{
1003cdf0e10cSrcweir 				if( !GetFollow() )
1004cdf0e10cSrcweir                 {
1005cdf0e10cSrcweir 					FormatAdjust( aLine, aFrmBreak,
1006cdf0e10cSrcweir                                   aInf.GetTxt().Len(), aInf.IsStop() );
1007cdf0e10cSrcweir                 }
1008cdf0e10cSrcweir 				else if ( !aFrmBreak.IsKeepAlways() )
1009cdf0e10cSrcweir 				{
1010cdf0e10cSrcweir 					// Siehe Bug: 2320
1011cdf0e10cSrcweir 					// Vor dem Master wird eine Zeile geloescht, der Follow
1012cdf0e10cSrcweir 					// koennte eine Zeile abgeben.
1013cdf0e10cSrcweir 					const SwCharRange aFollowRg( GetFollow()->GetOfst(), 1 );
1014cdf0e10cSrcweir 					*(pPara->GetReformat()) += aFollowRg;
1015cdf0e10cSrcweir 					// Es soll weitergehen!
1016cdf0e10cSrcweir 					bRet = sal_False;
1017cdf0e10cSrcweir 				}
1018cdf0e10cSrcweir 			}
1019cdf0e10cSrcweir 
1020cdf0e10cSrcweir             UNDO_SWAP( this )
1021cdf0e10cSrcweir             // Eine letzte Ueberpruefung, falls das FormatAdjust() nichts
1022cdf0e10cSrcweir 			// brachte, muessen wir amputieren.
1023cdf0e10cSrcweir 			if( bPrepMustFit )
1024cdf0e10cSrcweir 			{
1025cdf0e10cSrcweir                 const SwTwips nMust = (GetUpper()->*fnRect->fnGetPrtBottom)();
1026cdf0e10cSrcweir                 const SwTwips nIs   = (Frm().*fnRect->fnGetBottom)();
1027cdf0e10cSrcweir 
1028cdf0e10cSrcweir                 if( bVert && nIs < nMust )
1029cdf0e10cSrcweir                 {
1030cdf0e10cSrcweir                     Shrink( nMust - nIs );
1031cdf0e10cSrcweir                     if( Prt().Width() < 0 )
1032cdf0e10cSrcweir                         Prt().Width( 0 );
1033cdf0e10cSrcweir 					SetUndersized( sal_True );
1034cdf0e10cSrcweir                 }
1035cdf0e10cSrcweir                 else if ( ! bVert && nIs > nMust )
1036cdf0e10cSrcweir                 {
1037cdf0e10cSrcweir                     Shrink( nIs - nMust );
1038cdf0e10cSrcweir 					if( Prt().Height() < 0 )
1039cdf0e10cSrcweir 						Prt().Height( 0 );
1040cdf0e10cSrcweir 					SetUndersized( sal_True );
1041cdf0e10cSrcweir 				}
1042cdf0e10cSrcweir 			}
1043cdf0e10cSrcweir 		}
1044cdf0e10cSrcweir 	}
1045cdf0e10cSrcweir 	pPara->SetPrepMustFit( bPrepMustFit );
1046cdf0e10cSrcweir 	return bRet;
1047cdf0e10cSrcweir }
1048cdf0e10cSrcweir 
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir /*************************************************************************
1051cdf0e10cSrcweir  *						SwTxtFrm::FormatAdjust()
1052cdf0e10cSrcweir  *************************************************************************/
1053cdf0e10cSrcweir 
1054cdf0e10cSrcweir // Hier werden die Fussnoten und "als Zeichen"-gebundenen Objekte umgehaengt
1055cdf0e10cSrcweir #define CHG_OFFSET( pFrm, nNew )\
1056cdf0e10cSrcweir 	{\
1057cdf0e10cSrcweir 		if( pFrm->GetOfst() < nNew )\
1058cdf0e10cSrcweir 			pFrm->MoveFlyInCnt( this, 0, nNew );\
1059cdf0e10cSrcweir 		else if( pFrm->GetOfst() > nNew )\
1060cdf0e10cSrcweir 			MoveFlyInCnt( pFrm, nNew, STRING_LEN );\
1061cdf0e10cSrcweir 	}
1062cdf0e10cSrcweir 
FormatAdjust(SwTxtFormatter & rLine,WidowsAndOrphans & rFrmBreak,const xub_StrLen nStrLen,const sal_Bool bDummy)1063cdf0e10cSrcweir void SwTxtFrm::FormatAdjust( SwTxtFormatter &rLine,
1064cdf0e10cSrcweir 							 WidowsAndOrphans &rFrmBreak,
1065cdf0e10cSrcweir                              const xub_StrLen nStrLen,
1066cdf0e10cSrcweir                              const sal_Bool bDummy )
1067cdf0e10cSrcweir {
1068cdf0e10cSrcweir     SWAP_IF_NOT_SWAPPED( this )
1069cdf0e10cSrcweir 
1070cdf0e10cSrcweir     SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir 	xub_StrLen nEnd = rLine.GetStart();
1073cdf0e10cSrcweir 
1074cdf0e10cSrcweir 	sal_Bool bHasToFit = pPara->IsPrepMustFit();
1075cdf0e10cSrcweir 
1076cdf0e10cSrcweir 	// Das StopFlag wird durch Fussnoten gesetzt,
1077cdf0e10cSrcweir 	// die auf die naechste Seite wollen.
1078cdf0e10cSrcweir     // OD, FME 2004-03-03 - call base class method <SwTxtFrmBreak::IsBreakNow(..)>
1079cdf0e10cSrcweir     // instead of method <WidowsAndOrphans::IsBreakNow(..)> to get a break,
1080cdf0e10cSrcweir     // even if due to widow rule no enough lines exists.
1081cdf0e10cSrcweir     sal_uInt8 nNew = ( !GetFollow() &&
1082cdf0e10cSrcweir                        nEnd < nStrLen &&
1083cdf0e10cSrcweir                        ( rLine.IsStop() ||
1084cdf0e10cSrcweir                          ( bHasToFit
1085cdf0e10cSrcweir                            ? ( rLine.GetLineNr() > 1 &&
1086cdf0e10cSrcweir                                !rFrmBreak.IsInside( rLine ) )
1087cdf0e10cSrcweir                            : rFrmBreak.IsBreakNow( rLine ) ) ) )
1088cdf0e10cSrcweir                      ? 1 : 0;
1089cdf0e10cSrcweir     // --> OD #i84870#
1090cdf0e10cSrcweir     // no split of text frame, which only contains a as-character anchored object
1091cdf0e10cSrcweir     const bool bOnlyContainsAsCharAnchoredObj =
1092cdf0e10cSrcweir             !IsFollow() && nStrLen == 1 &&
1093cdf0e10cSrcweir             GetDrawObjs() && GetDrawObjs()->Count() == 1 &&
1094cdf0e10cSrcweir             (*GetDrawObjs())[0]->GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR;
1095cdf0e10cSrcweir     if ( nNew && bOnlyContainsAsCharAnchoredObj )
1096cdf0e10cSrcweir     {
1097cdf0e10cSrcweir         nNew = 0;
1098cdf0e10cSrcweir     }
1099cdf0e10cSrcweir     // <--
1100cdf0e10cSrcweir     if ( nNew )
1101cdf0e10cSrcweir 	{
1102cdf0e10cSrcweir 		SplitFrm( nEnd );
1103cdf0e10cSrcweir 	}
1104cdf0e10cSrcweir 
1105cdf0e10cSrcweir 	const SwFrm *pBodyFrm = (const SwFrm*)(FindBodyFrm());
1106cdf0e10cSrcweir 
1107cdf0e10cSrcweir     const long nBodyHeight = pBodyFrm ? ( IsVertical() ?
1108cdf0e10cSrcweir                                           pBodyFrm->Frm().Width() :
1109cdf0e10cSrcweir                                           pBodyFrm->Frm().Height() ) : 0;
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir 	// Wenn die aktuellen Werte berechnet wurden, anzeigen, dass
1112cdf0e10cSrcweir 	// sie jetzt gueltig sind.
1113cdf0e10cSrcweir 	*(pPara->GetReformat()) = SwCharRange();
1114cdf0e10cSrcweir 	sal_Bool bDelta = *pPara->GetDelta() != 0;
1115cdf0e10cSrcweir 	*(pPara->GetDelta()) = 0;
1116cdf0e10cSrcweir 
1117cdf0e10cSrcweir 	if( rLine.IsStop() )
1118cdf0e10cSrcweir 	{
1119cdf0e10cSrcweir 		rLine.TruncLines( sal_True );
1120cdf0e10cSrcweir 		nNew = 1;
1121cdf0e10cSrcweir 	}
1122cdf0e10cSrcweir 
1123cdf0e10cSrcweir 	// FindBreak schneidet die letzte Zeile ab.
1124cdf0e10cSrcweir 	if( !rFrmBreak.FindBreak( this, rLine, bHasToFit ) )
1125cdf0e10cSrcweir 	{
1126cdf0e10cSrcweir 		// Wenn wir bis zum Ende durchformatiert haben, wird nEnd auf das Ende
1127cdf0e10cSrcweir 		// gesetzt. In AdjustFollow wird dadurch ggf. JoinFrm() ausgefuehrt.
1128cdf0e10cSrcweir 		// Ansonsten ist nEnd das Ende der letzten Zeile im Master.
1129cdf0e10cSrcweir 		xub_StrLen nOld = nEnd;
1130cdf0e10cSrcweir 		nEnd = rLine.GetEnd();
1131cdf0e10cSrcweir 		if( GetFollow() )
1132cdf0e10cSrcweir 		{
1133cdf0e10cSrcweir 			if( nNew && nOld < nEnd )
1134cdf0e10cSrcweir 				RemoveFtn( nOld, nEnd - nOld );
1135cdf0e10cSrcweir 			CHG_OFFSET( GetFollow(), nEnd )
1136cdf0e10cSrcweir 			if( !bDelta )
1137cdf0e10cSrcweir 				GetFollow()->ManipOfst( nEnd );
1138cdf0e10cSrcweir 		}
1139cdf0e10cSrcweir 	}
1140cdf0e10cSrcweir 	else
1141cdf0e10cSrcweir 	{   // Wenn wir Zeilen abgeben, darf kein Join auf den Folows gerufen werden,
1142cdf0e10cSrcweir 		// im Gegenteil, es muss ggf. sogar ein Follow erzeugt werden.
1143cdf0e10cSrcweir 		// Dies muss auch geschehen, wenn die Textmasse komplett im Master
1144cdf0e10cSrcweir 		// bleibt, denn es k???nnte ja ein harter Zeilenumbruch noch eine weitere
1145cdf0e10cSrcweir 		// Zeile (ohne Textmassse) notwendig machen!
1146cdf0e10cSrcweir 		nEnd = rLine.GetEnd();
1147cdf0e10cSrcweir 		if( GetFollow() )
1148cdf0e10cSrcweir 		{
1149cdf0e10cSrcweir             // OD 21.03.2003 #108121# - Another case for not joining the follow:
1150cdf0e10cSrcweir             // Text frame has no content, but a numbering. Then, do *not* join.
1151cdf0e10cSrcweir             // Example of this case: When an empty, but numbered paragraph
1152cdf0e10cSrcweir             // at the end of page is completely displaced by a fly frame.
1153cdf0e10cSrcweir             // Thus, the text frame introduced a follow by a
1154cdf0e10cSrcweir             // <SwTxtFrm::SplitFrm(..)> - see below. The follow then shows
1155cdf0e10cSrcweir             // the numbering and must stay.
1156cdf0e10cSrcweir             if ( GetFollow()->GetOfst() != nEnd ||
1157cdf0e10cSrcweir                  GetFollow()->IsFieldFollow() ||
1158cdf0e10cSrcweir                  ( nStrLen == 0 && GetTxtNode()->GetNumRule() ) )
1159cdf0e10cSrcweir             {
1160cdf0e10cSrcweir 				nNew |= 3;
1161cdf0e10cSrcweir             }
1162cdf0e10cSrcweir 			CHG_OFFSET( GetFollow(), nEnd )
1163cdf0e10cSrcweir 			GetFollow()->ManipOfst( nEnd );
1164cdf0e10cSrcweir 		}
1165cdf0e10cSrcweir 		else
1166cdf0e10cSrcweir 		{
1167cdf0e10cSrcweir             // OD 21.03.2003 #108121# - Only split frame, if the frame contains
1168cdf0e10cSrcweir             // content or contains no content, but has a numbering.
1169cdf0e10cSrcweir             // OD #i84870# - no split, if text frame only contains one
1170cdf0e10cSrcweir             // as-character anchored object.
1171cdf0e10cSrcweir             if ( !bOnlyContainsAsCharAnchoredObj &&
1172cdf0e10cSrcweir                  ( nStrLen > 0 ||
1173cdf0e10cSrcweir                    ( nStrLen == 0 && GetTxtNode()->GetNumRule() ) )
1174cdf0e10cSrcweir                )
1175cdf0e10cSrcweir             {
1176cdf0e10cSrcweir                 SplitFrm( nEnd );
1177cdf0e10cSrcweir                 nNew |= 3;
1178cdf0e10cSrcweir             }
1179cdf0e10cSrcweir 		}
1180cdf0e10cSrcweir 		// Wenn sich die Resthoehe geaendert hat, z.B. durch RemoveFtn()
1181cdf0e10cSrcweir 		// dann muessen wir auffuellen, um Oszillationen zu vermeiden!
1182cdf0e10cSrcweir         if( bDummy && pBodyFrm &&
1183cdf0e10cSrcweir            nBodyHeight < ( IsVertical() ?
1184cdf0e10cSrcweir                            pBodyFrm->Frm().Width() :
1185cdf0e10cSrcweir                            pBodyFrm->Frm().Height() ) )
1186cdf0e10cSrcweir 			rLine.MakeDummyLine();
1187cdf0e10cSrcweir 	}
1188cdf0e10cSrcweir 
1189cdf0e10cSrcweir 	// In AdjustFrm() stellen wir uns selbst per Grow/Shrink ein,
1190cdf0e10cSrcweir 	// in AdjustFollow() stellen wir unseren FolgeFrame ein.
1191cdf0e10cSrcweir 
1192cdf0e10cSrcweir 	const SwTwips nDocPrtTop = Frm().Top() + Prt().Top();
1193cdf0e10cSrcweir 	const SwTwips nOldHeight = Prt().SSize().Height();
1194cdf0e10cSrcweir     SwTwips nChg = rLine.CalcBottomLine() - nDocPrtTop - nOldHeight;
1195cdf0e10cSrcweir     // --> OD #i84870# - no shrink of text frame, if it only contains one
1196cdf0e10cSrcweir     // as-character anchored object.
1197cdf0e10cSrcweir     if ( nChg < 0 &&
1198cdf0e10cSrcweir          bOnlyContainsAsCharAnchoredObj )
1199cdf0e10cSrcweir     {
1200cdf0e10cSrcweir         nChg = 0;
1201cdf0e10cSrcweir     }
1202cdf0e10cSrcweir     // <--
1203cdf0e10cSrcweir 
1204cdf0e10cSrcweir     // Vertical Formatting:
1205cdf0e10cSrcweir     // The (rotated) repaint rectangle's x coordinate referes to the frame.
1206cdf0e10cSrcweir     // If the frame grows (or shirks) the repaint rectangle cannot simply
1207cdf0e10cSrcweir     // be rotated back after formatting, because we use the upper left point
1208cdf0e10cSrcweir     // of the frame for rotation. This point changes when growing/shrinking.
1209cdf0e10cSrcweir 
1210cdf0e10cSrcweir     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1211cdf0e10cSrcweir     if ( IsVertical() && !IsVertLR() && nChg )
1212cdf0e10cSrcweir     {
1213cdf0e10cSrcweir         SwRect &rRepaint = *(pPara->GetRepaint());
1214cdf0e10cSrcweir         rRepaint.Left( rRepaint.Left() - nChg );
1215cdf0e10cSrcweir         rRepaint.Width( rRepaint.Width() - nChg );
1216cdf0e10cSrcweir     }
1217cdf0e10cSrcweir 
1218cdf0e10cSrcweir     AdjustFrm( nChg, bHasToFit );
1219cdf0e10cSrcweir 
1220cdf0e10cSrcweir /*
1221cdf0e10cSrcweir     // FME 16.07.2003 #i16930# - removed this code because it did not
1222cdf0e10cSrcweir     // work correctly. In SwCntntFrm::MakeAll, the frame did not move to the
1223cdf0e10cSrcweir     // next page, instead the print area was recalculated and
1224cdf0e10cSrcweir     // Prepare( PREP_POS_CHGD, (const void*)&bFormatted, sal_False ) invalidated
1225cdf0e10cSrcweir     // the other flags => loop
1226cdf0e10cSrcweir 
1227cdf0e10cSrcweir     // OD 04.04.2003 #108446# - handle special case:
1228cdf0e10cSrcweir     // If text frame contains no content and just has split, because of a
1229cdf0e10cSrcweir     // line stop, it has to move forward. To force this forward move without
1230cdf0e10cSrcweir     // unnecessary formatting of its footnotes and its follow, especially in
1231cdf0e10cSrcweir     // columned sections, adjust frame height to zero (0) and do not perform
1232cdf0e10cSrcweir     // the intrinsic format of the follow.
1233cdf0e10cSrcweir     // The formating method <SwCntntFrm::MakeAll()> will initiate the move forward.
1234cdf0e10cSrcweir     sal_Bool bForcedNoIntrinsicFollowCalc = sal_False;
1235cdf0e10cSrcweir     if ( nEnd == 0 &&
1236cdf0e10cSrcweir          rLine.IsStop() && HasFollow() && nNew == 1
1237cdf0e10cSrcweir        )
1238cdf0e10cSrcweir     {
1239cdf0e10cSrcweir         AdjustFrm( -Frm().SSize().Height(), bHasToFit );
1240cdf0e10cSrcweir         Prt().Pos().Y() = 0;
1241cdf0e10cSrcweir         Prt().Height( Frm().Height() );
1242cdf0e10cSrcweir         if ( FollowFormatAllowed() )
1243cdf0e10cSrcweir         {
1244cdf0e10cSrcweir             bForcedNoIntrinsicFollowCalc = sal_True;
1245cdf0e10cSrcweir             ForbidFollowFormat();
1246cdf0e10cSrcweir         }
1247cdf0e10cSrcweir     }
1248cdf0e10cSrcweir     else
1249cdf0e10cSrcweir     {
1250cdf0e10cSrcweir         AdjustFrm( nChg, bHasToFit );
1251cdf0e10cSrcweir     }
1252cdf0e10cSrcweir  */
1253cdf0e10cSrcweir 
1254cdf0e10cSrcweir     if( HasFollow() || IsInFtn() )
1255cdf0e10cSrcweir 		_AdjustFollow( rLine, nEnd, nStrLen, nNew );
1256cdf0e10cSrcweir 
1257cdf0e10cSrcweir     // FME 16.07.2003 #i16930# - removed this code because it did not work
1258cdf0e10cSrcweir     // correctly
1259cdf0e10cSrcweir     // OD 04.04.2003 #108446# - allow intrinsic format of follow, if above
1260cdf0e10cSrcweir     // special case has forbit it.
1261cdf0e10cSrcweir /*    if ( bForcedNoIntrinsicFollowCalc )
1262cdf0e10cSrcweir     {
1263cdf0e10cSrcweir         AllowFollowFormat();
1264cdf0e10cSrcweir     }
1265cdf0e10cSrcweir  */
1266cdf0e10cSrcweir 
1267cdf0e10cSrcweir     pPara->SetPrepMustFit( sal_False );
1268cdf0e10cSrcweir 
1269cdf0e10cSrcweir     UNDO_SWAP( this )
1270cdf0e10cSrcweir }
1271cdf0e10cSrcweir 
1272cdf0e10cSrcweir /*************************************************************************
1273cdf0e10cSrcweir  *						SwTxtFrm::FormatLine()
1274cdf0e10cSrcweir  *************************************************************************/
1275cdf0e10cSrcweir 
1276cdf0e10cSrcweir // bPrev zeigt an, ob Reformat.Start() wegen Prev() vorgezogen wurde.
1277cdf0e10cSrcweir // Man weiss sonst nicht, ob man Repaint weiter einschraenken kann oder nicht.
1278cdf0e10cSrcweir 
1279cdf0e10cSrcweir 
FormatLine(SwTxtFormatter & rLine,const sal_Bool bPrev)1280cdf0e10cSrcweir sal_Bool SwTxtFrm::FormatLine( SwTxtFormatter &rLine, const sal_Bool bPrev )
1281cdf0e10cSrcweir {
1282cdf0e10cSrcweir     ASSERT( ! IsVertical() || IsSwapped(),
1283cdf0e10cSrcweir             "SwTxtFrm::FormatLine( rLine, bPrev) with unswapped frame" );
1284cdf0e10cSrcweir 	SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1285cdf0e10cSrcweir 	// Nach rLine.FormatLine() haelt nStart den neuen Wert,
1286cdf0e10cSrcweir 	// waehrend in pOldStart der alte Offset gepflegt wird.
1287cdf0e10cSrcweir 	// Ueber diesen Weg soll das nDelta ersetzt werden.
1288cdf0e10cSrcweir 	// *pOldStart += rLine.GetCurr()->GetLen();
1289cdf0e10cSrcweir 	const SwLineLayout *pOldCur = rLine.GetCurr();
1290cdf0e10cSrcweir 	const xub_StrLen nOldLen    = pOldCur->GetLen();
1291cdf0e10cSrcweir 	const KSHORT nOldAscent = pOldCur->GetAscent();
1292cdf0e10cSrcweir 	const KSHORT nOldHeight = pOldCur->Height();
1293cdf0e10cSrcweir 	const SwTwips nOldWidth	= pOldCur->Width() + pOldCur->GetHangingMargin();
1294cdf0e10cSrcweir 	const sal_Bool bOldHyph = pOldCur->IsEndHyph();
1295cdf0e10cSrcweir 	SwTwips nOldTop = 0;
1296cdf0e10cSrcweir 	SwTwips nOldBottom = 0;
1297cdf0e10cSrcweir 	if( rLine.GetCurr()->IsClipping() )
1298cdf0e10cSrcweir 		rLine.CalcUnclipped( nOldTop, nOldBottom );
1299cdf0e10cSrcweir 
1300cdf0e10cSrcweir 	const xub_StrLen nNewStart = rLine.FormatLine( rLine.GetStart() );
1301cdf0e10cSrcweir 
1302cdf0e10cSrcweir     ASSERT( Frm().Pos().Y() + Prt().Pos().Y() == rLine.GetFirstPos(),
1303cdf0e10cSrcweir 			"SwTxtFrm::FormatLine: frame leaves orbit." );
1304cdf0e10cSrcweir 	ASSERT( rLine.GetCurr()->Height(),
1305cdf0e10cSrcweir 			"SwTxtFrm::FormatLine: line height is zero" );
1306cdf0e10cSrcweir 
1307cdf0e10cSrcweir 	// Das aktuelle Zeilenumbruchobjekt.
1308cdf0e10cSrcweir 	const SwLineLayout *pNew = rLine.GetCurr();
1309cdf0e10cSrcweir 
1310cdf0e10cSrcweir 	sal_Bool bUnChg = nOldLen == pNew->GetLen() &&
1311cdf0e10cSrcweir 				  bOldHyph == pNew->IsEndHyph();
1312cdf0e10cSrcweir 	if ( bUnChg && !bPrev )
1313cdf0e10cSrcweir 	{
1314cdf0e10cSrcweir 		// 6672: Toleranz von SLOPPY_TWIPS (5 Twips); vgl. 6922
1315cdf0e10cSrcweir 		const long nWidthDiff = nOldWidth > pNew->Width()
1316cdf0e10cSrcweir 								? nOldWidth - pNew->Width()
1317cdf0e10cSrcweir 								: pNew->Width() - nOldWidth;
1318cdf0e10cSrcweir 
1319cdf0e10cSrcweir         // we only declare a line as unchanged, if its main values have not
1320cdf0e10cSrcweir         // changed and it is not the last line (!paragraph end symbol!)
1321cdf0e10cSrcweir 		bUnChg = nOldHeight == pNew->Height() &&
1322cdf0e10cSrcweir 				 nOldAscent == pNew->GetAscent() &&
1323cdf0e10cSrcweir                  nWidthDiff <= SLOPPY_TWIPS &&
1324cdf0e10cSrcweir                  pOldCur->GetNext();
1325cdf0e10cSrcweir 	}
1326cdf0e10cSrcweir 
1327cdf0e10cSrcweir 	// rRepaint wird berechnet:
1328cdf0e10cSrcweir 	const SwTwips nBottom = rLine.Y() + rLine.GetLineHeight();
1329cdf0e10cSrcweir 	SwRepaint &rRepaint = *(pPara->GetRepaint());
1330cdf0e10cSrcweir 	if( bUnChg && rRepaint.Top() == rLine.Y()
1331cdf0e10cSrcweir 			   && (bPrev || nNewStart <= pPara->GetReformat()->Start())
1332cdf0e10cSrcweir 			   && ( nNewStart < GetTxtNode()->GetTxt().Len() ) )
1333cdf0e10cSrcweir 	{
1334cdf0e10cSrcweir 		rRepaint.Top( nBottom );
1335cdf0e10cSrcweir 		rRepaint.Height( 0 );
1336cdf0e10cSrcweir 	}
1337cdf0e10cSrcweir 	else
1338cdf0e10cSrcweir 	{
1339cdf0e10cSrcweir 		if( nOldTop )
1340cdf0e10cSrcweir 		{
1341cdf0e10cSrcweir 			if( nOldTop < rRepaint.Top() )
1342cdf0e10cSrcweir 				rRepaint.Top( nOldTop );
1343cdf0e10cSrcweir 			if( !rLine.IsUnclipped() || nOldBottom > rRepaint.Bottom() )
1344cdf0e10cSrcweir 			{
1345cdf0e10cSrcweir 				rRepaint.Bottom( nOldBottom - 1 );
1346cdf0e10cSrcweir 				rLine.SetUnclipped( sal_True );
1347cdf0e10cSrcweir 			}
1348cdf0e10cSrcweir 		}
1349cdf0e10cSrcweir 		if( rLine.GetCurr()->IsClipping() && rLine.IsFlyInCntBase() )
1350cdf0e10cSrcweir 		{
1351cdf0e10cSrcweir 			SwTwips nTmpTop, nTmpBottom;
1352cdf0e10cSrcweir 			rLine.CalcUnclipped( nTmpTop, nTmpBottom );
1353cdf0e10cSrcweir 			if( nTmpTop < rRepaint.Top() )
1354cdf0e10cSrcweir 				rRepaint.Top( nTmpTop );
1355cdf0e10cSrcweir 			if( !rLine.IsUnclipped() || nTmpBottom > rRepaint.Bottom() )
1356cdf0e10cSrcweir 			{
1357cdf0e10cSrcweir 				rRepaint.Bottom( nTmpBottom - 1 );
1358cdf0e10cSrcweir 				rLine.SetUnclipped( sal_True );
1359cdf0e10cSrcweir 			}
1360cdf0e10cSrcweir 		}
1361cdf0e10cSrcweir 		else
1362cdf0e10cSrcweir 		{
1363cdf0e10cSrcweir 			if( !rLine.IsUnclipped() || nBottom > rRepaint.Bottom() )
1364cdf0e10cSrcweir 			{
1365cdf0e10cSrcweir 				rRepaint.Bottom( nBottom - 1 );
1366cdf0e10cSrcweir 				rLine.SetUnclipped( sal_False );
1367cdf0e10cSrcweir 			}
1368cdf0e10cSrcweir 		}
1369cdf0e10cSrcweir 		SwTwips nRght = Max( nOldWidth, pNew->Width() +
1370cdf0e10cSrcweir 							 pNew->GetHangingMargin() );
1371cdf0e10cSrcweir 		ViewShell *pSh = getRootFrm()->GetCurrShell();
1372cdf0e10cSrcweir 		const SwViewOption *pOpt = pSh ? pSh->GetViewOptions() : 0;
1373cdf0e10cSrcweir 		if( pOpt && (pOpt->IsParagraph() || pOpt->IsLineBreak()) )
1374cdf0e10cSrcweir 			nRght += ( Max( nOldAscent, pNew->GetAscent() ) );
1375cdf0e10cSrcweir 		else
1376cdf0e10cSrcweir 			nRght += ( Max( nOldAscent, pNew->GetAscent() ) / 4);
1377cdf0e10cSrcweir 		nRght += rLine.GetLeftMargin();
1378cdf0e10cSrcweir 		if( rRepaint.GetOfst() || rRepaint.GetRightOfst() < nRght )
1379cdf0e10cSrcweir 			rRepaint.SetRightOfst( nRght );
1380cdf0e10cSrcweir 
1381cdf0e10cSrcweir         // Finally we enlarge the repaint rectangle if we found an underscore
1382cdf0e10cSrcweir         // within our line. 40 Twips should be enough
1383cdf0e10cSrcweir         const sal_Bool bHasUnderscore =
1384cdf0e10cSrcweir                 ( rLine.GetInfo().GetUnderScorePos() < nNewStart );
1385cdf0e10cSrcweir         if ( bHasUnderscore || rLine.GetCurr()->HasUnderscore() )
1386cdf0e10cSrcweir             rRepaint.Bottom( rRepaint.Bottom() + 40 );
1387cdf0e10cSrcweir 
1388cdf0e10cSrcweir         ((SwLineLayout*)rLine.GetCurr())->SetUnderscore( bHasUnderscore );
1389cdf0e10cSrcweir 	}
1390cdf0e10cSrcweir 	if( !bUnChg )
1391cdf0e10cSrcweir 		rLine.SetChanges();
1392cdf0e10cSrcweir 
1393cdf0e10cSrcweir 	// Die gute, alte nDelta-Berechnung:
1394cdf0e10cSrcweir 	*(pPara->GetDelta()) -= long(pNew->GetLen()) - long(nOldLen);
1395cdf0e10cSrcweir 
1396cdf0e10cSrcweir 	// Stop!
1397cdf0e10cSrcweir 	if( rLine.IsStop() )
1398cdf0e10cSrcweir 		return sal_False;
1399cdf0e10cSrcweir 
1400cdf0e10cSrcweir 	// Unbedingt noch eine Zeile
1401cdf0e10cSrcweir 	if( rLine.IsNewLine() )
1402cdf0e10cSrcweir 		return sal_True;
1403cdf0e10cSrcweir 
1404cdf0e10cSrcweir 	// bis zum Ende des Strings ?
1405cdf0e10cSrcweir 	if( nNewStart >= GetTxtNode()->GetTxt().Len() )
1406cdf0e10cSrcweir 		return sal_False;
1407cdf0e10cSrcweir 
1408cdf0e10cSrcweir 	if( rLine.GetInfo().IsShift() )
1409cdf0e10cSrcweir 		return sal_True;
1410cdf0e10cSrcweir 
1411cdf0e10cSrcweir 	// Ende des Reformats erreicht ?
1412cdf0e10cSrcweir 	const xub_StrLen nEnd = pPara->GetReformat()->Start() +
1413cdf0e10cSrcweir 						pPara->GetReformat()->Len();
1414cdf0e10cSrcweir 
1415cdf0e10cSrcweir 	if( nNewStart <= nEnd )
1416cdf0e10cSrcweir 		return sal_True;
1417cdf0e10cSrcweir 
1418cdf0e10cSrcweir 	return 0 != *(pPara->GetDelta());
1419cdf0e10cSrcweir }
1420cdf0e10cSrcweir 
1421cdf0e10cSrcweir /*************************************************************************
1422cdf0e10cSrcweir  *						SwTxtFrm::_Format()
1423cdf0e10cSrcweir  *************************************************************************/
1424cdf0e10cSrcweir 
_Format(SwTxtFormatter & rLine,SwTxtFormatInfo & rInf,const sal_Bool bAdjust)1425cdf0e10cSrcweir void SwTxtFrm::_Format( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf,
1426cdf0e10cSrcweir 						const sal_Bool bAdjust )
1427cdf0e10cSrcweir {
1428cdf0e10cSrcweir     ASSERT( ! IsVertical() || IsSwapped(),"SwTxtFrm::_Format with unswapped frame" );
1429cdf0e10cSrcweir 
1430cdf0e10cSrcweir     SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1431cdf0e10cSrcweir 	rLine.SetUnclipped( sal_False );
1432cdf0e10cSrcweir 
1433cdf0e10cSrcweir 	// Das war dem C30 zu kompliziert: aString( GetTxt() );
1434cdf0e10cSrcweir 	const XubString &rString = GetTxtNode()->GetTxt();
1435cdf0e10cSrcweir 	const xub_StrLen nStrLen = rString.Len();
1436cdf0e10cSrcweir 
1437cdf0e10cSrcweir 	SwCharRange &rReformat = *(pPara->GetReformat());
1438cdf0e10cSrcweir 	SwRepaint	&rRepaint = *(pPara->GetRepaint());
1439cdf0e10cSrcweir 	SwRepaint *pFreeze = NULL;
1440cdf0e10cSrcweir 
1441cdf0e10cSrcweir 	// Aus Performancegruenden wird in Init() rReformat auf STRING_LEN gesetzt.
1442cdf0e10cSrcweir 	// Fuer diesen Fall wird rReformat angepasst.
1443cdf0e10cSrcweir 	if( rReformat.Len() > nStrLen )
1444cdf0e10cSrcweir 		rReformat.Len() = nStrLen;
1445cdf0e10cSrcweir 
1446cdf0e10cSrcweir 	// Optimiert:
1447cdf0e10cSrcweir 	xub_StrLen nEnd = rReformat.Start() + rReformat.Len();
1448cdf0e10cSrcweir 	if( nEnd > nStrLen )
1449cdf0e10cSrcweir 	{
1450cdf0e10cSrcweir 		rReformat.Len() = nStrLen - rReformat.Start();
1451cdf0e10cSrcweir 		nEnd = nStrLen;
1452cdf0e10cSrcweir 	}
1453cdf0e10cSrcweir 
1454cdf0e10cSrcweir 	SwTwips nOldBottom;
1455cdf0e10cSrcweir 	if( GetOfst() && !IsFollow() )
1456cdf0e10cSrcweir 	{
1457cdf0e10cSrcweir 		rLine.Bottom();
1458cdf0e10cSrcweir 		nOldBottom = rLine.Y();
1459cdf0e10cSrcweir 		rLine.Top();
1460cdf0e10cSrcweir 	}
1461cdf0e10cSrcweir 	else
1462cdf0e10cSrcweir 		nOldBottom = 0;
1463cdf0e10cSrcweir 	rLine.CharToLine( rReformat.Start() );
1464cdf0e10cSrcweir 
1465cdf0e10cSrcweir 	// Worte koennen durch Fortfall oder Einfuegen eines Space
1466cdf0e10cSrcweir 	// auf die Zeile vor der editierten hinausgezogen werden,
1467cdf0e10cSrcweir 	// deshalb muss diese ebenfalls formatiert werden.
1468cdf0e10cSrcweir 	// Optimierung: Wenn rReformat erst hinter dem ersten Wort der
1469cdf0e10cSrcweir 	// Zeile beginnt, so kann diese Zeile die vorige nicht mehr beeinflussen.
1470cdf0e10cSrcweir 	// AMA: Leider doch, Textgroessenaenderungen + FlyFrames, die Rueckwirkung
1471cdf0e10cSrcweir 	// kann im Extremfall mehrere Zeilen (Frames!!!) betreffen!
1472cdf0e10cSrcweir 
1473cdf0e10cSrcweir     // --> FME 2005-04-18 #i46560#
1474cdf0e10cSrcweir     // FME: Yes, consider this case: (word ) has to go to the next line
1475cdf0e10cSrcweir     // because ) is a forbidden character at the beginning of a line although
1476cdf0e10cSrcweir     // (word would still fit on the previous line. Adding text right in front
1477cdf0e10cSrcweir     // of ) would not trigger a reformatting of the previous line. Adding 1
1478cdf0e10cSrcweir     // to the result of FindBrk() does not solve the problem in all cases,
1479cdf0e10cSrcweir     // nevertheless it should be sufficient.
1480cdf0e10cSrcweir     // <--
1481cdf0e10cSrcweir     sal_Bool bPrev = rLine.GetPrev() &&
1482cdf0e10cSrcweir                      ( FindBrk( rString, rLine.GetStart(), rReformat.Start() + 1 )
1483cdf0e10cSrcweir                        // --> FME 2005-04-18 #i46560#
1484cdf0e10cSrcweir                        + 1
1485cdf0e10cSrcweir                        // <--
1486cdf0e10cSrcweir                        >= rReformat.Start() ||
1487cdf0e10cSrcweir                        rLine.GetCurr()->IsRest() );
1488cdf0e10cSrcweir     if( bPrev )
1489cdf0e10cSrcweir 	{
1490cdf0e10cSrcweir 		while( rLine.Prev() )
1491cdf0e10cSrcweir 			if( rLine.GetCurr()->GetLen() && !rLine.GetCurr()->IsRest() )
1492cdf0e10cSrcweir 			{
1493cdf0e10cSrcweir 				if( !rLine.GetStart() )
1494cdf0e10cSrcweir 					rLine.Top(); // damit NumDone nicht durcheinander kommt
1495cdf0e10cSrcweir 				break;
1496cdf0e10cSrcweir 			}
1497cdf0e10cSrcweir 		xub_StrLen nNew = rLine.GetStart() + rLine.GetLength();
1498cdf0e10cSrcweir 		if( nNew )
1499cdf0e10cSrcweir 		{
1500cdf0e10cSrcweir 			--nNew;
1501cdf0e10cSrcweir 			if( CH_BREAK == rString.GetChar( nNew ) )
1502cdf0e10cSrcweir 			{
1503cdf0e10cSrcweir 				++nNew;
1504cdf0e10cSrcweir 				rLine.Next();
1505cdf0e10cSrcweir 				bPrev = sal_False;
1506cdf0e10cSrcweir 			}
1507cdf0e10cSrcweir 		}
1508cdf0e10cSrcweir 		rReformat.Len()  += rReformat.Start() - nNew;
1509cdf0e10cSrcweir 		rReformat.Start() = nNew;
1510cdf0e10cSrcweir 	}
1511cdf0e10cSrcweir 
1512cdf0e10cSrcweir 	rRepaint.SetOfst( 0 );
1513cdf0e10cSrcweir 	rRepaint.SetRightOfst( 0 );
1514cdf0e10cSrcweir 	rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
1515cdf0e10cSrcweir 	if( pPara->IsMargin() )
1516cdf0e10cSrcweir 		rRepaint.Width( rRepaint.Width() + pPara->GetHangingMargin() );
1517cdf0e10cSrcweir 	rRepaint.Top( rLine.Y() );
1518cdf0e10cSrcweir 	// 6792: Rrand < LRand und Repaint
1519cdf0e10cSrcweir 	if( 0 >= rRepaint.Width() )
1520cdf0e10cSrcweir 		rRepaint.Width(1);
1521cdf0e10cSrcweir 	WidowsAndOrphans aFrmBreak( this, rInf.IsTest() ? 1 : 0 );
1522cdf0e10cSrcweir 
1523cdf0e10cSrcweir 	// rLine steht jetzt auf der ersten Zeile, die formatiert werden
1524cdf0e10cSrcweir 	// muss. Das Flag bFirst sorgt dafuer, dass nicht Next() gerufen wird.
1525cdf0e10cSrcweir 	// Das ganze sieht verdreht aus, aber es muss sichergestellt werden,
1526cdf0e10cSrcweir 	// dass bei IsBreakNow rLine auf der Zeile zum stehen kommt, die
1527cdf0e10cSrcweir 	// nicht mehr passt.
1528cdf0e10cSrcweir 	sal_Bool bFirst  = sal_True;
1529cdf0e10cSrcweir 	sal_Bool bFormat = sal_True;
1530cdf0e10cSrcweir 
1531cdf0e10cSrcweir 	// 5383: Das CharToLine() kann uns auch in den roten Bereich fuehren.
1532cdf0e10cSrcweir 	// In diesem Fall muessen wir zurueckwandern, bis die Zeile, die
1533cdf0e10cSrcweir 	// nicht mehr passt in rLine eingestellt ist. Ansonsten geht Textmasse
1534cdf0e10cSrcweir 	// verloren, weil der Ofst im Follow falsch eingestellt wird.
1535cdf0e10cSrcweir 
1536cdf0e10cSrcweir     // OD 2004-02-25 #i16128# - method renamed
1537cdf0e10cSrcweir     sal_Bool bBreak = ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 )
1538cdf0e10cSrcweir                     && aFrmBreak.IsBreakNowWidAndOrp( rLine );
1539cdf0e10cSrcweir 	if( bBreak )
1540cdf0e10cSrcweir 	{
1541cdf0e10cSrcweir 		sal_Bool bPrevDone = 0 != rLine.Prev();
1542cdf0e10cSrcweir         // OD 2004-02-25 #i16128# - method renamed
1543cdf0e10cSrcweir         while( bPrevDone && aFrmBreak.IsBreakNowWidAndOrp(rLine) )
1544cdf0e10cSrcweir 			bPrevDone = 0 != rLine.Prev();
1545cdf0e10cSrcweir 		if( bPrevDone )
1546cdf0e10cSrcweir 		{
1547cdf0e10cSrcweir 			aFrmBreak.SetKeep( sal_False );
1548cdf0e10cSrcweir 			rLine.Next();
1549cdf0e10cSrcweir 		}
1550cdf0e10cSrcweir 		rLine.TruncLines();
1551cdf0e10cSrcweir 
1552cdf0e10cSrcweir 		// auf Nummer sicher:
1553cdf0e10cSrcweir         // OD 2004-02-25 #i16128# - method renamed
1554cdf0e10cSrcweir         bBreak = aFrmBreak.IsBreakNowWidAndOrp(rLine) &&
1555cdf0e10cSrcweir 				  ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 );
1556cdf0e10cSrcweir 	}
1557cdf0e10cSrcweir 
1558cdf0e10cSrcweir  /*	Bedeutung der folgenden Flags:
1559cdf0e10cSrcweir 	Ist das Watch(End/Mid)Hyph-Flag gesetzt, so muss formatiert werden, wenn
1560cdf0e10cSrcweir 	eine Trennung am (Zeilenende/Fly) vorliegt, sofern MaxHyph erreicht ist.
1561cdf0e10cSrcweir 	Das Jump(End/Mid)Flag bedeutet, dass die naechste Zeile, bei der keine
1562cdf0e10cSrcweir 	Trennung (Zeilenende/Fly) vorliegt, formatiert werden muss, da jetzt
1563cdf0e10cSrcweir 	umgebrochen werden koennte, was vorher moeglicherweise durch MaxHyph
1564cdf0e10cSrcweir 	verboten war.
1565cdf0e10cSrcweir 	Watch(End/Mid)Hyph wird gesetzt, wenn die letzte formatierte Zeile eine
1566cdf0e10cSrcweir 	Trennstelle erhalten hat, vorher aber keine hatte,
1567cdf0e10cSrcweir 	Jump(End/Mid)Hyph, wenn eine Trennstelle verschwindet.
1568cdf0e10cSrcweir  */
1569cdf0e10cSrcweir 	sal_Bool bJumpEndHyph  = sal_False,
1570cdf0e10cSrcweir 		 bWatchEndHyph = sal_False,
1571cdf0e10cSrcweir 		 bJumpMidHyph  = sal_False,
1572cdf0e10cSrcweir 		 bWatchMidHyph = sal_False;
1573cdf0e10cSrcweir 
1574cdf0e10cSrcweir 	const SwAttrSet& rAttrSet = GetTxtNode()->GetSwAttrSet();
1575cdf0e10cSrcweir 	sal_Bool bMaxHyph = ( 0 !=
1576cdf0e10cSrcweir 		( rInf.MaxHyph() = rAttrSet.GetHyphenZone().GetMaxHyphens() ) );
1577cdf0e10cSrcweir 	if ( bMaxHyph )
1578cdf0e10cSrcweir 		rLine.InitCntHyph();
1579cdf0e10cSrcweir 
1580cdf0e10cSrcweir     if( IsFollow() && IsFieldFollow() && rLine.GetStart() == GetOfst() )
1581cdf0e10cSrcweir     {
1582cdf0e10cSrcweir         const SwLineLayout* pLine;
1583cdf0e10cSrcweir         {
1584cdf0e10cSrcweir             SwTxtFrm *pMaster = FindMaster();
1585cdf0e10cSrcweir             ASSERT( pMaster, "SwTxtFrm::Format: homeless follow" );
1586cdf0e10cSrcweir             if( !pMaster->HasPara() )
1587cdf0e10cSrcweir                 pMaster->GetFormatted();
1588cdf0e10cSrcweir             SwTxtSizeInfo aInf( pMaster );
1589cdf0e10cSrcweir             SwTxtIter aMasterLine( pMaster, &aInf );
1590cdf0e10cSrcweir             aMasterLine.Bottom();
1591cdf0e10cSrcweir             pLine = aMasterLine.GetCurr();
1592cdf0e10cSrcweir         }
1593cdf0e10cSrcweir         SwLinePortion* pRest =
1594cdf0e10cSrcweir             rLine.MakeRestPortion( pLine, GetOfst() );
1595cdf0e10cSrcweir         if( pRest )
1596cdf0e10cSrcweir             rInf.SetRest( pRest );
1597cdf0e10cSrcweir         else
1598cdf0e10cSrcweir             SetFieldFollow( sal_False );
1599cdf0e10cSrcweir     }
1600cdf0e10cSrcweir 
1601cdf0e10cSrcweir 	/* Zum Abbruchkriterium:
1602cdf0e10cSrcweir 	 * Um zu erkennen, dass eine Zeile nicht mehr auf die Seite passt,
1603cdf0e10cSrcweir 	 * muss sie formatiert werden. Dieser Ueberhang wird z.B. in AdjustFollow
1604cdf0e10cSrcweir 	 * wieder entfernt.
1605cdf0e10cSrcweir 	 * Eine weitere Komplikation: wenn wir der Master sind, so muessen
1606cdf0e10cSrcweir 	 * wir die Zeilen durchgehen, da es ja sein kann, dass eine Zeile
1607cdf0e10cSrcweir 	 * vom Follow in den Master rutschen kann.
1608cdf0e10cSrcweir 	 */
1609cdf0e10cSrcweir 	do
1610cdf0e10cSrcweir 	{
1611cdf0e10cSrcweir 		DBG_LOOP;
1612cdf0e10cSrcweir 		if( bFirst )
1613cdf0e10cSrcweir 			bFirst = sal_False;
1614cdf0e10cSrcweir 		else
1615cdf0e10cSrcweir 		{
1616cdf0e10cSrcweir 			if ( bMaxHyph )
1617cdf0e10cSrcweir 			{
1618cdf0e10cSrcweir 				if ( rLine.GetCurr()->IsEndHyph() )
1619cdf0e10cSrcweir 					rLine.CntEndHyph()++;
1620cdf0e10cSrcweir 				else
1621cdf0e10cSrcweir 					rLine.CntEndHyph() = 0;
1622cdf0e10cSrcweir 				if ( rLine.GetCurr()->IsMidHyph() )
1623cdf0e10cSrcweir 					rLine.CntMidHyph()++;
1624cdf0e10cSrcweir 				else
1625cdf0e10cSrcweir 					rLine.CntMidHyph() = 0;
1626cdf0e10cSrcweir 			}
1627cdf0e10cSrcweir 			if( !rLine.Next() )
1628cdf0e10cSrcweir 			{
1629cdf0e10cSrcweir 				if( !bFormat )
1630cdf0e10cSrcweir                 {
1631cdf0e10cSrcweir             		SwLinePortion* pRest =
1632cdf0e10cSrcweir     					rLine.MakeRestPortion( rLine.GetCurr(),	rLine.GetEnd() );
1633cdf0e10cSrcweir             		if( pRest )
1634cdf0e10cSrcweir 			            rInf.SetRest( pRest );
1635cdf0e10cSrcweir                 }
1636cdf0e10cSrcweir 				rLine.Insert( new SwLineLayout() );
1637cdf0e10cSrcweir 				rLine.Next();
1638cdf0e10cSrcweir 				bFormat = sal_True;
1639cdf0e10cSrcweir 			}
1640cdf0e10cSrcweir 		}
1641cdf0e10cSrcweir 		if ( !bFormat && bMaxHyph &&
1642cdf0e10cSrcweir 			  (bWatchEndHyph || bJumpEndHyph || bWatchMidHyph || bJumpMidHyph) )
1643cdf0e10cSrcweir 		{
1644cdf0e10cSrcweir 			if ( rLine.GetCurr()->IsEndHyph() )
1645cdf0e10cSrcweir 			{
1646cdf0e10cSrcweir 				if ( bWatchEndHyph )
1647cdf0e10cSrcweir 					bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
1648cdf0e10cSrcweir 			}
1649cdf0e10cSrcweir 			else
1650cdf0e10cSrcweir 			{
1651cdf0e10cSrcweir 				bFormat = bJumpEndHyph;
1652cdf0e10cSrcweir 				bWatchEndHyph = sal_False;
1653cdf0e10cSrcweir 				bJumpEndHyph = sal_False;
1654cdf0e10cSrcweir 			}
1655cdf0e10cSrcweir 			if ( rLine.GetCurr()->IsMidHyph() )
1656cdf0e10cSrcweir 			{
1657cdf0e10cSrcweir 				if ( bWatchMidHyph && !bFormat )
1658cdf0e10cSrcweir 					bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
1659cdf0e10cSrcweir 			}
1660cdf0e10cSrcweir 			else
1661cdf0e10cSrcweir 			{
1662cdf0e10cSrcweir 				bFormat = bFormat || bJumpMidHyph;
1663cdf0e10cSrcweir 				bWatchMidHyph = sal_False;
1664cdf0e10cSrcweir 				bJumpMidHyph = sal_False;
1665cdf0e10cSrcweir 			}
1666cdf0e10cSrcweir 		}
1667cdf0e10cSrcweir 		if( bFormat )
1668cdf0e10cSrcweir 		{
1669cdf0e10cSrcweir 			sal_Bool bOldEndHyph = rLine.GetCurr()->IsEndHyph();
1670cdf0e10cSrcweir 			sal_Bool bOldMidHyph = rLine.GetCurr()->IsMidHyph();
1671cdf0e10cSrcweir 			bFormat = FormatLine( rLine, bPrev );
1672cdf0e10cSrcweir 			//9334: Es kann nur ein bPrev geben... (???)
1673cdf0e10cSrcweir 			bPrev = sal_False;
1674cdf0e10cSrcweir 			if ( bMaxHyph )
1675cdf0e10cSrcweir 			{
1676cdf0e10cSrcweir 				if ( rLine.GetCurr()->IsEndHyph() != bOldEndHyph )
1677cdf0e10cSrcweir 				{
1678cdf0e10cSrcweir 					bWatchEndHyph = !bOldEndHyph;
1679cdf0e10cSrcweir 					bJumpEndHyph = bOldEndHyph;
1680cdf0e10cSrcweir 				}
1681cdf0e10cSrcweir 				if ( rLine.GetCurr()->IsMidHyph() != bOldMidHyph )
1682cdf0e10cSrcweir 				{
1683cdf0e10cSrcweir 					bWatchMidHyph = !bOldMidHyph;
1684cdf0e10cSrcweir 					bJumpMidHyph = bOldMidHyph;
1685cdf0e10cSrcweir 				}
1686cdf0e10cSrcweir 			}
1687cdf0e10cSrcweir 		}
1688cdf0e10cSrcweir 
1689cdf0e10cSrcweir 		if( !rInf.IsNewLine() )
1690cdf0e10cSrcweir 		{
1691cdf0e10cSrcweir 			if( !bFormat )
1692cdf0e10cSrcweir 				 bFormat = 0 != rInf.GetRest();
1693cdf0e10cSrcweir 			if( rInf.IsStop() || rInf.GetIdx() >= nStrLen )
1694cdf0e10cSrcweir 				break;
1695cdf0e10cSrcweir 			if( !bFormat && ( !bMaxHyph || ( !bWatchEndHyph &&
1696cdf0e10cSrcweir 					!bJumpEndHyph && !bWatchMidHyph && !bJumpMidHyph ) ) )
1697cdf0e10cSrcweir 			{
1698cdf0e10cSrcweir 				if( GetFollow() )
1699cdf0e10cSrcweir 				{
1700cdf0e10cSrcweir 					while( rLine.Next() )
1701cdf0e10cSrcweir 						; //Nothing
1702cdf0e10cSrcweir 					pFreeze = new SwRepaint( rRepaint ); // to minimize painting
1703cdf0e10cSrcweir 				}
1704cdf0e10cSrcweir 				else
1705cdf0e10cSrcweir 					break;
1706cdf0e10cSrcweir 			}
1707cdf0e10cSrcweir 		}
1708cdf0e10cSrcweir         // OD 2004-02-25 #i16128# - method renamed
1709cdf0e10cSrcweir         bBreak = aFrmBreak.IsBreakNowWidAndOrp(rLine);
1710cdf0e10cSrcweir 	}while( !bBreak );
1711cdf0e10cSrcweir 
1712cdf0e10cSrcweir 	if( pFreeze )
1713cdf0e10cSrcweir 	{
1714cdf0e10cSrcweir 		rRepaint = *pFreeze;
1715cdf0e10cSrcweir 		delete pFreeze;
1716cdf0e10cSrcweir 	}
1717cdf0e10cSrcweir 
1718cdf0e10cSrcweir 	if( !rLine.IsStop() )
1719cdf0e10cSrcweir 	{
1720cdf0e10cSrcweir 		// Wurde aller Text formatiert und gibt es noch weitere
1721cdf0e10cSrcweir 		// Zeilenobjekte, dann sind diese jetzt ueberfluessig,
1722cdf0e10cSrcweir 		// weil der Text kuerzer geworden ist.
1723cdf0e10cSrcweir 		if( rLine.GetStart() + rLine.GetLength() >= nStrLen &&
1724cdf0e10cSrcweir 			rLine.GetCurr()->GetNext() )
1725cdf0e10cSrcweir 		{
1726cdf0e10cSrcweir 			rLine.TruncLines();
1727cdf0e10cSrcweir 			rLine.SetTruncLines( sal_True );
1728cdf0e10cSrcweir 		}
1729cdf0e10cSrcweir 	}
1730cdf0e10cSrcweir 
1731cdf0e10cSrcweir 	if( !rInf.IsTest() )
1732cdf0e10cSrcweir 	{
1733cdf0e10cSrcweir 		// Bei OnceMore lohnt sich kein FormatAdjust
1734cdf0e10cSrcweir 		if( bAdjust || !rLine.GetDropFmt() || !rLine.CalcOnceMore() )
1735cdf0e10cSrcweir         {
1736cdf0e10cSrcweir             FormatAdjust( rLine, aFrmBreak, nStrLen, rInf.IsStop() );
1737cdf0e10cSrcweir         }
1738cdf0e10cSrcweir 		if( rRepaint.HasArea() )
1739cdf0e10cSrcweir 			SetRepaint();
1740cdf0e10cSrcweir 		rLine.SetTruncLines( sal_False );
1741cdf0e10cSrcweir 		if( nOldBottom )                    // Bei "gescollten" Absaetzen wird
1742cdf0e10cSrcweir 		{                                   // noch ueberprueft, ob durch Schrumpfen
1743cdf0e10cSrcweir 			rLine.Bottom();					// das Scrolling ueberfluessig wurde.
1744cdf0e10cSrcweir 			SwTwips nNewBottom = rLine.Y();
1745cdf0e10cSrcweir 			if( nNewBottom < nOldBottom )
1746cdf0e10cSrcweir 				_SetOfst( 0 );
1747cdf0e10cSrcweir 		}
1748cdf0e10cSrcweir 	}
1749cdf0e10cSrcweir }
1750cdf0e10cSrcweir 
1751cdf0e10cSrcweir /*************************************************************************
1752cdf0e10cSrcweir  *						SwTxtFrm::Format()
1753cdf0e10cSrcweir  *************************************************************************/
1754cdf0e10cSrcweir 
FormatOnceMore(SwTxtFormatter & rLine,SwTxtFormatInfo & rInf)1755cdf0e10cSrcweir void SwTxtFrm::FormatOnceMore( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf )
1756cdf0e10cSrcweir {
1757cdf0e10cSrcweir     ASSERT( ! IsVertical() || IsSwapped(),
1758cdf0e10cSrcweir             "A frame is not swapped in SwTxtFrm::FormatOnceMore" );
1759cdf0e10cSrcweir 
1760cdf0e10cSrcweir 	SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1761cdf0e10cSrcweir 	if( !pPara )
1762cdf0e10cSrcweir 		return;
1763cdf0e10cSrcweir 
1764cdf0e10cSrcweir 	// ggf gegen pPara
1765cdf0e10cSrcweir 	KSHORT nOld  = ((const SwTxtMargin&)rLine).GetDropHeight();
1766cdf0e10cSrcweir 	sal_Bool bShrink = sal_False,
1767cdf0e10cSrcweir 		 bGrow   = sal_False,
1768cdf0e10cSrcweir 		 bGoOn   = rLine.IsOnceMore();
1769cdf0e10cSrcweir 	sal_uInt8 nGo	 = 0;
1770cdf0e10cSrcweir 	while( bGoOn )
1771cdf0e10cSrcweir 	{
1772cdf0e10cSrcweir #ifdef DBGTXT
1773cdf0e10cSrcweir 		aDbstream << "OnceMore!" << endl;
1774cdf0e10cSrcweir #endif
1775cdf0e10cSrcweir 		++nGo;
1776cdf0e10cSrcweir 		rInf.Init();
1777cdf0e10cSrcweir 		rLine.Top();
1778cdf0e10cSrcweir 		if( !rLine.GetDropFmt() )
1779cdf0e10cSrcweir 			rLine.SetOnceMore( sal_False );
1780cdf0e10cSrcweir 		SwCharRange aRange( 0, rInf.GetTxt().Len() );
1781cdf0e10cSrcweir 		*(pPara->GetReformat()) = aRange;
1782cdf0e10cSrcweir 		_Format( rLine, rInf );
1783cdf0e10cSrcweir 
1784cdf0e10cSrcweir 		bGoOn = rLine.IsOnceMore();
1785cdf0e10cSrcweir 		if( bGoOn )
1786cdf0e10cSrcweir 		{
1787cdf0e10cSrcweir 			const KSHORT nNew = ((const SwTxtMargin&)rLine).GetDropHeight();
1788cdf0e10cSrcweir 			if( nOld == nNew )
1789cdf0e10cSrcweir 				bGoOn = sal_False;
1790cdf0e10cSrcweir 			else
1791cdf0e10cSrcweir 			{
1792cdf0e10cSrcweir 				if( nOld > nNew )
1793cdf0e10cSrcweir 					bShrink = sal_True;
1794cdf0e10cSrcweir 				else
1795cdf0e10cSrcweir 					bGrow = sal_True;
1796cdf0e10cSrcweir 
1797cdf0e10cSrcweir 				if( bShrink == bGrow || 5 < nGo )
1798cdf0e10cSrcweir 					bGoOn = sal_False;
1799cdf0e10cSrcweir 
1800cdf0e10cSrcweir 				nOld = nNew;
1801cdf0e10cSrcweir 			}
1802cdf0e10cSrcweir 
1803cdf0e10cSrcweir 			// 6107: Wenn was schief ging, muss noch einmal formatiert werden.
1804cdf0e10cSrcweir 			if( !bGoOn )
1805cdf0e10cSrcweir 			{
1806cdf0e10cSrcweir 				rInf.CtorInitTxtFormatInfo( this );
1807cdf0e10cSrcweir 				rLine.CtorInitTxtFormatter( this, &rInf );
1808cdf0e10cSrcweir 				rLine.SetDropLines( 1 );
1809cdf0e10cSrcweir 				rLine.CalcDropHeight( 1 );
1810cdf0e10cSrcweir                 SwCharRange aTmpRange( 0, rInf.GetTxt().Len() );
1811cdf0e10cSrcweir                 *(pPara->GetReformat()) = aTmpRange;
1812cdf0e10cSrcweir 				_Format( rLine, rInf, sal_True );
1813cdf0e10cSrcweir 				// 8047: Wir painten alles...
1814cdf0e10cSrcweir 				SetCompletePaint();
1815cdf0e10cSrcweir 			}
1816cdf0e10cSrcweir 		}
1817cdf0e10cSrcweir 	}
1818cdf0e10cSrcweir }
1819cdf0e10cSrcweir 
1820cdf0e10cSrcweir /*************************************************************************
1821cdf0e10cSrcweir  *						SwTxtFrm::_Format()
1822cdf0e10cSrcweir  *************************************************************************/
1823cdf0e10cSrcweir 
1824cdf0e10cSrcweir 
_Format(SwParaPortion * pPara)1825cdf0e10cSrcweir void SwTxtFrm::_Format( SwParaPortion *pPara )
1826cdf0e10cSrcweir {
1827cdf0e10cSrcweir 	const xub_StrLen nStrLen = GetTxt().Len();
1828cdf0e10cSrcweir 
1829cdf0e10cSrcweir 	// AMA: Wozu soll das gut sein? Scheint mir zuoft zu einem kompletten
1830cdf0e10cSrcweir 	// Formatieren und Repainten zu fuehren???
1831cdf0e10cSrcweir //	if ( !(*pPara->GetDelta()) )
1832cdf0e10cSrcweir //		*(pPara->GetDelta()) = nStrLen;
1833cdf0e10cSrcweir //	else
1834cdf0e10cSrcweir 	if ( !nStrLen )
1835cdf0e10cSrcweir 	{
1836cdf0e10cSrcweir 		// Leere Zeilen werden nicht lange gequaelt:
1837cdf0e10cSrcweir 		// pPara wird blank geputzt
1838cdf0e10cSrcweir 		// entspricht *pPara = SwParaPortion;
1839cdf0e10cSrcweir 		sal_Bool bMustFit = pPara->IsPrepMustFit();
1840cdf0e10cSrcweir 		pPara->Truncate();
1841cdf0e10cSrcweir 		pPara->FormatReset();
1842cdf0e10cSrcweir 		if( pBlink && pPara->IsBlinking() )
1843cdf0e10cSrcweir 			pBlink->Delete( pPara );
1844cdf0e10cSrcweir 
1845cdf0e10cSrcweir         // delete pSpaceAdd und pKanaComp
1846cdf0e10cSrcweir         pPara->FinishSpaceAdd();
1847cdf0e10cSrcweir         pPara->FinishKanaComp();
1848cdf0e10cSrcweir 		pPara->ResetFlags();
1849cdf0e10cSrcweir 		pPara->SetPrepMustFit( bMustFit );
1850cdf0e10cSrcweir 	}
1851cdf0e10cSrcweir 
1852cdf0e10cSrcweir     ASSERT( ! IsSwapped(), "A frame is swapped before _Format" );
1853cdf0e10cSrcweir 
1854cdf0e10cSrcweir     if ( IsVertical() )
1855cdf0e10cSrcweir         SwapWidthAndHeight();
1856cdf0e10cSrcweir 
1857cdf0e10cSrcweir     SwTxtFormatInfo aInf( this );
1858cdf0e10cSrcweir 	SwTxtFormatter	aLine( this, &aInf );
1859cdf0e10cSrcweir 
1860cdf0e10cSrcweir     // OD 2004-01-15 #110582#
1861cdf0e10cSrcweir     HideAndShowObjects();
1862cdf0e10cSrcweir 
1863cdf0e10cSrcweir     _Format( aLine, aInf );
1864cdf0e10cSrcweir 
1865cdf0e10cSrcweir 	if( aLine.IsOnceMore() )
1866cdf0e10cSrcweir 		FormatOnceMore( aLine, aInf );
1867cdf0e10cSrcweir 
1868cdf0e10cSrcweir     if ( IsVertical() )
1869cdf0e10cSrcweir         SwapWidthAndHeight();
1870cdf0e10cSrcweir 
1871cdf0e10cSrcweir     ASSERT( ! IsSwapped(), "A frame is swapped after _Format" );
1872cdf0e10cSrcweir 
1873cdf0e10cSrcweir     if( 1 < aLine.GetDropLines() )
1874cdf0e10cSrcweir 	{
1875cdf0e10cSrcweir 		if( SVX_ADJUST_LEFT != aLine.GetAdjust() &&
1876cdf0e10cSrcweir 			SVX_ADJUST_BLOCK != aLine.GetAdjust() )
1877cdf0e10cSrcweir 		{
1878cdf0e10cSrcweir 			aLine.CalcDropAdjust();
1879cdf0e10cSrcweir 			aLine.SetPaintDrop( sal_True );
1880cdf0e10cSrcweir 		}
1881cdf0e10cSrcweir 
1882cdf0e10cSrcweir 		if( aLine.IsPaintDrop() )
1883cdf0e10cSrcweir 		{
1884cdf0e10cSrcweir 			aLine.CalcDropRepaint();
1885cdf0e10cSrcweir 			aLine.SetPaintDrop( sal_False );
1886cdf0e10cSrcweir 		}
1887cdf0e10cSrcweir 	}
1888cdf0e10cSrcweir }
1889cdf0e10cSrcweir 
1890cdf0e10cSrcweir /*************************************************************************
1891cdf0e10cSrcweir  *						SwTxtFrm::Format()
1892cdf0e10cSrcweir  *************************************************************************/
1893cdf0e10cSrcweir 
1894cdf0e10cSrcweir /*
1895cdf0e10cSrcweir  * Format berechnet die Groesse des Textframes und ruft, wenn
1896cdf0e10cSrcweir  * diese feststeht, Shrink() oder Grow(), um die Framegroesse dem
1897cdf0e10cSrcweir  * evtl. veraenderten Platzbedarf anzupassen.
1898cdf0e10cSrcweir  */
1899cdf0e10cSrcweir 
Format(const SwBorderAttrs *)1900cdf0e10cSrcweir void SwTxtFrm::Format( const SwBorderAttrs * )
1901cdf0e10cSrcweir {
1902cdf0e10cSrcweir 	DBG_LOOP;
1903cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1904cdf0e10cSrcweir 	const XubString aXXX = GetTxtNode()->GetTxt();
1905cdf0e10cSrcweir 	const SwTwips nDbgY = Frm().Top();
1906cdf0e10cSrcweir     (void)nDbgY;
1907cdf0e10cSrcweir 	const SwPageFrm *pDbgPage = FindPageFrm();
1908cdf0e10cSrcweir 	const MSHORT nDbgPageNr = pDbgPage->GetPhyPageNum();
1909cdf0e10cSrcweir     (void)nDbgPageNr;
1910cdf0e10cSrcweir 	// Um zu gucken, ob es einen Ftn-Bereich gibt.
1911cdf0e10cSrcweir 	const SwFrm *pDbgFtnCont = (const SwFrm*)(FindPageFrm()->FindFtnCont());
1912cdf0e10cSrcweir     (void)pDbgFtnCont;
1913cdf0e10cSrcweir 
1914cdf0e10cSrcweir #ifdef DBG_UTIL
1915cdf0e10cSrcweir 	// nStopAt laesst sich vom CV bearbeiten.
1916cdf0e10cSrcweir 	static MSHORT nStopAt = 0;
1917cdf0e10cSrcweir 	if( nStopAt == GetFrmId() )
1918cdf0e10cSrcweir 	{
1919cdf0e10cSrcweir 		int i = GetFrmId();
1920cdf0e10cSrcweir         (void)i;
1921cdf0e10cSrcweir 	}
1922cdf0e10cSrcweir #endif
1923cdf0e10cSrcweir #endif
1924cdf0e10cSrcweir 
1925cdf0e10cSrcweir #ifdef DEBUG_FTN
1926cdf0e10cSrcweir 	//Fussnote darf nicht auf einer Seite vor ihrer Referenz stehen.
1927cdf0e10cSrcweir 	if( IsInFtn() )
1928cdf0e10cSrcweir 	{
1929cdf0e10cSrcweir 		const SwFtnFrm *pFtn = (SwFtnFrm*)GetUpper();
1930cdf0e10cSrcweir 		const SwPageFrm *pFtnPage = pFtn->GetRef()->FindPageFrm();
1931cdf0e10cSrcweir 		const MSHORT nFtnPageNr = pFtnPage->GetPhyPageNum();
1932cdf0e10cSrcweir 		if( !IsLocked() )
1933cdf0e10cSrcweir 		{
1934cdf0e10cSrcweir 			if( nFtnPageNr > nDbgPageNr )
1935cdf0e10cSrcweir 			{
1936cdf0e10cSrcweir 				SwTxtFrmLocker aLock(this);
1937cdf0e10cSrcweir 				ASSERT( nFtnPageNr <= nDbgPageNr, "!Ftn steht vor der Referenz." );
1938cdf0e10cSrcweir 				MSHORT i = 0;
1939cdf0e10cSrcweir 			}
1940cdf0e10cSrcweir 		}
1941cdf0e10cSrcweir 	}
1942cdf0e10cSrcweir #endif
1943cdf0e10cSrcweir 
1944cdf0e10cSrcweir     SWRECTFN( this )
1945cdf0e10cSrcweir 
1946cdf0e10cSrcweir     // --> OD 2008-01-31 #newlistlevelattrs#
1947cdf0e10cSrcweir     CalcAdditionalFirstLineOffset();
1948cdf0e10cSrcweir     // <--
1949cdf0e10cSrcweir 
1950cdf0e10cSrcweir     // Vom Berichtsautopiloten oder ueber die BASIC-Schnittstelle kommen
1951cdf0e10cSrcweir     // gelegentlich TxtFrms mit einer Breite <=0.
1952cdf0e10cSrcweir     if( (Prt().*fnRect->fnGetWidth)() <= 0 )
1953cdf0e10cSrcweir     {
1954cdf0e10cSrcweir         // Wenn MustFit gesetzt ist, schrumpfen wir ggf. auf die Unterkante
1955cdf0e10cSrcweir         // des Uppers, ansonsten nehmen wir einfach eine Standardgroesse
1956cdf0e10cSrcweir         // von 12 Pt. ein (240 Twip).
1957cdf0e10cSrcweir         SwTxtLineAccess aAccess( this );
1958cdf0e10cSrcweir         long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1959cdf0e10cSrcweir         if( aAccess.GetPara()->IsPrepMustFit() )
1960cdf0e10cSrcweir         {
1961cdf0e10cSrcweir             const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)();
1962cdf0e10cSrcweir             const SwTwips nDiff = - (Frm().*fnRect->fnBottomDist)( nLimit );
1963cdf0e10cSrcweir             if( nDiff > 0 )
1964cdf0e10cSrcweir                 Shrink( nDiff );
1965cdf0e10cSrcweir         }
1966cdf0e10cSrcweir         else if( 240 < nFrmHeight )
1967cdf0e10cSrcweir             Shrink( nFrmHeight - 240 );
1968cdf0e10cSrcweir         else if( 240 > nFrmHeight )
1969cdf0e10cSrcweir             Grow( 240 - nFrmHeight );
1970cdf0e10cSrcweir         nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1971cdf0e10cSrcweir 
1972cdf0e10cSrcweir         long nTop = (this->*fnRect->fnGetTopMargin)();
1973cdf0e10cSrcweir         if( nTop > nFrmHeight )
1974cdf0e10cSrcweir             (this->*fnRect->fnSetYMargins)( nFrmHeight, 0 );
1975cdf0e10cSrcweir         else if( (Prt().*fnRect->fnGetHeight)() < 0 )
1976cdf0e10cSrcweir             (Prt().*fnRect->fnSetHeight)( 0 );
1977cdf0e10cSrcweir         return;
1978cdf0e10cSrcweir     }
1979cdf0e10cSrcweir 
1980cdf0e10cSrcweir     const xub_StrLen nStrLen = GetTxtNode()->GetTxt().Len();
1981cdf0e10cSrcweir     if ( nStrLen || !FormatEmpty() )
1982cdf0e10cSrcweir     {
1983cdf0e10cSrcweir 
1984cdf0e10cSrcweir         SetEmpty( sal_False );
1985cdf0e10cSrcweir         // Um nicht durch verschachtelte Formats irritiert zu werden.
1986cdf0e10cSrcweir         FormatLevel aLevel;
1987cdf0e10cSrcweir         if( 12 == aLevel.GetLevel() )
1988cdf0e10cSrcweir             return;
1989cdf0e10cSrcweir 
1990cdf0e10cSrcweir         // Die Formatinformationen duerfen u.U. nicht veraendert werden.
1991cdf0e10cSrcweir         if( IsLocked() )
1992cdf0e10cSrcweir             return;
1993cdf0e10cSrcweir 
1994cdf0e10cSrcweir         // 8708: Vorsicht, das Format() kann auch durch GetFormatted()
1995cdf0e10cSrcweir         // angestossen werden.
1996cdf0e10cSrcweir         if( IsHiddenNow() )
1997cdf0e10cSrcweir         {
1998cdf0e10cSrcweir             long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1999cdf0e10cSrcweir             if( nPrtHeight )
2000cdf0e10cSrcweir             {
2001cdf0e10cSrcweir                 HideHidden();
2002cdf0e10cSrcweir                 Shrink( nPrtHeight );
2003cdf0e10cSrcweir             }
2004cdf0e10cSrcweir             else
2005cdf0e10cSrcweir             {
2006cdf0e10cSrcweir                 // OD 2004-01-20 #110582# - assure that objects anchored
2007cdf0e10cSrcweir                 // at paragraph resp. at/as character inside paragraph
2008cdf0e10cSrcweir                 // are hidden.
2009cdf0e10cSrcweir                 HideAndShowObjects();
2010cdf0e10cSrcweir             }
2011cdf0e10cSrcweir             ChgThisLines();
2012cdf0e10cSrcweir             return;
2013cdf0e10cSrcweir         }
2014cdf0e10cSrcweir 
2015cdf0e10cSrcweir         // Waehrend wir formatieren, wollen wir nicht gestoert werden.
2016cdf0e10cSrcweir         SwTxtFrmLocker aLock(this);
2017cdf0e10cSrcweir         SwTxtLineAccess aAccess( this );
2018cdf0e10cSrcweir         const sal_Bool bNew = !aAccess.SwTxtLineAccess::IsAvailable();
2019cdf0e10cSrcweir         const sal_Bool bSetOfst = ( GetOfst() && GetOfst() > GetTxtNode()->GetTxt().Len() );
2020cdf0e10cSrcweir 
2021cdf0e10cSrcweir         if( CalcPreps() )
2022cdf0e10cSrcweir             ; // nothing
2023cdf0e10cSrcweir         // Wir returnen, wenn schon formatiert wurde, nicht aber, wenn
2024cdf0e10cSrcweir         // der TxtFrm gerade erzeugt wurde und ueberhaupt keine Format-
2025cdf0e10cSrcweir         // informationen vorliegen.
2026cdf0e10cSrcweir         else if( !bNew && !aAccess.GetPara()->GetReformat()->Len() )
2027cdf0e10cSrcweir         {
2028cdf0e10cSrcweir             if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
2029cdf0e10cSrcweir             {
2030cdf0e10cSrcweir                 aAccess.GetPara()->SetPrepAdjust( sal_True );
2031cdf0e10cSrcweir                 aAccess.GetPara()->SetPrep( sal_True );
2032cdf0e10cSrcweir                 CalcPreps();
2033cdf0e10cSrcweir             }
2034cdf0e10cSrcweir             SetWidow( sal_False );
2035cdf0e10cSrcweir         }
2036cdf0e10cSrcweir         else if( bSetOfst && IsFollow() )
2037cdf0e10cSrcweir         {
2038cdf0e10cSrcweir             SwTxtFrm *pMaster = FindMaster();
2039cdf0e10cSrcweir             ASSERT( pMaster, "SwTxtFrm::Format: homeless follow" );
2040cdf0e10cSrcweir             if( pMaster )
2041cdf0e10cSrcweir                 pMaster->Prepare( PREP_FOLLOW_FOLLOWS );
2042cdf0e10cSrcweir             SwTwips nMaxY = (GetUpper()->*fnRect->fnGetPrtBottom)();
2043cdf0e10cSrcweir             if( (Frm().*fnRect->fnOverStep)( nMaxY  ) )
2044cdf0e10cSrcweir                 (this->*fnRect->fnSetLimit)( nMaxY );
2045cdf0e10cSrcweir             else if( (Frm().*fnRect->fnBottomDist)( nMaxY  ) < 0 )
2046cdf0e10cSrcweir                 (Frm().*fnRect->fnAddBottom)( -(Frm().*fnRect->fnGetHeight)() );
2047cdf0e10cSrcweir         }
2048cdf0e10cSrcweir         else
2049cdf0e10cSrcweir         {
2050cdf0e10cSrcweir             // bSetOfst here means that we have the "red arrow situation"
2051cdf0e10cSrcweir             if ( bSetOfst )
2052cdf0e10cSrcweir                 _SetOfst( 0 );
2053cdf0e10cSrcweir 
2054cdf0e10cSrcweir             const sal_Bool bOrphan = IsWidow();
2055cdf0e10cSrcweir             const SwFtnBossFrm* pFtnBoss = HasFtn() ? FindFtnBossFrm() : 0;
2056cdf0e10cSrcweir             SwTwips nFtnHeight = 0;
2057cdf0e10cSrcweir             if( pFtnBoss )
2058cdf0e10cSrcweir             {
2059cdf0e10cSrcweir                 const SwFtnContFrm* pCont = pFtnBoss->FindFtnCont();
2060cdf0e10cSrcweir                 nFtnHeight = pCont ? (pCont->Frm().*fnRect->fnGetHeight)() : 0;
2061cdf0e10cSrcweir             }
2062cdf0e10cSrcweir             do
2063cdf0e10cSrcweir             {
2064cdf0e10cSrcweir                 _Format( aAccess.GetPara() );
2065cdf0e10cSrcweir                 if( pFtnBoss && nFtnHeight )
2066cdf0e10cSrcweir                 {
2067cdf0e10cSrcweir                     const SwFtnContFrm* pCont = pFtnBoss->FindFtnCont();
2068cdf0e10cSrcweir                     SwTwips nNewHeight = pCont ? (pCont->Frm().*fnRect->fnGetHeight)() : 0;
2069cdf0e10cSrcweir                     // If we lost some footnotes, we may have more space
2070cdf0e10cSrcweir                     // for our main text, so we have to format again ...
2071cdf0e10cSrcweir                     if( nNewHeight < nFtnHeight )
2072cdf0e10cSrcweir                         nFtnHeight = nNewHeight;
2073cdf0e10cSrcweir                     else
2074cdf0e10cSrcweir                         break;
2075cdf0e10cSrcweir                 }
2076cdf0e10cSrcweir                 else
2077cdf0e10cSrcweir                     break;
2078cdf0e10cSrcweir             } while ( pFtnBoss );
2079cdf0e10cSrcweir             if( bOrphan )
2080cdf0e10cSrcweir             {
2081cdf0e10cSrcweir                 ValidateFrm();
2082cdf0e10cSrcweir                 SetWidow( sal_False );
2083cdf0e10cSrcweir             }
2084cdf0e10cSrcweir         }
2085cdf0e10cSrcweir         if( IsEmptyMaster() )
2086cdf0e10cSrcweir         {
2087cdf0e10cSrcweir             SwFrm* pPre = GetPrev();
2088cdf0e10cSrcweir             if( pPre &&
2089cdf0e10cSrcweir                 // --> FME 2004-07-22 #i10826# It's the first, it cannot keep!
2090cdf0e10cSrcweir                 pPre->GetIndPrev() &&
2091cdf0e10cSrcweir                 // <--
2092cdf0e10cSrcweir                 pPre->GetAttrSet()->GetKeep().GetValue() )
2093cdf0e10cSrcweir             {
2094cdf0e10cSrcweir                 pPre->InvalidatePos();
2095cdf0e10cSrcweir             }
2096cdf0e10cSrcweir         }
2097cdf0e10cSrcweir     }
2098cdf0e10cSrcweir 
2099cdf0e10cSrcweir 	ChgThisLines();
2100cdf0e10cSrcweir 
2101cdf0e10cSrcweir     // the PrepMustFit should not survive a Format operation
2102cdf0e10cSrcweir     SwParaPortion *pPara = GetPara();
2103cdf0e10cSrcweir 	if ( pPara )
2104cdf0e10cSrcweir        	pPara->SetPrepMustFit( sal_False );
2105cdf0e10cSrcweir 
2106cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2107cdf0e10cSrcweir 	// Hier ein Instrumentarium, um ungewoehnlichen Master/Follow-Kombinationen,
2108cdf0e10cSrcweir 	// insbesondere bei Fussnoten, auf die Schliche zu kommen
2109cdf0e10cSrcweir 	if( IsFollow() || GetFollow() )
2110cdf0e10cSrcweir 	{
2111cdf0e10cSrcweir 		SwTxtFrm *pTmpFrm = IsFollow() ? FindMaster() : this;
2112cdf0e10cSrcweir 		const SwPageFrm *pTmpPage = pTmpFrm->FindPageFrm();
2113cdf0e10cSrcweir 		MSHORT nPgNr = pTmpPage->GetPhyPageNum();
2114cdf0e10cSrcweir 		MSHORT nLast;
2115cdf0e10cSrcweir 		MSHORT nDummy = 0; // nur zum Breakpoint setzen
2116cdf0e10cSrcweir 		while( pTmpFrm->GetFollow() )
2117cdf0e10cSrcweir 		{
2118cdf0e10cSrcweir 			pTmpFrm = pTmpFrm->GetFollow();
2119cdf0e10cSrcweir 			nLast = nPgNr;
2120cdf0e10cSrcweir 			pTmpPage = pTmpFrm->FindPageFrm();
2121cdf0e10cSrcweir 			nPgNr = pTmpPage->GetPhyPageNum();
2122cdf0e10cSrcweir 			if( nLast > nPgNr )
2123cdf0e10cSrcweir 				++nDummy; // schon fast eine Assertion wert
2124cdf0e10cSrcweir 			else if( nLast == nPgNr )
2125cdf0e10cSrcweir 				++nDummy; // bei Spalten voellig normal, aber sonst!?
2126cdf0e10cSrcweir 			else if( nLast < nPgNr - 1 )
2127cdf0e10cSrcweir 				++nDummy; // kann schon mal temporaer vorkommen
2128cdf0e10cSrcweir 		}
2129cdf0e10cSrcweir 	}
2130cdf0e10cSrcweir #endif
2131cdf0e10cSrcweir 
2132cdf0e10cSrcweir     CalcBaseOfstForFly();
2133cdf0e10cSrcweir     // OD 2004-03-17 #i11860#
2134cdf0e10cSrcweir     _CalcHeightOfLastLine();
2135cdf0e10cSrcweir }
2136cdf0e10cSrcweir 
2137cdf0e10cSrcweir /*************************************************************************
2138cdf0e10cSrcweir  *						SwTxtFrm::FormatQuick()
2139cdf0e10cSrcweir  *
2140cdf0e10cSrcweir  * bForceQuickFormat is set if GetFormatted() has been called during the
2141cdf0e10cSrcweir  * painting process. Actually I cannot imagine a situation which requires
2142cdf0e10cSrcweir  * a full formatting of the paragraph during painting, on the other hand
2143cdf0e10cSrcweir  * a full formatting can cause the invalidation of other layout frames,
2144cdf0e10cSrcweir  * e.g., if there are footnotes in this paragraph, and invalid layout
2145cdf0e10cSrcweir  * frames will not calculated during the painting. So I actually want to
2146cdf0e10cSrcweir  * avoid a formatting during painting, but since I'm a coward, I'll only
2147cdf0e10cSrcweir  * force the quick formatting in the situation of issue i29062.
2148cdf0e10cSrcweir  *************************************************************************/
2149cdf0e10cSrcweir 
FormatQuick(bool bForceQuickFormat)2150cdf0e10cSrcweir sal_Bool SwTxtFrm::FormatQuick( bool bForceQuickFormat )
2151cdf0e10cSrcweir {
2152cdf0e10cSrcweir     ASSERT( ! IsVertical() || ! IsSwapped(),
2153cdf0e10cSrcweir             "SwTxtFrm::FormatQuick with swapped frame" );
2154cdf0e10cSrcweir 
2155cdf0e10cSrcweir 	DBG_LOOP;
2156cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2157cdf0e10cSrcweir 	const XubString aXXX = GetTxtNode()->GetTxt();
2158cdf0e10cSrcweir 	const SwTwips nDbgY = Frm().Top();
2159cdf0e10cSrcweir     (void)nDbgY;
2160cdf0e10cSrcweir #ifdef DBG_UTIL
2161cdf0e10cSrcweir 	// nStopAt laesst sich vom CV bearbeiten.
2162cdf0e10cSrcweir 	static MSHORT nStopAt = 0;
2163cdf0e10cSrcweir 	if( nStopAt == GetFrmId() )
2164cdf0e10cSrcweir 	{
2165cdf0e10cSrcweir 		int i = GetFrmId();
2166cdf0e10cSrcweir         (void)i;
2167cdf0e10cSrcweir 	}
2168cdf0e10cSrcweir #endif
2169cdf0e10cSrcweir #endif
2170cdf0e10cSrcweir 
2171cdf0e10cSrcweir 	if( IsEmpty() && FormatEmpty() )
2172cdf0e10cSrcweir 		return sal_True;
2173cdf0e10cSrcweir 
2174cdf0e10cSrcweir     // Wir sind sehr waehlerisch:
2175cdf0e10cSrcweir 	if( HasPara() || IsWidow() || IsLocked()
2176cdf0e10cSrcweir         || !GetValidSizeFlag() ||
2177cdf0e10cSrcweir         ( ( IsVertical() ? Prt().Width() : Prt().Height() ) && IsHiddenNow() ) )
2178cdf0e10cSrcweir 		return sal_False;
2179cdf0e10cSrcweir 
2180cdf0e10cSrcweir 	SwTxtLineAccess aAccess( this );
2181cdf0e10cSrcweir 	SwParaPortion *pPara = aAccess.GetPara();
2182cdf0e10cSrcweir 	if( !pPara )
2183cdf0e10cSrcweir 		return sal_False;
2184cdf0e10cSrcweir 
2185cdf0e10cSrcweir     SwFrmSwapper aSwapper( this, sal_True );
2186cdf0e10cSrcweir 
2187cdf0e10cSrcweir     SwTxtFrmLocker aLock(this);
2188cdf0e10cSrcweir 	SwTxtFormatInfo aInf( this, sal_False, sal_True );
2189cdf0e10cSrcweir 	if( 0 != aInf.MaxHyph() )	// 27483: MaxHyphen beachten!
2190cdf0e10cSrcweir 		return sal_False;
2191cdf0e10cSrcweir 
2192cdf0e10cSrcweir 	SwTxtFormatter	aLine( this, &aInf );
2193cdf0e10cSrcweir 
2194cdf0e10cSrcweir 	// DropCaps sind zu kompliziert...
2195cdf0e10cSrcweir 	if( aLine.GetDropFmt() )
2196cdf0e10cSrcweir         return sal_False;
2197cdf0e10cSrcweir 
2198cdf0e10cSrcweir 	xub_StrLen nStart = GetOfst();
2199cdf0e10cSrcweir 	const xub_StrLen nEnd = GetFollow()
2200cdf0e10cSrcweir 					  ? GetFollow()->GetOfst() : aInf.GetTxt().Len();
2201cdf0e10cSrcweir 	do
2202cdf0e10cSrcweir     {
2203cdf0e10cSrcweir         //DBG_LOOP; shadows declaration above.
2204cdf0e10cSrcweir 		//resolved into:
2205cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2206cdf0e10cSrcweir #ifdef DBG_UTIL
2207cdf0e10cSrcweir 		DbgLoop aDbgLoop2( (const void*) this );
2208cdf0e10cSrcweir #endif
2209cdf0e10cSrcweir #endif
2210cdf0e10cSrcweir 		nStart = aLine.FormatLine( nStart );
2211cdf0e10cSrcweir 		if( aInf.IsNewLine() || (!aInf.IsStop() && nStart < nEnd) )
2212cdf0e10cSrcweir 			aLine.Insert( new SwLineLayout() );
2213cdf0e10cSrcweir 	} while( aLine.Next() );
2214cdf0e10cSrcweir 
2215cdf0e10cSrcweir     // Last exit: die Hoehen muessen uebereinstimmen.
2216cdf0e10cSrcweir 	Point aTopLeft( Frm().Pos() );
2217cdf0e10cSrcweir 	aTopLeft += Prt().Pos();
2218cdf0e10cSrcweir 	const SwTwips nNewHeight = aLine.Y() + aLine.GetLineHeight();
2219cdf0e10cSrcweir 	const SwTwips nOldHeight = aTopLeft.Y() + Prt().Height();
2220cdf0e10cSrcweir 
2221cdf0e10cSrcweir     if( !bForceQuickFormat && nNewHeight != nOldHeight && !IsUndersized() )
2222cdf0e10cSrcweir 	{
2223cdf0e10cSrcweir         // Achtung: Durch FormatLevel==12 kann diese Situation auftreten, don't panic!
2224cdf0e10cSrcweir         // ASSERT( nNewHeight == nOldHeight, "!FormatQuick: rosebud" );
2225cdf0e10cSrcweir         const xub_StrLen nStrt = GetOfst();
2226cdf0e10cSrcweir 		_InvalidateRange( SwCharRange( nStrt, nEnd - nStrt) );
2227cdf0e10cSrcweir 		return sal_False;
2228cdf0e10cSrcweir 	}
2229cdf0e10cSrcweir 
2230cdf0e10cSrcweir 	if( pFollow && nStart != ((SwTxtFrm*)pFollow)->GetOfst() )
2231cdf0e10cSrcweir 		return sal_False; // kann z.B. durch Orphans auftreten (35083,35081)
2232cdf0e10cSrcweir 
2233cdf0e10cSrcweir 	// Geschafft, wir sind durch ...
2234cdf0e10cSrcweir 
2235cdf0e10cSrcweir 	// Repaint setzen
2236cdf0e10cSrcweir 	pPara->GetRepaint()->Pos( aTopLeft );
2237cdf0e10cSrcweir 	pPara->GetRepaint()->SSize( Prt().SSize() );
2238cdf0e10cSrcweir 
2239cdf0e10cSrcweir 	// Reformat loeschen
2240cdf0e10cSrcweir 	*(pPara->GetReformat()) = SwCharRange();
2241cdf0e10cSrcweir 	*(pPara->GetDelta()) = 0;
2242cdf0e10cSrcweir 
2243cdf0e10cSrcweir 	return sal_True;
2244cdf0e10cSrcweir }
2245