xref: /aoo42x/main/sw/source/core/layout/frmtool.cxx (revision 56b35d86)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #include <hintids.hxx>
27 #include <tools/bigint.hxx>
28 #include <svx/svdmodel.hxx>
29 #include <svx/svdpage.hxx>
30 #include <editeng/brshitem.hxx>
31 #include <editeng/keepitem.hxx>
32 #include <editeng/shaditem.hxx>
33 #include <editeng/ulspitem.hxx>
34 #include <editeng/lrspitem.hxx>
35 #include <editeng/boxitem.hxx>
36 #include <sfx2/printer.hxx>
37 #include <editeng/lspcitem.hxx>
38 
39 #include <fmtornt.hxx>
40 #include <fmtanchr.hxx>
41 #include <fmthdft.hxx>
42 #include <fmtcntnt.hxx>
43 #include <fmtfsize.hxx>
44 #include <fmtsrnd.hxx>
45 #include <docary.hxx>
46 #include <lineinfo.hxx>
47 #include <swmodule.hxx>
48 #include "pagefrm.hxx"
49 #include "colfrm.hxx"
50 #include "doc.hxx"
51 #include "fesh.hxx"
52 #include "viewimp.hxx"
53 #include "viewopt.hxx"
54 #include "pam.hxx"
55 #include "dflyobj.hxx"
56 #include "dcontact.hxx"
57 #include "frmtool.hxx"
58 #include "docsh.hxx"
59 #include "tabfrm.hxx"
60 #include "rowfrm.hxx"
61 #include "ftnfrm.hxx"
62 #include "txtfrm.hxx"
63 #include "notxtfrm.hxx"
64 #include "flyfrms.hxx"
65 #include "layact.hxx"
66 #include "pagedesc.hxx"
67 #include "section.hxx"
68 #include "sectfrm.hxx"
69 #include "node2lay.hxx"
70 #include "ndole.hxx"
71 #include "ndtxt.hxx"
72 #include "swtable.hxx"
73 #include "hints.hxx"
74 #include <layhelp.hxx>
75 #include <laycache.hxx>
76 #include <rootfrm.hxx>
77 #include "mdiexp.hxx"
78 #include "statstr.hrc"
79 #include <paratr.hxx>
80 #include <sortedobjs.hxx>
81 #include <objectformatter.hxx>
82 #include <switerator.hxx>
83 
84 //UUUU
85 #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
86 
87 // ftnfrm.cxx:
88 void lcl_RemoveFtns( SwFtnBossFrm* pBoss, sal_Bool bPageOnly, sal_Bool bEndNotes );
89 
90 using namespace ::com::sun::star;
91 
92 
93 sal_Bool bObjsDirect = sal_True;
94 sal_Bool bDontCreateObjects = sal_False;
95 sal_Bool bSetCompletePaintOnInvalidate = sal_False;
96 
97 sal_uInt8 StackHack::nCnt = 0;
98 sal_Bool StackHack::bLocked = sal_False;
99 
100 
101 
102 /*************************************************************************/
103 
104 SwFrmNotify::SwFrmNotify( SwFrm *pF ) :
105 	pFrm( pF ),
106 	aFrm( pF->Frm() ),
107 	aPrt( pF->Prt() ),
108     bInvaKeep( sal_False ),
109     bValidSize( pF->GetValidSizeFlag() ),
110     mbFrmDeleted( false )     // #i49383#
111 {
112     if ( pF->IsTxtFrm() )
113     {
114         mnFlyAnchorOfst = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_True );
115         mnFlyAnchorOfstNoWrap = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_False );
116     }
117     else
118     {
119         mnFlyAnchorOfst = 0;
120         mnFlyAnchorOfstNoWrap = 0;
121     }
122 
123 	bHadFollow = pF->IsCntntFrm() ?
124 					(((SwCntntFrm*)pF)->GetFollow() ? sal_True : sal_False) :
125 					sal_False;
126 }
127 
128 /*************************************************************************/
129 
130 SwFrmNotify::~SwFrmNotify()
131 {
132     // #i49383#
133     if ( mbFrmDeleted )
134     {
135         return;
136     }
137 
138     SWRECTFN( pFrm )
139     const sal_Bool bAbsP = POS_DIFF( aFrm, pFrm->Frm() );
140     const sal_Bool bChgWidth =
141             (aFrm.*fnRect->fnGetWidth)() != (pFrm->Frm().*fnRect->fnGetWidth)();
142     const sal_Bool bChgHeight =
143             (aFrm.*fnRect->fnGetHeight)()!=(pFrm->Frm().*fnRect->fnGetHeight)();
144     const sal_Bool bChgFlyBasePos = pFrm->IsTxtFrm() &&
145        ( ( mnFlyAnchorOfst != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_True ) ) ||
146          ( mnFlyAnchorOfstNoWrap != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_False ) ) );
147 
148 	if ( pFrm->IsFlowFrm() && !pFrm->IsInFtn() )
149 	{
150 		SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );
151 
152 		if ( !pFlow->IsFollow() )
153 		{
154 			if ( !pFrm->GetIndPrev() )
155 			{
156 				if ( bInvaKeep )
157 				{
158                     SwFrm *pPre = pFrm->FindPrev();
159                     if ( pPre && pPre->IsFlowFrm() )
160                     {
161                         // 1. pPre wants to keep with me:
162                         bool bInvalidPrePos = SwFlowFrm::CastFlowFrm( pPre )->IsKeep( *pPre->GetAttrSet() ) && pPre->GetIndPrev();
163 
164                         // 2. pPre is a table and the last row wants to keep with me:
165                         if ( !bInvalidPrePos && pPre->IsTabFrm() )
166                         {
167                             SwTabFrm* pPreTab = static_cast<SwTabFrm*>(pPre);
168                             if ( pPreTab->GetFmt()->GetDoc()->get(IDocumentSettingAccess::TABLE_ROW_KEEP) )
169                             {
170                                 SwRowFrm* pLastRow = static_cast<SwRowFrm*>(pPreTab->GetLastLower());
171                                 if ( pLastRow && pLastRow->ShouldRowKeepWithNext() )
172                                     bInvalidPrePos = true;
173                             }
174                         }
175 
176                         if ( bInvalidPrePos )
177                             pPre->InvalidatePos();
178                     }
179 				}
180 			}
181             else if ( !pFlow->HasFollow() )
182             {
183                 long nOldHeight = (aFrm.*fnRect->fnGetHeight)();
184                 long nNewHeight = (pFrm->Frm().*fnRect->fnGetHeight)();
185                 if( (nOldHeight > nNewHeight) || (!nOldHeight && nNewHeight) )
186                     pFlow->CheckKeep();
187             }
188 		}
189 	}
190 
191 	if ( bAbsP )
192 	{
193 		pFrm->SetCompletePaint();
194 
195 		SwFrm* pNxt = pFrm->GetIndNext();
196         // #121888# - skip empty section frames
197         while ( pNxt &&
198                 pNxt->IsSctFrm() && !static_cast<SwSectionFrm*>(pNxt)->GetSection() )
199         {
200             pNxt = pNxt->GetIndNext();
201         }
202 
203 		if ( pNxt )
204 			pNxt->InvalidatePos();
205 		else
206 		{
207             // #104100# - correct condition for setting retouche
208             // flag for vertical layout.
209             if( pFrm->IsRetoucheFrm() &&
210                 (aFrm.*fnRect->fnTopDist)( (pFrm->Frm().*fnRect->fnGetTop)() ) > 0 )
211             {
212 				pFrm->SetRetouche();
213             }
214 
215             // A fresh follow frame does not have to be invalidated, because
216             // it is already formatted:
217             if ( bHadFollow || !pFrm->IsCntntFrm() || !((SwCntntFrm*)pFrm)->GetFollow() )
218             {
219                 if ( !pFrm->IsTabFrm() || !((SwTabFrm*)pFrm)->GetFollow() )
220                     pFrm->InvalidateNextPos();
221             }
222         }
223 	}
224 
225 	//Fuer Hintergrundgrafiken muss bei Groessenaenderungen ein Repaint her.
226     const sal_Bool bPrtWidth =
227             (aPrt.*fnRect->fnGetWidth)() != (pFrm->Prt().*fnRect->fnGetWidth)();
228     const sal_Bool bPrtHeight =
229             (aPrt.*fnRect->fnGetHeight)()!=(pFrm->Prt().*fnRect->fnGetHeight)();
230     if ( bPrtWidth || bPrtHeight )
231     {
232         //UUUU
233         drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes(pFrm->getSdrAllFillAttributesHelper());
234 
235         if(aFillAttributes.get() && aFillAttributes->isUsed())
236         {
237             //UUUU use SetCompletePaint if needed
238             if(aFillAttributes->needCompleteRepaint())
239             {
240                 pFrm->SetCompletePaint();
241             }
242         }
243         else
244         {
245             const SvxGraphicPosition ePos = pFrm->GetAttrSet()->GetBackground().GetGraphicPos();
246             if(GPOS_NONE != ePos && GPOS_TILED != ePos)
247                 pFrm->SetCompletePaint();
248         }
249     }
250     else
251     {
252         // #97597# - consider case that *only* margins between
253         // frame and printing area has changed. Then, frame has to be repainted,
254         // in order to force paint of the margin areas.
255         if ( !bAbsP && (bChgWidth || bChgHeight) )
256         {
257             pFrm->SetCompletePaint();
258         }
259     }
260 
261 	const sal_Bool bPrtP = POS_DIFF( aPrt, pFrm->Prt() );
262     if ( bAbsP || bPrtP || bChgWidth || bChgHeight ||
263          bPrtWidth || bPrtHeight || bChgFlyBasePos )
264 	{
265 		if( pFrm->IsAccessibleFrm() )
266 		{
267 			SwRootFrm *pRootFrm = pFrm->getRootFrm();
268 			if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
269 				pRootFrm->GetCurrShell() )
270 			{
271 				pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm );
272 			}
273 		}
274 
275         // Notification of anchored objects
276         if ( pFrm->GetDrawObjs() )
277         {
278             const SwSortedObjs &rObjs = *pFrm->GetDrawObjs();
279             SwPageFrm* pPageFrm = 0;
280             for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
281             {
282                 // OD 2004-03-31 #i26791# - no general distinction between
283                 // Writer fly frames and drawing objects
284                 bool bNotify = false;
285                 bool bNotifySize = false;
286                 SwAnchoredObject* pObj = rObjs[i];
287                 SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() );
288                 // --> OD 2004-12-08 #115759#
289                 const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar();
290                 if ( !bAnchoredAsChar )
291                 // <--
292                 {
293                     // Notify object, which aren't anchored as-character:
294 
295                     // always notify objects, if frame position has changed
296                     // or if the object is to-page|to-fly anchored.
297                     if ( bAbsP ||
298                          pContact->ObjAnchoredAtPage() ||
299                          pContact->ObjAnchoredAtFly() )
300                     {
301                         bNotify = true;
302 
303                         // assure that to-fly anchored Writer fly frames are
304                         // registered at the correct page frame, if frame
305                         // position has changed.
306                         if ( bAbsP && pContact->ObjAnchoredAtFly() &&
307                              pObj->ISA(SwFlyFrm) )
308                         {
309                             // determine to-fly anchored Writer fly frame
310                             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
311                             // determine page frame of to-fly anchored
312                             // Writer fly frame
313                             SwPageFrm* pFlyPageFrm = pFlyFrm->FindPageFrm();
314                             // determine page frame, if needed.
315                             if ( !pPageFrm )
316                             {
317                                 pPageFrm = pFrm->FindPageFrm();
318                             }
319                             if ( pPageFrm != pFlyPageFrm )
320                             {
321                                 ASSERT( pFlyPageFrm, "~SwFrmNotify: Fly from Nowhere" );
322                                 if( pFlyPageFrm )
323                                     pFlyPageFrm->MoveFly( pFlyFrm, pPageFrm );
324                                 else
325                                     pPageFrm->AppendFlyToPage( pFlyFrm );
326                             }
327                         }
328                     }
329                     // otherwise the objects are notified in dependence to
330                     // its positioning and alignment
331                     else
332                     {
333                         const SwFmtVertOrient& rVert =
334                                         pContact->GetFmt()->GetVertOrient();
335                         if ( ( rVert.GetVertOrient() == text::VertOrientation::CENTER ||
336                                rVert.GetVertOrient() == text::VertOrientation::BOTTOM ||
337                                rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) &&
338                              ( bChgHeight || bPrtHeight ) )
339                         {
340                             bNotify = true;
341                         }
342                         if ( !bNotify )
343                         {
344                             const SwFmtHoriOrient& rHori =
345                                         pContact->GetFmt()->GetHoriOrient();
346                             if ( ( rHori.GetHoriOrient() != text::HoriOrientation::NONE ||
347                                    rHori.GetRelationOrient()== text::RelOrientation::PRINT_AREA ||
348                                    rHori.GetRelationOrient()== text::RelOrientation::FRAME ) &&
349                                  ( bChgWidth || bPrtWidth || bChgFlyBasePos ) )
350                             {
351                                 bNotify = true;
352                             }
353                         }
354                     }
355                 }
356                 else if ( bPrtWidth )
357                 {
358                     // Notify as-character anchored objects, if printing area
359                     // width has changed.
360                     bNotify = true;
361                     bNotifySize = true;
362                 }
363 
364                 // perform notification via the corresponding invalidations
365                 if ( bNotify )
366                 {
367                     if ( pObj->ISA(SwFlyFrm) )
368                     {
369                         SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
370                         if ( bNotifySize )
371                             pFlyFrm->_InvalidateSize();
372                         // --> OD 2004-12-08 #115759# - no invalidation of
373                         // position for as-character anchored objects.
374                         if ( !bAnchoredAsChar )
375                         {
376                             pFlyFrm->_InvalidatePos();
377                         }
378                         // <--
379                         pFlyFrm->_Invalidate();
380                     }
381                     else if ( pObj->ISA(SwAnchoredDrawObject) )
382                     {
383                         // --> OD 2004-12-08 #115759# - no invalidation of
384                         // position for as-character anchored objects.
385                         if ( !bAnchoredAsChar )
386                         {
387                             pObj->InvalidateObjPos();
388                         }
389                         // <--
390                     }
391                     else
392                     {
393                         ASSERT( false,
394                                 "<SwCntntNotify::~SwCntntNotify()> - unknown anchored object type. Please inform OD." );
395                     }
396                 }
397             }
398         }
399 	}
400 	else if( pFrm->IsTxtFrm() && bValidSize != pFrm->GetValidSizeFlag() )
401 	{
402 		SwRootFrm *pRootFrm = pFrm->getRootFrm();
403 		if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
404 			pRootFrm->GetCurrShell() )
405 		{
406 			pRootFrm->GetCurrShell()->Imp()->InvalidateAccessibleFrmContent( pFrm );
407 		}
408 	}
409 
410     // #i9046# Automatic frame width
411     SwFlyFrm* pFly = 0;
412     // --> FME 2004-10-21 #i35879# Do not trust the inf flags. pFrm does not
413     // necessarily have to have an upper!
414     if ( !pFrm->IsFlyFrm() && 0 != ( pFly = pFrm->ImplFindFlyFrm() ) )
415     // <--
416     {
417         // --> OD 2006-05-08 #i61999#
418         // no invalidation of columned Writer fly frames, because automatic
419         // width doesn't make sense for such Writer fly frames.
420         if ( pFly->Lower() && !pFly->Lower()->IsColumnFrm() )
421         {
422             const SwFmtFrmSize &rFrmSz = pFly->GetFmt()->GetFrmSize();
423 
424             // This could be optimized. Basically the fly frame only has to
425             // be invalidated, if the first line of pFrm (if pFrm is a content
426             // frame, for other frame types its the print area) has changed its
427             // size and pFrm was responsible for the current width of pFly. On
428             // the other hand, this is only rarely used and re-calculation of
429             // the fly frame does not cause too much trouble. So we keep it this
430             // way:
431             if ( ATT_FIX_SIZE != rFrmSz.GetWidthSizeType() )
432             {
433                 // --> OD 2005-07-29 #i50668#, #i50998# - invalidation of position
434                 // of as-character anchored fly frames not needed and can cause
435                 // layout loops
436                 if ( !pFly->ISA(SwFlyInCntFrm) )
437                 {
438                     pFly->InvalidatePos();
439                 }
440                 // <--
441                 pFly->InvalidateSize();
442             }
443         }
444         // <--
445     }
446 }
447 
448 /*************************************************************************/
449 
450 SwLayNotify::SwLayNotify( SwLayoutFrm *pLayFrm ) :
451 	SwFrmNotify( pLayFrm ),
452     bLowersComplete( sal_False )
453 {
454 }
455 
456 /*************************************************************************/
457 
458 // OD 2004-05-11 #i28701# - local method to invalidate the position of all
459 // frames inclusive its floating screen objects, which are lowers of the given
460 // layout frame
461 void lcl_InvalidatePosOfLowers( SwLayoutFrm& _rLayoutFrm )
462 {
463     if( _rLayoutFrm.IsFlyFrm() && _rLayoutFrm.GetDrawObjs() )
464     {
465         _rLayoutFrm.InvalidateObjs( true, false );
466     }
467 
468     SwFrm* pLowerFrm = _rLayoutFrm.Lower();
469     while ( pLowerFrm )
470     {
471         pLowerFrm->InvalidatePos();
472         if ( pLowerFrm->IsTxtFrm() )
473         {
474             static_cast<SwTxtFrm*>(pLowerFrm)->Prepare( PREP_POS_CHGD );
475         }
476         else if ( pLowerFrm->IsTabFrm() )
477         {
478             pLowerFrm->InvalidatePrt();
479         }
480 
481         pLowerFrm->InvalidateObjs( true, false );
482 
483         pLowerFrm = pLowerFrm->GetNext();
484     };
485 }
486 
487 SwLayNotify::~SwLayNotify()
488 {
489     // --> OD 2005-07-29 #i49383#
490     if ( mbFrmDeleted )
491     {
492         return;
493     }
494     // <--
495 
496 	SwLayoutFrm *pLay = GetLay();
497     SWRECTFN( pLay )
498 	sal_Bool bNotify = sal_False;
499 	if ( pLay->Prt().SSize() != aPrt.SSize() )
500 	{
501 		if ( !IsLowersComplete() )
502 		{
503 			sal_Bool bInvaPercent;
504 
505 			if ( pLay->IsRowFrm() )
506 			{
507 				bInvaPercent = sal_True;
508                 long nNew = (pLay->Prt().*fnRect->fnGetHeight)();
509                 if( nNew != (aPrt.*fnRect->fnGetHeight)() )
510                      ((SwRowFrm*)pLay)->AdjustCells( nNew, sal_True);
511                 if( (pLay->Prt().*fnRect->fnGetWidth)()
512                     != (aPrt.*fnRect->fnGetWidth)() )
513 					 ((SwRowFrm*)pLay)->AdjustCells( 0, sal_False );
514 			}
515 			else
516 			{
517 				//Proportionale Anpassung der innenliegenden.
518 				//1. Wenn der Formatierte kein Fly ist
519 				//2. Wenn er keine Spalten enthaelt
520 				//3. Wenn der Fly eine feste Hoehe hat und die Spalten in der
521 				//	 Hoehe danebenliegen.
522 				//4. niemals bei SectionFrms.
523 				sal_Bool bLow;
524 				if( pLay->IsFlyFrm() )
525 				{
526 					if ( pLay->Lower() )
527 					{
528 						bLow = !pLay->Lower()->IsColumnFrm() ||
529                             (pLay->Lower()->Frm().*fnRect->fnGetHeight)()
530                              != (pLay->Prt().*fnRect->fnGetHeight)();
531 					}
532 					else
533 						bLow = sal_False;
534 				}
535 				else if( pLay->IsSctFrm() )
536 				{
537 					if ( pLay->Lower() )
538 					{
539 						if( pLay->Lower()->IsColumnFrm() && pLay->Lower()->GetNext() )
540 							bLow = pLay->Lower()->Frm().Height() != pLay->Prt().Height();
541 						else
542 							bLow = pLay->Prt().Width() != aPrt.Width();
543 					}
544 					else
545 						bLow = sal_False;
546 				}
547                 else if( pLay->IsFooterFrm() && !pLay->HasFixSize() )
548                     bLow = pLay->Prt().Width() != aPrt.Width();
549                 else
550 					bLow = sal_True;
551 				bInvaPercent = bLow;
552 				if ( bLow )
553 				{
554                     pLay->ChgLowersProp( aPrt.SSize() );
555                 }
556 				//Wenn die PrtArea gewachsen ist, so ist es moeglich, dass die
557 				//Kette der Untergeordneten einen weiteren Frm aufnehmen kann,
558 				//mithin muss also der 'moeglicherweise passende' Invalidiert werden.
559 				//Das invalidieren lohnt nur, wenn es sich beim mir bzw. meinen
560 				//Uppers um eine Moveable-Section handelt.
561 				//Die PrtArea ist gewachsen, wenn die Breite oder die Hoehe groesser
562 				//geworden ist.
563 				if ( (pLay->Prt().Height() > aPrt.Height() ||
564 					  pLay->Prt().Width()  > aPrt.Width()) &&
565 					 (pLay->IsMoveable() || pLay->IsFlyFrm()) )
566 				{
567                     SwFrm *pTmpFrm = pLay->Lower();
568                     if ( pTmpFrm && pTmpFrm->IsFlowFrm() )
569 					{
570                         while ( pTmpFrm->GetNext() )
571                             pTmpFrm = pTmpFrm->GetNext();
572                         pTmpFrm->InvalidateNextPos();
573 					}
574 				}
575 			}
576 			bNotify = sal_True;
577 			//TEUER!! aber wie macht man es geschickter?
578 			if( bInvaPercent )
579                 pLay->InvaPercentLowers( pLay->Prt().Height() - aPrt.Height() );
580 		}
581 		if ( pLay->IsTabFrm() )
582 			//Damit _nur_ der Shatten bei Groessenaenderungen gemalt wird.
583 			((SwTabFrm*)pLay)->SetComplete();
584         else
585         {
586             const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
587             if( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) ||
588 				  !(pLay->GetType() & (FRM_BODY | FRM_PAGE)) )
589 			//Damit die untergeordneten sauber retouchiert werden.
590 			//Problembsp: Flys an den Henkeln packen und verkleinern.
591 			//Nicht fuer Body und Page, sonst flackerts beim HTML-Laden.
592 			pLay->SetCompletePaint();
593         }
594 	}
595 	//Lower benachrichtigen wenn sich die Position veraendert hat.
596     const sal_Bool bPrtPos = POS_DIFF( aPrt, pLay->Prt() );
597     const sal_Bool bPos = bPrtPos || POS_DIFF( aFrm, pLay->Frm() );
598 	const sal_Bool bSize = pLay->Frm().SSize() != aFrm.SSize();
599 
600 	if ( bPos && pLay->Lower() && !IsLowersComplete() )
601 		pLay->Lower()->InvalidatePos();
602 
603     if ( bPrtPos )
604 		pLay->SetCompletePaint();
605 
606 	//Nachfolger benachrichtigen wenn sich die SSize geaendert hat.
607 	if ( bSize )
608 	{
609 		if( pLay->GetNext() )
610 		{
611 			if ( pLay->GetNext()->IsLayoutFrm() )
612 				pLay->GetNext()->_InvalidatePos();
613 			else
614 				pLay->GetNext()->InvalidatePos();
615 		}
616 		else if( pLay->IsSctFrm() )
617 			pLay->InvalidateNextPos();
618 	}
619 	if ( !IsLowersComplete() &&
620 		 !(pLay->GetType()&(FRM_FLY|FRM_SECTION) &&
621 			pLay->Lower() && pLay->Lower()->IsColumnFrm()) &&
622 		 (bPos || bNotify) && !(pLay->GetType() & 0x1823) )  //Tab, Row, FtnCont, Root, Page
623 	{
624         // --> OD 2005-03-11 #i44016# - force unlock of position of lower objects.
625         // --> OD 2005-03-30 #i43913# - no unlock of position of objects,
626         // if <pLay> is a cell frame, and its table frame resp. its parent table
627         // frame is locked.
628         // --> OD 2005-04-15 #i47458# - force unlock of position of lower objects,
629         // only if position of layout frame has changed.
630         bool bUnlockPosOfObjs( bPos );
631         if ( bUnlockPosOfObjs && pLay->IsCellFrm() )
632         {
633             SwTabFrm* pTabFrm( pLay->FindTabFrm() );
634             if ( pTabFrm &&
635                  ( pTabFrm->IsJoinLocked() ||
636                    ( pTabFrm->IsFollow() &&
637                      pTabFrm->FindMaster()->IsJoinLocked() ) ) )
638             {
639                 bUnlockPosOfObjs = false;
640             }
641         }
642         // --> OD 2005-05-18 #i49383# - check for footnote frame, if unlock
643         // of position of lower objects is allowed.
644         else if ( bUnlockPosOfObjs && pLay->IsFtnFrm() )
645         {
646             bUnlockPosOfObjs = static_cast<SwFtnFrm*>(pLay)->IsUnlockPosOfLowerObjs();
647         }
648         // <--
649         // --> OD 2005-07-29 #i51303# - no unlock of object positions for sections
650         else if ( bUnlockPosOfObjs && pLay->IsSctFrm() )
651         {
652             bUnlockPosOfObjs = false;
653         }
654         // <--
655         pLay->NotifyLowerObjs( bUnlockPosOfObjs );
656         // <--
657 	}
658 	if ( bPos && pLay->IsFtnFrm() && pLay->Lower() )
659 	{
660         // OD 2004-05-11 #i28701#
661         ::lcl_InvalidatePosOfLowers( *pLay );
662 	}
663     if( ( bPos || bSize ) && pLay->IsFlyFrm() && ((SwFlyFrm*)pLay)->GetAnchorFrm()
664           && ((SwFlyFrm*)pLay)->GetAnchorFrm()->IsFlyFrm() )
665         ((SwFlyFrm*)pLay)->AnchorFrm()->InvalidateSize();
666 }
667 
668 /*************************************************************************/
669 
670 SwFlyNotify::SwFlyNotify( SwFlyFrm *pFlyFrm ) :
671 	SwLayNotify( pFlyFrm ),
672     // --> OD 2004-11-24 #115759# - keep correct page frame - the page frame
673     // the Writer fly frame is currently registered at.
674     pOldPage( pFlyFrm->GetPageFrm() ),
675     // <--
676     aFrmAndSpace( pFlyFrm->GetObjRectWithSpaces() )
677 {
678 }
679 
680 /*************************************************************************/
681 
682 SwFlyNotify::~SwFlyNotify()
683 {
684     // --> OD 2005-07-29 #i49383#
685     if ( mbFrmDeleted )
686     {
687         return;
688     }
689     // <--
690 
691 	SwFlyFrm *pFly = GetFly();
692 	if ( pFly->IsNotifyBack() )
693 	{
694 		ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
695 		SwViewImp *pImp = pSh ? pSh->Imp() : 0;
696 		if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() )
697 		{
698 			//Wenn in der LayAction das IsAgain gesetzt ist kann es sein,
699 			//dass die alte Seite inzwischen vernichtet wurde!
700             ::Notify( pFly, pOldPage, aFrmAndSpace, &aPrt );
701             // --> OD 2004-10-20 #i35640# - additional notify anchor text frame,
702             // if Writer fly frame has changed its page
703             if ( pFly->GetAnchorFrm()->IsTxtFrm() &&
704                  pFly->GetPageFrm() != pOldPage )
705             {
706                 pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
707             }
708             // <--
709 		}
710 		pFly->ResetNotifyBack();
711 	}
712 
713 	//Haben sich Groesse oder Position geaendert, so sollte die View
714 	//das wissen.
715     SWRECTFN( pFly )
716     const bool bPosChgd = POS_DIFF( aFrm, pFly->Frm() );
717     const bool bFrmChgd = pFly->Frm().SSize() != aFrm.SSize();
718     const bool bPrtChgd = aPrt != pFly->Prt();
719     if ( bPosChgd || bFrmChgd || bPrtChgd )
720 	{
721 		pFly->NotifyDrawObj();
722 	}
723 	if ( bPosChgd && aFrm.Pos().X() != WEIT_WECH )
724 	{
725         // OD 2004-05-10 #i28701# - no direct move of lower Writer fly frames.
726         // reason: New positioning and alignment (e.g. to-paragraph anchored,
727         // but aligned at page) are introduced.
728         // <SwLayNotify::~SwLayNotify()> takes care of invalidation of lower
729         // floating screen objects by calling method <SwLayoutFrm::NotifyLowerObjs()>.
730 
731 		if ( pFly->IsFlyAtCntFrm() )
732 		{
733             SwFrm *pNxt = pFly->AnchorFrm()->FindNext();
734 			if ( pNxt )
735             {
736 				pNxt->InvalidatePos();
737             }
738 		}
739 
740         // --> OD 2004-11-05 #i26945# - notify anchor.
741         // Needed for negative positioned Writer fly frames
742         if ( pFly->GetAnchorFrm()->IsTxtFrm() )
743         {
744             pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
745         }
746         // <--
747 	}
748 
749     // OD 2004-05-13 #i28701#
750     // --> OD 2005-03-21 #i45180# - no adjustment of layout process flags and
751     // further notifications/invalidations, if format is called by grow/shrink
752     if ( pFly->ConsiderObjWrapInfluenceOnObjPos() &&
753          ( !pFly->ISA(SwFlyFreeFrm) ||
754            !static_cast<SwFlyFreeFrm*>(pFly)->IsNoMoveOnCheckClip() ) )
755     // <--
756     {
757         // --> OD 2005-09-05 #i54138# - suppress restart of the layout process
758         // on changed frame height.
759         // Note: It doesn't seem to be necessary and can cause layout loops.
760         if ( bPosChgd )
761         // <--
762         {
763             // indicate a restart of the layout process
764             pFly->SetRestartLayoutProcess( true );
765         }
766         else
767         {
768             // lock position
769             pFly->LockPosition();
770 
771             if ( !pFly->ConsiderForTextWrap() )
772             {
773                 // indicate that object has to be considered for text wrap
774                 pFly->SetConsiderForTextWrap( true );
775                 // invalidate 'background' in order to allow its 'background'
776                 // to wrap around it.
777                 pFly->NotifyBackground( pFly->GetPageFrm(),
778                                         pFly->GetObjRectWithSpaces(),
779                                         PREP_FLY_ARRIVE );
780                 // invalidate position of anchor frame in order to force
781                 // a re-format of the anchor frame, which also causes a
782                 // re-format of the invalid previous frames of the anchor frame.
783                 pFly->AnchorFrm()->InvalidatePos();
784             }
785         }
786     }
787 }
788 
789 /*************************************************************************/
790 
791 SwCntntNotify::SwCntntNotify( SwCntntFrm *pCntntFrm ) :
792     SwFrmNotify( pCntntFrm ),
793     // OD 08.01.2004 #i11859#
794     mbChkHeightOfLastLine( false ),
795     mnHeightOfLastLine( 0L ),
796     // OD 2004-02-26 #i25029#
797     mbInvalidatePrevPrtArea( false ),
798     mbBordersJoinedWithPrev( false )
799 {
800     // OD 08.01.2004 #i11859#
801     if ( pCntntFrm->IsTxtFrm() )
802     {
803         SwTxtFrm* pTxtFrm = static_cast<SwTxtFrm*>(pCntntFrm);
804         if ( !pTxtFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::OLD_LINE_SPACING) )
805         {
806             const SwAttrSet* pSet = pTxtFrm->GetAttrSet();
807             const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
808             if ( rSpace.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
809             {
810                 mbChkHeightOfLastLine = true;
811                 mnHeightOfLastLine = pTxtFrm->GetHeightOfLastLine();
812             }
813         }
814     }
815 }
816 
817 /*************************************************************************/
818 
819 SwCntntNotify::~SwCntntNotify()
820 {
821     // --> OD 2005-07-29 #i49383#
822     if ( mbFrmDeleted )
823     {
824         return;
825     }
826     // <--
827 
828 	SwCntntFrm *pCnt = GetCnt();
829 	if ( bSetCompletePaintOnInvalidate )
830 		pCnt->SetCompletePaint();
831 
832     SWRECTFN( pCnt )
833     if ( pCnt->IsInTab() && ( POS_DIFF( pCnt->Frm(), aFrm ) ||
834 							 pCnt->Frm().SSize() != aFrm.SSize()))
835 	{
836 		SwLayoutFrm* pCell = pCnt->GetUpper();
837 		while( !pCell->IsCellFrm() && pCell->GetUpper() )
838 			pCell = pCell->GetUpper();
839 		ASSERT( pCell->IsCellFrm(), "Where's my cell?" );
840         if ( text::VertOrientation::NONE != pCell->GetFmt()->GetVertOrient().GetVertOrient() )
841 			pCell->InvalidatePrt();	//fuer vertikale Ausrichtung.
842 	}
843 
844     // OD 2004-02-26 #i25029#
845     if ( mbInvalidatePrevPrtArea && mbBordersJoinedWithPrev &&
846          pCnt->IsTxtFrm() &&
847          !pCnt->IsFollow() && !pCnt->GetIndPrev() )
848     {
849         // determine previous frame
850         SwFrm* pPrevFrm = pCnt->FindPrev();
851         // skip empty section frames and hidden text frames
852         {
853             while ( pPrevFrm &&
854                     ( ( pPrevFrm->IsSctFrm() &&
855                         !static_cast<SwSectionFrm*>(pPrevFrm)->GetSection() ) ||
856                       ( pPrevFrm->IsTxtFrm() &&
857                         static_cast<SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ) )
858             {
859                 pPrevFrm = pPrevFrm->FindPrev();
860             }
861         }
862 
863         // Invalidate printing area of found previous frame
864         if ( pPrevFrm )
865         {
866             if ( pPrevFrm->IsSctFrm() )
867             {
868                 if ( pCnt->IsInSct() )
869                 {
870                     // Note: found previous frame is a section frame and
871                     //       <pCnt> is also inside a section.
872                     //       Thus due to <mbBordersJoinedWithPrev>,
873                     //       <pCnt> had joined its borders/shadow with the
874                     //       last content of the found section.
875                     // Invalidate printing area of last content in found section.
876                     SwFrm* pLstCntntOfSctFrm =
877                             static_cast<SwSectionFrm*>(pPrevFrm)->FindLastCntnt();
878                     if ( pLstCntntOfSctFrm )
879                     {
880                         pLstCntntOfSctFrm->InvalidatePrt();
881                     }
882                 }
883             }
884             else
885             {
886                 pPrevFrm->InvalidatePrt();
887             }
888         }
889     }
890 
891     const bool bFirst = (aFrm.*fnRect->fnGetWidth)() == 0;
892 
893 	if ( pCnt->IsNoTxtFrm() )
894 	{
895 		//Aktive PlugIn's oder OLE-Objekte sollten etwas von der Veraenderung
896 		//mitbekommen, damit sie Ihr Window entsprechend verschieben.
897 		ViewShell *pSh  = pCnt->getRootFrm()->GetCurrShell();
898 		if ( pSh )
899 		{
900             SwOLENode *pNd;
901 			if ( 0 != (pNd = pCnt->GetNode()->GetOLENode()) &&
902 				 (pNd->GetOLEObj().IsOleRef() ||
903 				  pNd->IsOLESizeInvalid()) )
904 			{
905                 // --> OD #i117189#
906                 const bool bNoTxtFrmPrtAreaChanged =
907                         ( aPrt.SSize().Width() != 0 &&
908                           aPrt.SSize().Height() != 0 ) &&
909                         aPrt.SSize() != pCnt->Prt().SSize();
910                 // <--
911 				ASSERT( pCnt->IsInFly(), "OLE not in FlyFrm" );
912 				SwFlyFrm *pFly = pCnt->FindFlyFrm();
913                 svt::EmbeddedObjectRef& xObj = pNd->GetOLEObj().GetObject();
914 				SwFEShell *pFESh = 0;
915 				ViewShell *pTmp = pSh;
916 				do
917 				{	if ( pTmp->ISA( SwCrsrShell ) )
918 					{
919 						pFESh = (SwFEShell*)pTmp;
920                         // #108369#: Here used to be the condition if (!bFirst).
921                         // I think this should mean "do not call CalcAndSetScale"
922                         // if the frame is formatted for the first time.
923                         // Unfortunately this is not valid anymore since the
924                         // SwNoTxtFrm already gets a width during CalcLowerPreps.
925                         // Nevertheless, the indention of !bFirst seemed to be
926                         // to assure that the OLE objects have already been notified
927                         // if necessary before calling CalcAndSetScale.
928                         // So I replaced !bFirst by !IsOLESizeInvalid. There is
929                         // one additional problem specific to the word import:
930                         // The layout is calculated _before_ calling PrtOLENotify,
931                         // and the OLE objects are not invalidated during import.
932                         // Therefore I added the condition !IsUpdateExpFld,
933                         // have a look at the occurrence of CalcLayout in
934                         // uiview/view.cxx.
935                         if ( !pNd->IsOLESizeInvalid() &&
936                              !pSh->GetDoc()->IsUpdateExpFld() )
937                             pFESh->CalcAndSetScale( xObj,
938                                                     &pFly->Prt(), &pFly->Frm(),
939                                                     bNoTxtFrmPrtAreaChanged );
940 					}
941 					pTmp = (ViewShell*)pTmp->GetNext();
942 				} while ( pTmp != pSh );
943 
944 				if ( pFESh && pNd->IsOLESizeInvalid() )
945 				{
946 					pNd->SetOLESizeInvalid( sal_False );
947                     //TODO/LATER: needs OnDocumentPrinterChanged
948                     //xObj->OnDocumentPrinterChanged( pNd->GetDoc()->getPrinter( false ) );
949 					pFESh->CalcAndSetScale( xObj );//Client erzeugen lassen.
950 				}
951             }
952 			//dito Animierte Grafiken
953 			if ( Frm().HasArea() && ((SwNoTxtFrm*)pCnt)->HasAnimation() )
954 			{
955 				((SwNoTxtFrm*)pCnt)->StopAnimation();
956 				pSh->InvalidateWindows( Frm() );
957 			}
958 		}
959 	}
960 
961 	if ( bFirst )
962 	{
963 		pCnt->SetRetouche();	//fix(13870)
964 
965 		SwDoc *pDoc = pCnt->GetNode()->GetDoc();
966 		if ( pDoc->GetSpzFrmFmts()->Count() &&
967 			 pDoc->DoesContainAtPageObjWithContentAnchor() && !pDoc->IsNewDoc() )
968 		{
969             // If certain import filters for foreign file format import
970             // AT_PAGE anchored objects, the corresponding page number is
971             // typically not known. In this case the content position is
972             // stored at which the anchored object is found in the
973             // imported document.
974             // When this content is formatted it is the time at which
975             // the page is known. Thus, this data can be corrected now.
976 
977             const SwPageFrm* pPage = 0;
978             SwNodeIndex *pIdx  = 0;
979             SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
980             for ( sal_uInt16 i = 0; i < pTbl->Count(); ++i )
981             {
982                 SwFrmFmt *pFmt = (*pTbl)[i];
983                 const SwFmtAnchor &rAnch = pFmt->GetAnchor();
984                 if ( FLY_AT_PAGE != rAnch.GetAnchorId() ||
985                      rAnch.GetCntntAnchor() == 0 )
986                 {
987                     continue;
988                 }
989 
990                 if ( !pIdx )
991                 {
992                     pIdx = new SwNodeIndex( *pCnt->GetNode() );
993                 }
994                 if ( rAnch.GetCntntAnchor()->nNode == *pIdx )
995                 {
996                     ASSERT( false, "<SwCntntNotify::~SwCntntNotify()> - to page anchored object with content position. Please inform OD." );
997                     if ( !pPage )
998                     {
999                         pPage = pCnt->FindPageFrm();
1000                     }
1001                     SwFmtAnchor aAnch( rAnch );
1002                     aAnch.SetAnchor( 0 );
1003                     aAnch.SetPageNum( pPage->GetPhyPageNum() );
1004                     pFmt->SetFmtAttr( aAnch );
1005                     if ( RES_DRAWFRMFMT != pFmt->Which() )
1006                     {
1007                         pFmt->MakeFrms();
1008                     }
1009                 }
1010             }
1011             delete pIdx;
1012         }
1013     }
1014 
1015     // OD 12.01.2004 #i11859# - invalidate printing area of following frame,
1016     //  if height of last line has changed.
1017     if ( pCnt->IsTxtFrm() && mbChkHeightOfLastLine )
1018     {
1019         if ( mnHeightOfLastLine != static_cast<SwTxtFrm*>(pCnt)->GetHeightOfLastLine() )
1020         {
1021             pCnt->InvalidateNextPrtArea();
1022         }
1023     }
1024 
1025     // --> OD 2005-03-07 #i44049#
1026     if ( pCnt->IsTxtFrm() && POS_DIFF( aFrm, pCnt->Frm() ) )
1027     {
1028         pCnt->InvalidateObjs( true );
1029     }
1030     // <--
1031 
1032     // --> OD 2005-04-12 #i43255# - move code to invalidate at-character
1033     // anchored objects due to a change of its anchor character from
1034     // method <SwTxtFrm::Format(..)>.
1035     if ( pCnt->IsTxtFrm() )
1036     {
1037         SwTxtFrm* pMasterFrm = pCnt->IsFollow()
1038                                ? static_cast<SwTxtFrm*>(pCnt)->FindMaster()
1039                                : static_cast<SwTxtFrm*>(pCnt);
1040         if ( pMasterFrm && !pMasterFrm->IsFlyLock() &&
1041              pMasterFrm->GetDrawObjs() )
1042         {
1043             SwSortedObjs* pObjs = pMasterFrm->GetDrawObjs();
1044             for ( sal_uInt32 i = 0; i < pObjs->Count(); ++i )
1045             {
1046                 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
1047                 if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
1048                         == FLY_AT_CHAR )
1049                 {
1050                     pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrm->IsEmpty() );
1051                 }
1052             }
1053         }
1054     }
1055     // <--
1056 }
1057 
1058 /*************************************************************************/
1059 
1060 void AppendObjs( const SwSpzFrmFmts *pTbl, sal_uLong nIndex,
1061 						SwFrm *pFrm, SwPageFrm *pPage )
1062 {
1063 	for ( sal_uInt16 i = 0; i < pTbl->Count(); ++i )
1064 	{
1065 		SwFrmFmt *pFmt = (SwFrmFmt*)(*pTbl)[i];
1066 		const SwFmtAnchor &rAnch = pFmt->GetAnchor();
1067 		if ( rAnch.GetCntntAnchor() &&
1068 			 (rAnch.GetCntntAnchor()->nNode.GetIndex() == nIndex) )
1069 		{
1070             const bool bFlyAtFly = rAnch.GetAnchorId() == FLY_AT_FLY; // LAYER_IMPL
1071             //Wird ein Rahmen oder ein SdrObject beschrieben?
1072             const bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
1073             // OD 23.06.2003 #108784# - append also drawing objects anchored
1074             // as character.
1075             const bool bDrawObjInCntnt = bSdrObj &&
1076                                          (rAnch.GetAnchorId() == FLY_AS_CHAR);
1077 
1078             if( bFlyAtFly ||
1079                 (rAnch.GetAnchorId() == FLY_AT_PARA) ||
1080                 (rAnch.GetAnchorId() == FLY_AT_CHAR) ||
1081                 bDrawObjInCntnt )
1082 			{
1083                 SdrObject* pSdrObj = 0;
1084                 if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) )
1085 				{
1086 					ASSERT( !bSdrObj, "DrawObject not found." );
1087 					pFmt->GetDoc()->DelFrmFmt( pFmt );
1088 					--i;
1089 					continue;
1090 				}
1091 				if ( pSdrObj )
1092 				{
1093 					if ( !pSdrObj->GetPage() )
1094                     {
1095                         pFmt->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
1096 								InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect());
1097                     }
1098 
1099                     SwDrawContact* pNew =
1100                         static_cast<SwDrawContact*>(GetUserCall( pSdrObj ));
1101                     if ( !pNew->GetAnchorFrm() )
1102                     {
1103                         pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( 0L )) );
1104                     }
1105                     // OD 19.06.2003 #108784# - add 'virtual' drawing object,
1106                     // if necessary. But control objects have to be excluded.
1107                     else if ( !::CheckControlLayer( pSdrObj ) &&
1108                               pNew->GetAnchorFrm() != pFrm &&
1109                               !pNew->GetDrawObjectByAnchorFrm( *pFrm ) )
1110                     {
1111                         SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj();
1112                         pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) );
1113 
1114 						// for repaint, use new ActionChanged()
1115                         // pDrawVirtObj->SendRepaintBroadcast();
1116                         pDrawVirtObj->ActionChanged();
1117                     }
1118 
1119 				}
1120 				else
1121 				{
1122 					SwFlyFrm *pFly;
1123 					if( bFlyAtFly )
1124 						pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
1125 					else
1126 						pFly = new SwFlyAtCntFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
1127 					pFly->Lock();
1128 					pFrm->AppendFly( pFly );
1129 					pFly->Unlock();
1130 					if ( pPage )
1131 						::RegistFlys( pPage, pFly );
1132 				}
1133 			}
1134 		}
1135 	}
1136 }
1137 
1138 bool lcl_ObjConnected( SwFrmFmt *pFmt, const SwFrm* pSib )
1139 {
1140 	SwIterator<SwFlyFrm,SwFmt> aIter( *pFmt );
1141 	if ( RES_FLYFRMFMT == pFmt->Which() )
1142     {
1143         const SwRootFrm* pRoot = pSib ? pSib->getRootFrm() : 0;
1144         const SwFlyFrm* pTmpFrm;
1145 		for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
1146         {
1147             if(! pRoot || pRoot == pTmpFrm->getRootFrm() )
1148                 return true;
1149         }
1150     }
1151 	else
1152 	{
1153 		SwDrawContact *pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement(*pFmt);
1154 		if ( pContact )
1155             return pContact->GetAnchorFrm() != 0;
1156 	}
1157 	return false;
1158 }
1159 
1160 /** helper method to determine, if a <SwFrmFmt>, which has an object connected,
1161     is located in header or footer.
1162 
1163     OD 23.06.2003 #108784#
1164 
1165     @author OD
1166 */
1167 bool lcl_InHeaderOrFooter( SwFrmFmt& _rFmt )
1168 {
1169     bool bRetVal = false;
1170 
1171     const SwFmtAnchor& rAnch = _rFmt.GetAnchor();
1172 
1173     if (rAnch.GetAnchorId() != FLY_AT_PAGE)
1174     {
1175         bRetVal = _rFmt.GetDoc()->IsInHeaderFooter( rAnch.GetCntntAnchor()->nNode );
1176     }
1177 
1178     return bRetVal;
1179 }
1180 
1181 void AppendAllObjs( const SwSpzFrmFmts *pTbl, const SwFrm* pSib )
1182 {
1183 	//Verbinden aller Objekte, die in der SpzTbl beschrieben sind mit dem
1184 	//Layout.
1185 	//Wenn sich nix mehr tut hoeren wir auf. Dann koennen noch Formate
1186 	//uebrigbleiben, weil wir weder zeichengebunde Rahmen verbinden noch
1187 	//Objecte die in zeichengebundenen verankert sind.
1188 
1189 	SwSpzFrmFmts aCpy( 255, 255 );
1190 	aCpy.Insert( pTbl, 0 );
1191 
1192 	sal_uInt16 nOldCnt = USHRT_MAX;
1193 
1194 	while ( aCpy.Count() && aCpy.Count() != nOldCnt )
1195 	{
1196 		nOldCnt = aCpy.Count();
1197 		for ( int i = 0; i < int(aCpy.Count()); ++i )
1198 		{
1199 			SwFrmFmt *pFmt = (SwFrmFmt*)aCpy[ sal_uInt16(i) ];
1200 			const SwFmtAnchor &rAnch = pFmt->GetAnchor();
1201 			sal_Bool bRemove = sal_False;
1202             if ((rAnch.GetAnchorId() == FLY_AT_PAGE) ||
1203                 (rAnch.GetAnchorId() == FLY_AS_CHAR))
1204             {
1205 				//Seitengebunde sind bereits verankert, zeichengebundene
1206 				//will ich hier nicht.
1207 				bRemove = sal_True;
1208             }
1209             else if ( sal_False == (bRemove = ::lcl_ObjConnected( pFmt, pSib )) ||
1210                       ::lcl_InHeaderOrFooter( *pFmt ) )
1211 			{
1212             // OD 23.06.2003 #108784# - correction: for objects in header
1213             // or footer create frames, in spite of the fact that an connected
1214             // objects already exists.
1215 				//Fuer Flys und DrawObjs nur dann ein MakeFrms rufen wenn noch
1216 				//keine abhaengigen Existieren, andernfalls, oder wenn das
1217 				//MakeFrms keine abhaengigen erzeugt, entfernen.
1218 				pFmt->MakeFrms();
1219 				bRemove = ::lcl_ObjConnected( pFmt, pSib );
1220 			}
1221 			if ( bRemove )
1222 			{
1223 				aCpy.Remove( sal_uInt16(i) );
1224 				--i;
1225 			}
1226 		}
1227 	}
1228 	aCpy.Remove( 0, aCpy.Count() );
1229 }
1230 
1231 /** local method to set 'working' position for newly inserted frames
1232 
1233     OD 12.08.2003 #i17969#
1234 
1235     @author OD
1236 */
1237 void lcl_SetPos( SwFrm&             _rNewFrm,
1238                  const SwLayoutFrm& _rLayFrm )
1239 {
1240     SWRECTFN( (&_rLayFrm) )
1241     (_rNewFrm.Frm().*fnRect->fnSetPos)( (_rLayFrm.Frm().*fnRect->fnGetPos)() );
1242     // move position by one SwTwip in text flow direction in order to get
1243     // notifications for a new calculated position after its formatting.
1244     if ( bVert )
1245         _rNewFrm.Frm().Pos().X() -= 1;
1246     else
1247         _rNewFrm.Frm().Pos().Y() += 1;
1248 }
1249 
1250 void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
1251 							 sal_uLong nIndex, sal_Bool bPages, sal_uLong nEndIndex,
1252 							 SwFrm *pPrv )
1253 {
1254 	pDoc->BlockIdling();
1255 	SwRootFrm* pLayout = pLay->getRootFrm();
1256     const sal_Bool bOldCallbackActionEnabled = pLayout ? pLayout->IsCallbackActionEnabled() : sal_False;
1257 	if( bOldCallbackActionEnabled )
1258         pLayout->SetCallbackActionEnabled( sal_False );
1259 
1260 	//Bei der Erzeugung des Layouts wird bPages mit sal_True uebergeben. Dann
1261 	//werden schon mal alle x Absaetze neue Seiten angelegt. Bei umbruechen
1262 	//und/oder Pagedescriptorwechseln werden gleich die entsprechenden Seiten
1263 	//angelegt.
1264 	//Vorteil ist, das einerseits schon eine annaehernd realistische Zahl von
1265 	//Seiten angelegt wird, vor allem aber gibt es nicht mehr eine schier
1266 	//lange Kette von Absaetzen teuer verschoben werden muss, bis sie sich auf
1267 	//ertraegliches mass reduziert hat.
1268 	//Wir gehen mal davon aus, da? 20 Absaetze auf eine Seite passen
1269 	//Damit es in extremen Faellen nicht gar so heftig rechenen wir je nach
1270 	//Node noch etwas drauf.
1271 	//Wenn in der DocStatistik eine brauchebare Seitenzahl angegeben ist
1272 	//(wird beim Schreiben gepflegt), so wird von dieser Seitenanzahl
1273 	//ausgegengen.
1274 	const sal_Bool bStartPercent = bPages && !nEndIndex;
1275 
1276 	SwPageFrm *pPage = pLay->FindPageFrm();
1277 	const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
1278 	SwFrm		*pFrm = 0;
1279 	sal_Bool   bBreakAfter	 = sal_False;
1280 
1281     SwActualSection *pActualSection = 0;
1282     SwLayHelper *pPageMaker;
1283 
1284     //Wenn das Layout erzeugt wird (bPages == sal_True) steuern wir den Progress
1285 	//an. Flys und DrawObjekte werden dann nicht gleich verbunden, dies
1286 	//passiert erst am Ende der Funktion.
1287     if ( bPages )
1288     {
1289         // Attention: the SwLayHelper class uses references to the content-,
1290         // page-, layout-frame etc. and may change them!
1291         pPageMaker = new SwLayHelper( pDoc, pFrm, pPrv, pPage, pLay,
1292                 pActualSection, bBreakAfter, nIndex, 0 == nEndIndex );
1293         if( bStartPercent )
1294         {
1295             const sal_uLong nPageCount = pPageMaker->CalcPageCount();
1296             if( nPageCount )
1297                 bObjsDirect = sal_False;
1298         }
1299 	}
1300     else
1301         pPageMaker = NULL;
1302 
1303     if( pLay->IsInSct() &&
1304 		( pLay->IsSctFrm() || pLay->GetUpper() ) ) // Hierdurch werden Frischlinge
1305 			// abgefangen, deren Flags noch nicht ermittelt werden koennen,
1306 			// so z.B. beim Einfuegen einer Tabelle
1307 	{
1308 		SwSectionFrm* pSct = pLay->FindSctFrm();
1309 		// Wenn Inhalt in eine Fussnote eingefuegt wird, die in einem spaltigen
1310 		// Bereich liegt, so darf der spaltige Bereich nicht aufgebrochen werden.
1311 		// Nur wenn im Innern der Fussnote ein Bereich liegt, ist dies ein
1312 		// Kandidat fuer pActualSection.
1313 		// Gleiches gilt fuer Bereiche in Tabellen, wenn innerhalb einer Tabelle
1314 		// eingefuegt wird, duerfen nur Bereiche, die ebenfalls im Innern liegen,
1315 		// aufgebrochen werden.
1316 		if( ( !pLay->IsInFtn() || pSct->IsInFtn() ) &&
1317 			( !pLay->IsInTab() || pSct->IsInTab() ) )
1318 		{
1319 			pActualSection = new SwActualSection( 0, pSct, 0 );
1320 			ASSERT( !pLay->Lower() || !pLay->Lower()->IsColumnFrm(),
1321 				"_InsertCnt: Wrong Call" );
1322 		}
1323 	}
1324 
1325     //If a section is "open", the pActualSection points to an SwActualSection.
1326     //If the page breaks, for "open" sections a follow will created.
1327     //For nested sections (which have, however, not a nested layout),
1328     //the SwActualSection class has a member, which points to an upper(section).
1329     //When the "inner" section finishs, the upper will used instead.
1330 
1331 	while( sal_True )
1332 	{
1333 		SwNode *pNd = pDoc->GetNodes()[nIndex];
1334 		if ( pNd->IsCntntNode() )
1335 		{
1336 			SwCntntNode* pNode = (SwCntntNode*)pNd;
1337 			pFrm = pNode->IsTxtNode() ? new SwTxtFrm( (SwTxtNode*)pNode, pLay ) :
1338 										pNode->MakeFrm( pLay );
1339             if( pPageMaker )
1340                 pPageMaker->CheckInsert( nIndex );
1341 
1342             pFrm->InsertBehind( pLay, pPrv );
1343             // --> OD 2005-12-01 #i27138#
1344             // notify accessibility paragraphs objects about changed
1345             // CONTENT_FLOWS_FROM/_TO relation.
1346             // Relation CONTENT_FLOWS_FROM for next paragraph will change
1347             // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1348             if ( pFrm->IsTxtFrm() )
1349             {
1350                 ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1351                 // no notification, if <ViewShell> is in construction
1352                 if ( pViewShell && !pViewShell->IsInConstructor() &&
1353                      pViewShell->GetLayout() &&
1354                      pViewShell->GetLayout()->IsAnyShellAccessible() )
1355                 {
1356                     pViewShell->InvalidateAccessibleParaFlowRelation(
1357                         dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1358                         dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1359                     // --> OD 2006-08-28 #i68958#
1360                     // The information flags of the text frame are validated
1361                     // in methods <FindNextCnt(..)> and <FindPrevCnt(..)>.
1362                     // The information flags have to be invalidated, because
1363                     // it is possible, that the one of its upper frames
1364                     // isn't inserted into the layout.
1365                     pFrm->InvalidateInfFlags();
1366                     // <--
1367                 }
1368             }
1369             // <--
1370             // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1371             // for setting position at newly inserted frame
1372             lcl_SetPos( *pFrm, *pLay );
1373 			pPrv = pFrm;
1374 
1375 			if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects )
1376 				AppendObjs( pTbl, nIndex, pFrm, pPage );
1377 		}
1378 		else if ( pNd->IsTableNode() )
1379 		{	//Sollten wir auf eine Tabelle gestossen sein?
1380 			SwTableNode *pTblNode = (SwTableNode*)pNd;
1381 
1382             // #108116# loading may produce table structures that GCLines
1383             // needs to clean up. To keep table formulas correct, change
1384             // all table formulas to internal (BOXPTR) representation.
1385             SwTableFmlUpdate aMsgHnt( &pTblNode->GetTable() );
1386             aMsgHnt.eFlags = TBL_BOXPTR;
1387             pDoc->UpdateTblFlds( &aMsgHnt );
1388             pTblNode->GetTable().GCLines();
1389 
1390 			pFrm = pTblNode->MakeFrm( pLay );
1391 
1392             if( pPageMaker )
1393                 pPageMaker->CheckInsert( nIndex );
1394 
1395 			pFrm->InsertBehind( pLay, pPrv );
1396             // --> OD 2005-12-01 #i27138#
1397             // notify accessibility paragraphs objects about changed
1398             // CONTENT_FLOWS_FROM/_TO relation.
1399             // Relation CONTENT_FLOWS_FROM for next paragraph will change
1400             // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1401             {
1402                 ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1403                 // no notification, if <ViewShell> is in construction
1404                 if ( pViewShell && !pViewShell->IsInConstructor() &&
1405                      pViewShell->GetLayout() &&
1406                      pViewShell->GetLayout()->IsAnyShellAccessible() )
1407                 {
1408                     pViewShell->InvalidateAccessibleParaFlowRelation(
1409                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1410                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1411                 }
1412             }
1413             // <--
1414             if ( bObjsDirect && pTbl->Count() )
1415 				((SwTabFrm*)pFrm)->RegistFlys();
1416             // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1417             // for setting position at newly inserted frame
1418             lcl_SetPos( *pFrm, *pLay );
1419 
1420             pPrv = pFrm;
1421 			//Index auf den Endnode der Tabellensection setzen.
1422 			nIndex = pTblNode->EndOfSectionIndex();
1423 
1424             SwTabFrm* pTmpFrm = (SwTabFrm*)pFrm;
1425             while ( pTmpFrm )
1426             {
1427                 pTmpFrm->CheckDirChange();
1428                 pTmpFrm = pTmpFrm->IsFollow() ? pTmpFrm->FindMaster() : NULL;
1429             }
1430 
1431 		}
1432 		else if ( pNd->IsSectionNode() )
1433 		{
1434 			SwSectionNode *pNode = (SwSectionNode*)pNd;
1435 			if( pNode->GetSection().CalcHiddenFlag() )
1436 				// ist versteckt, ueberspringe den Bereich
1437 				nIndex = pNode->EndOfSectionIndex();
1438 			else
1439 			{
1440                 pFrm = pNode->MakeFrm( pLay );
1441 				pActualSection = new SwActualSection( pActualSection,
1442 												(SwSectionFrm*)pFrm, pNode );
1443 				if ( pActualSection->GetUpper() )
1444 				{
1445 					//Hinter den Upper einsetzen, beim EndNode wird der "Follow"
1446 					//des Uppers erzeugt.
1447 					SwSectionFrm *pTmp = pActualSection->GetUpper()->GetSectionFrm();
1448 					pFrm->InsertBehind( pTmp->GetUpper(), pTmp );
1449                     // OD 25.03.2003 #108339# - direct initialization of section
1450                     // after insertion in the layout
1451                     static_cast<SwSectionFrm*>(pFrm)->Init();
1452 				}
1453 				else
1454 				{
1455 					pFrm->InsertBehind( pLay, pPrv );
1456                     // OD 25.03.2003 #108339# - direct initialization of section
1457                     // after insertion in the layout
1458                     static_cast<SwSectionFrm*>(pFrm)->Init();
1459 
1460                     // --> FME 2004-09-08 #i33963#
1461                     // Do not trust the IsInFtn flag. If we are currently
1462                     // building up a table, the upper of pPrv may be a cell
1463                     // frame, but the cell frame does not have an upper yet.
1464                     if( pPrv && 0 != pPrv->ImplFindFtnFrm() )
1465                     // <--
1466                     {
1467 						if( pPrv->IsSctFrm() )
1468 							pPrv = ((SwSectionFrm*)pPrv)->ContainsCntnt();
1469 						if( pPrv && pPrv->IsTxtFrm() )
1470 							((SwTxtFrm*)pPrv)->Prepare( PREP_QUOVADIS, 0, sal_False );
1471 					}
1472 				}
1473                 // --> OD 2005-12-01 #i27138#
1474                 // notify accessibility paragraphs objects about changed
1475                 // CONTENT_FLOWS_FROM/_TO relation.
1476                 // Relation CONTENT_FLOWS_FROM for next paragraph will change
1477                 // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1478                 {
1479                     ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
1480                     // no notification, if <ViewShell> is in construction
1481                     if ( pViewShell && !pViewShell->IsInConstructor() &&
1482                          pViewShell->GetLayout() &&
1483                          pViewShell->GetLayout()->IsAnyShellAccessible() )
1484                     {
1485                         pViewShell->InvalidateAccessibleParaFlowRelation(
1486                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
1487                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
1488                     }
1489                 }
1490                 // <--
1491                 pFrm->CheckDirChange();
1492 
1493                 // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1494                 // for setting position at newly inserted frame
1495                 lcl_SetPos( *pFrm, *pLay );
1496 
1497                 // OD 20.11.2002 #105405# - no page, no invalidate.
1498                 if ( pPage )
1499                 {
1500                     // OD 18.09.2002 #100522#
1501                     // invalidate page in order to force format and paint of
1502                     // inserted section frame
1503                     pFrm->InvalidatePage( pPage );
1504 
1505                     // FME 10.11.2003 #112243#
1506                     // Invalidate fly content flag:
1507                     if ( pFrm->IsInFly() )
1508                         pPage->InvalidateFlyCntnt();
1509 
1510                     // OD 14.11.2002 #104684# - invalidate page content in order to
1511                     // force format and paint of section content.
1512                     pPage->InvalidateCntnt();
1513                 }
1514 
1515 				pLay = (SwLayoutFrm*)pFrm;
1516 				if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
1517 					pLay = pLay->GetNextLayoutLeaf();
1518 				pPrv = 0;
1519 			}
1520 		}
1521         else if ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )
1522 		{
1523 			ASSERT( pActualSection, "Sectionende ohne Anfang?" );
1524             ASSERT( pActualSection->GetSectionNode() == pNd->StartOfSectionNode(),
1525 							"Sectionende mit falschen Start Node?" );
1526 
1527 			//Section schliessen, ggf. die umgebende Section wieder
1528 			//aktivieren.
1529 			SwActualSection *pTmp = pActualSection->GetUpper();
1530 			delete pActualSection;
1531 			pLay = pLay->FindSctFrm();
1532 			if ( 0 != (pActualSection = pTmp) )
1533 			{
1534 				//Koennte noch sein, das der letzte SectionFrm leer geblieben
1535 				//ist. Dann ist es jetzt an der Zeit ihn zu entfernen.
1536 				if ( !pLay->ContainsCntnt() )
1537 				{
1538                     SwFrm *pTmpFrm = pLay;
1539                     pLay = pTmpFrm->GetUpper();
1540                     pPrv = pTmpFrm->GetPrev();
1541                     pTmpFrm->Remove();
1542                     delete pTmpFrm;
1543 				}
1544 				else
1545 				{
1546 					pPrv = pLay;
1547 					pLay = pLay->GetUpper();
1548 				}
1549 
1550                 // new section frame
1551                 pFrm = pActualSection->GetSectionNode()->MakeFrm( pLay );
1552                 pFrm->InsertBehind( pLay, pPrv );
1553                 static_cast<SwSectionFrm*>(pFrm)->Init();
1554 
1555                 // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
1556                 // for setting position at newly inserted frame
1557                 lcl_SetPos( *pFrm, *pLay );
1558 
1559                 SwSectionFrm* pOuterSectionFrm = pActualSection->GetSectionFrm();
1560 
1561                 // a follow has to be appended to the new section frame
1562                 SwSectionFrm* pFollow = pOuterSectionFrm->GetFollow();
1563                 if ( pFollow )
1564                 {
1565                     pOuterSectionFrm->SetFollow( NULL );
1566                     pOuterSectionFrm->InvalidateSize();
1567                     ((SwSectionFrm*)pFrm)->SetFollow( pFollow );
1568                 }
1569 
1570 				// Wir wollen keine leeren Teile zuruecklassen
1571                 if( ! pOuterSectionFrm->IsColLocked() &&
1572                     ! pOuterSectionFrm->ContainsCntnt() )
1573 				{
1574                     pOuterSectionFrm->DelEmpty( sal_True );
1575                     delete pOuterSectionFrm;
1576 				}
1577 				pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
1578 
1579 				pLay = (SwLayoutFrm*)pFrm;
1580 				if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
1581 					pLay = pLay->GetNextLayoutLeaf();
1582 				pPrv = 0;
1583 			}
1584 			else
1585 			{
1586 				//Nix mehr mit Sections, es geht direkt hinter dem SectionFrame
1587 				//weiter.
1588 				pPrv = pLay;
1589 				pLay = pLay->GetUpper();
1590 			}
1591 		}
1592 		else if( pNd->IsStartNode() &&
1593 				 SwFlyStartNode	== ((SwStartNode*)pNd)->GetStartNodeType() )
1594 		{
1595 			if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects )
1596 			{
1597 				SwFlyFrm* pFly = pLay->FindFlyFrm();
1598 				if( pFly )
1599 					AppendObjs( pTbl, nIndex, pFly, pPage );
1600 			}
1601 		}
1602 		else
1603 			// Weder Cntnt noch Tabelle noch Section,
1604 			// also muessen wir fertig sein.
1605 			break;
1606 
1607 		++nIndex;
1608 		// Der Endnode wird nicht mehr mitgenommen, es muss vom
1609 		// Aufrufenden (Section/MakeFrms()) sichergestellt sein, dass das Ende
1610 		// des Bereichs vor dem EndIndex liegt!
1611 		if ( nEndIndex && nIndex >= nEndIndex )
1612 			break;
1613 	}
1614 
1615 	if ( pActualSection )
1616 	{
1617 		//Kann passieren, dass noch eine leere (Follow-)Section uebrig geblieben ist.
1618 		if ( !(pLay = pActualSection->GetSectionFrm())->ContainsCntnt() )
1619 		{
1620 			pLay->Remove();
1621 			delete pLay;
1622 		}
1623 		delete pActualSection;
1624 	}
1625 
1626 	if ( bPages )		//Jetzt noch die Flys verbinden lassen.
1627 	{
1628 		if ( !bDontCreateObjects )
1629 			AppendAllObjs( pTbl, pLayout );
1630 		bObjsDirect = sal_True;
1631 	}
1632 
1633     if( pPageMaker )
1634     {
1635         pPageMaker->CheckFlyCache( pPage );
1636         delete pPageMaker;
1637         if( pDoc->GetLayoutCache() )
1638         {
1639 #ifdef DBG_UTIL
1640 #if OSL_DEBUG_LEVEL > 1
1641             pDoc->GetLayoutCache()->CompareLayout( *pDoc );
1642 #endif
1643 #endif
1644             pDoc->GetLayoutCache()->ClearImpl();
1645         }
1646     }
1647 
1648     pDoc->UnblockIdling();
1649 	if( bOldCallbackActionEnabled )
1650         pLayout->SetCallbackActionEnabled( bOldCallbackActionEnabled );
1651 }
1652 
1653 
1654 void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
1655 			   const SwNodeIndex &rEndIdx )
1656 {
1657     bObjsDirect = sal_False;
1658 
1659 	SwNodeIndex aTmp( rSttIdx );
1660 	sal_uLong nEndIdx = rEndIdx.GetIndex();
1661     SwNode* pNd = pDoc->GetNodes().FindPrvNxtFrmNode( aTmp,
1662 											pDoc->GetNodes()[ nEndIdx-1 ]);
1663 	if ( pNd )
1664 	{
1665 		sal_Bool bApres = aTmp < rSttIdx;
1666 		SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() );
1667 		SwFrm* pFrm;
1668 		while( 0 != (pFrm = aNode2Layout.NextFrm()) )
1669 		{
1670 			SwLayoutFrm *pUpper = pFrm->GetUpper();
1671 			SwFtnFrm* pFtnFrm = pUpper->FindFtnFrm();
1672 			sal_Bool bOldLock, bOldFtn;
1673 			if( pFtnFrm )
1674 			{
1675 				bOldFtn = pFtnFrm->IsColLocked();
1676 				pFtnFrm->ColLock();
1677 			}
1678 			else
1679 				bOldFtn = sal_True;
1680 			SwSectionFrm* pSct = pUpper->FindSctFrm();
1681 			// Es sind innerhalb von Fussnoten nur die Bereiche interessant,
1682 			// die in den Fussnoten liegen, nicht etwa die (spaltigen) Bereiche,
1683 			// in denen die Fussnoten(Container) liegen.
1684             // #109767# Table frame is in section, insert section in cell frame.
1685 			if( pSct && ((pFtnFrm && !pSct->IsInFtn()) || pUpper->IsCellFrm()) )
1686 				pSct = NULL;
1687 			if( pSct )
1688 			{   // damit der SectionFrm nicht zerstoert wird durch pTmp->MoveFwd()
1689 				bOldLock = pSct->IsColLocked();
1690 				pSct->ColLock();
1691 			}
1692 			else
1693 				bOldLock = sal_True;
1694 
1695             // Wenn pFrm sich nicht bewegen kann, koennen wir auch niemanden
1696 			// auf die naechste Seite schieben. Innerhalb eines Rahmens auch
1697 			// nicht ( in der 1. Spalte eines Rahmens waere pFrm Moveable()! )
1698 			// Auch in spaltigen Bereichen in Tabellen waere pFrm Moveable.
1699             sal_Bool bMoveNext = nEndIdx - rSttIdx.GetIndex() > 120;
1700             sal_Bool bAllowMove = !pFrm->IsInFly() && pFrm->IsMoveable() &&
1701                  (!pFrm->IsInTab() || pFrm->IsTabFrm() );
1702             if ( bMoveNext && bAllowMove )
1703 			{
1704 				SwFrm *pMove = pFrm;
1705 				SwFrm *pPrev = pFrm->GetPrev();
1706 				SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pMove );
1707 				ASSERT( pTmp, "Missing FlowFrm" );
1708 
1709 				if ( bApres )
1710 				{
1711 					// Wir wollen, dass der Rest der Seite leer ist, d.h.
1712 					// der naechste muss auf die naechste Seite wandern.
1713 					// Dieser kann auch in der naechsten Spalte stehen!
1714 					ASSERT( !pTmp->HasFollow(), "Follows forbidden" );
1715 					pPrev = pFrm;
1716 					// Wenn unser umgebender SectionFrm einen Next besitzt,
1717 					// so soll dieser ebenfalls gemoved werden!
1718 					pMove = pFrm->GetIndNext();
1719 					SwColumnFrm* pCol = (SwColumnFrm*)pFrm->FindColFrm();
1720 					if( pCol )
1721 						pCol = (SwColumnFrm*)pCol->GetNext();
1722 					do
1723 					{
1724 						if( pCol && !pMove )
1725 						{   // Bisher haben wir keinen Nachfolger gefunden
1726 							// jetzt gucken wir in die naechste Spalte
1727 							pMove = pCol->ContainsAny();
1728 							if( pCol->GetNext() )
1729 								pCol = (SwColumnFrm*)pCol->GetNext();
1730 							else if( pCol->IsInSct() )
1731 							{   // Wenn es keine naechste Spalte gibt, wir aber
1732 								// innerhalb eines spaltigen Bereichs sind,
1733 								// koennte es noch ausserhalb des Bereich
1734 								// (Seiten-)Spalten geben
1735 								pCol = (SwColumnFrm*)pCol->FindSctFrm()->FindColFrm();
1736 								if( pCol )
1737 									pCol = (SwColumnFrm*)pCol->GetNext();
1738 							}
1739 							else
1740 								pCol = NULL;
1741 						}
1742 						// Falls hier verschrottete SectionFrms herumgammeln,
1743 						// muessen diese uebersprungen werden.
1744 						while( pMove && pMove->IsSctFrm() &&
1745 							   !((SwSectionFrm*)pMove)->GetSection() )
1746 							pMove = pMove->GetNext();
1747 					} while( !pMove && pCol );
1748 
1749 					if( pMove )
1750 					{
1751 						if ( pMove->IsCntntFrm() )
1752 							pTmp = (SwCntntFrm*)pMove;
1753 						else if ( pMove->IsTabFrm() )
1754 							pTmp = (SwTabFrm*)pMove;
1755 						else if ( pMove->IsSctFrm() )
1756 						{
1757 							pMove = ((SwSectionFrm*)pMove)->ContainsAny();
1758 							if( pMove )
1759 								pTmp = SwFlowFrm::CastFlowFrm( pMove );
1760 							else
1761 								pTmp = NULL;
1762 						}
1763 					}
1764 					else
1765 						pTmp = 0;
1766 				}
1767 				else
1768 				{
1769 					ASSERT( !pTmp->IsFollow(), "Follows really forbidden" );
1770 					// Bei Bereichen muss natuerlich der Inhalt auf die Reise
1771 					// geschickt werden.
1772 					if( pMove->IsSctFrm() )
1773 					{
1774 						while( pMove && pMove->IsSctFrm() &&
1775 							   !((SwSectionFrm*)pMove)->GetSection() )
1776 							pMove = pMove->GetNext();
1777 						if( pMove && pMove->IsSctFrm() )
1778 							pMove = ((SwSectionFrm*)pMove)->ContainsAny();
1779 						if( pMove )
1780 							pTmp = SwFlowFrm::CastFlowFrm( pMove );
1781 						else
1782 							pTmp = NULL;
1783 					}
1784 				}
1785 
1786 				if( pTmp )
1787 				{
1788 					SwFrm* pOldUp = pTmp->GetFrm()->GetUpper();
1789 					// MoveFwd==sal_True bedeutet, dass wir auf der gleichen
1790 					// Seite geblieben sind, wir wollen aber die Seite wechseln,
1791 					// sofern dies moeglich ist
1792                     sal_Bool bTmpOldLock = pTmp->IsJoinLocked();
1793 					pTmp->LockJoin();
1794 					while( pTmp->MoveFwd( sal_True, sal_False, sal_True ) )
1795 					{
1796 						if( pOldUp == pTmp->GetFrm()->GetUpper() )
1797 							break;
1798 						pOldUp = pTmp->GetFrm()->GetUpper();
1799 					}
1800                     if( !bTmpOldLock )
1801 						pTmp->UnlockJoin();
1802 				}
1803 				::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(),
1804 							  pFrm->IsInDocBody(), nEndIdx, pPrev );
1805 			}
1806 			else
1807 			{
1808 				sal_Bool bSplit;
1809 				SwFrm* pPrv = bApres ? pFrm : pFrm->GetPrev();
1810 				// Wenn in einen SectionFrm ein anderer eingefuegt wird,
1811 				// muss dieser aufgebrochen werden
1812 				if( pSct && rSttIdx.GetNode().IsSectionNode() )
1813 				{
1814 					bSplit = pSct->SplitSect( pFrm, bApres );
1815 					// Wenn pSct nicht aufgespalten werden konnte
1816 					if( !bSplit && !bApres )
1817 					{
1818 						pUpper = pSct->GetUpper();
1819 						pPrv = pSct->GetPrev();
1820 					}
1821 				}
1822 				else
1823 					bSplit = sal_False;
1824                 ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(), sal_False,
1825                               nEndIdx, pPrv );
1826                 // OD 23.06.2003 #108784# - correction: append objects doesn't
1827                 // depend on value of <bAllowMove>
1828                 if( !bDontCreateObjects )
1829                 {
1830                     const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
1831                     if( pTbl->Count() )
1832                         AppendAllObjs( pTbl, pUpper );
1833                 }
1834 
1835 				// Wenn nichts eingefuegt wurde, z.B. ein ausgeblendeter Bereich,
1836 				// muss das Splitten rueckgaengig gemacht werden
1837 				if( bSplit && pSct && pSct->GetNext()
1838 					&& pSct->GetNext()->IsSctFrm() )
1839 					pSct->MergeNext( (SwSectionFrm*)pSct->GetNext() );
1840 				if( pFrm->IsInFly() )
1841 					pFrm->FindFlyFrm()->_Invalidate();
1842 				if( pFrm->IsInTab() )
1843 					pFrm->InvalidateSize();
1844 			}
1845 
1846 			SwPageFrm *pPage = pUpper->FindPageFrm();
1847 			SwFrm::CheckPageDescs( pPage, sal_False );
1848 			if( !bOldFtn )
1849 				pFtnFrm->ColUnlock();
1850 			if( !bOldLock )
1851 			{
1852 				pSct->ColUnlock();
1853 				// Zum Beispiel beim Einfuegen von gelinkten Bereichen,
1854 				// die wiederum Bereiche enthalten, kann pSct jetzt leer sein
1855 				// und damit ruhig zerstoert werden.
1856 				if( !pSct->ContainsCntnt() )
1857 				{
1858 					pSct->DelEmpty( sal_True );
1859 					pUpper->getRootFrm()->RemoveFromList( pSct );
1860 					delete pSct;
1861 				}
1862 			}
1863 		}
1864 	}
1865 
1866     bObjsDirect = sal_True;
1867 }
1868 
1869 
1870 /*************************************************************************/
1871 
1872 SwBorderAttrs::SwBorderAttrs( const SwModify *pMod, const SwFrm *pConstructor ) :
1873 	SwCacheObj( pMod ),
1874 	rAttrSet( pConstructor->IsCntntFrm()
1875 					? ((SwCntntFrm*)pConstructor)->GetNode()->GetSwAttrSet()
1876 					: ((SwLayoutFrm*)pConstructor)->GetFmt()->GetAttrSet() ),
1877 	rUL 	( rAttrSet.GetULSpace() ),
1878     // --> OD 2008-12-04 #i96772#
1879     // LRSpaceItem is copied due to the possibility that it is adjusted - see below
1880     rLR     ( rAttrSet.GetLRSpace() ),
1881     // <--
1882 	rBox	( rAttrSet.GetBox() 	),
1883 	rShadow ( rAttrSet.GetShadow()	),
1884 	aFrmSize( rAttrSet.GetFrmSize().GetSize() )
1885 {
1886     // --> OD 2008-12-02 #i96772#
1887     const SwTxtFrm* pTxtFrm = dynamic_cast<const SwTxtFrm*>(pConstructor);
1888     if ( pTxtFrm )
1889     {
1890         pTxtFrm->GetTxtNode()->ClearLRSpaceItemDueToListLevelIndents( rLR );
1891     }
1892 
1893 	//Achtung: Die USHORTs fuer die gecache'ten Werte werden absichtlich
1894 	//nicht initialisiert!
1895 
1896 	//Muessen alle einmal berechnet werden:
1897 	bTopLine = bBottomLine = bLeftLine = bRightLine =
1898     bTop     = bBottom     = bLine   = sal_True;
1899 
1900 	bCacheGetLine = bCachedGetTopLine = bCachedGetBottomLine = sal_False;
1901     // OD 21.05.2003 #108789# - init cache status for values <bJoinedWithPrev>
1902     // and <bJoinedWithNext>, which aren't initialized by default.
1903     bCachedJoinedWithPrev = sal_False;
1904     bCachedJoinedWithNext = sal_False;
1905 
1906 	bBorderDist = 0 != (pConstructor->GetType() & (FRM_CELL));
1907 }
1908 
1909 SwBorderAttrs::~SwBorderAttrs()
1910 {
1911 	((SwModify*)pOwner)->SetInCache( sal_False );
1912 }
1913 
1914 /*************************************************************************
1915 |*
1916 |*	SwBorderAttrs::CalcTop(), CalcBottom(), CalcLeft(), CalcRight()
1917 |*
1918 |*	Beschreibung		Die Calc-Methoden errechnen zusaetzlich zu den
1919 |*		von den Attributen vorgegebenen Groessen einen Sicherheitsabstand.
1920 |*		der Sicherheitsabstand wird nur einkalkuliert, wenn Umrandung und/oder
1921 |*		Schatten im Spiel sind; er soll vermeiden, dass aufgrund der
1922 |*		groben physikalischen Gegebenheiten Raender usw. uebermalt werden.
1923 |*
1924 |*************************************************************************/
1925 
1926 void SwBorderAttrs::_CalcTop()
1927 {
1928 	nTop = CalcTopLine() + rUL.GetUpper();
1929 	bTop = sal_False;
1930 }
1931 
1932 void SwBorderAttrs::_CalcBottom()
1933 {
1934 	nBottom = CalcBottomLine() + rUL.GetLower();
1935 	bBottom = sal_False;
1936 }
1937 
1938 long SwBorderAttrs::CalcRight( const SwFrm* pCaller ) const
1939 {
1940     long nRight;
1941 
1942     // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
1943     // and right border are painted on the right respectively left.
1944     if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
1945         nRight = CalcLeftLine();
1946     else
1947         nRight = CalcRightLine();
1948 
1949     // for paragraphs, "left" is "before text" and "right" is "after text"
1950     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1951         nRight += rLR.GetLeft();
1952     else
1953         nRight += rLR.GetRight();
1954 
1955     // --> OD 2008-01-21 #newlistlevelattrs#
1956     // correction: retrieve left margin for numbering in R2L-layout
1957     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1958     {
1959         nRight += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
1960     }
1961     // <--
1962 
1963     return nRight;
1964 }
1965 
1966 long SwBorderAttrs::CalcLeft( const SwFrm *pCaller ) const
1967 {
1968     long nLeft;
1969 
1970     // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
1971     // and right border are painted on the right respectively left.
1972     if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
1973         nLeft = CalcRightLine();
1974     else
1975         nLeft = CalcLeftLine();
1976 
1977     // for paragraphs, "left" is "before text" and "right" is "after text"
1978     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
1979         nLeft += rLR.GetRight();
1980     else
1981         nLeft += rLR.GetLeft();
1982 
1983     // --> OD 2008-01-21 #newlistlevelattrs#
1984     // correction: do not retrieve left margin for numbering in R2L-layout
1985 //    if ( pCaller->IsTxtFrm() )
1986     if ( pCaller->IsTxtFrm() && !pCaller->IsRightToLeft() )
1987     // <--
1988     {
1989         nLeft += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
1990     }
1991 
1992     return nLeft;
1993 }
1994 
1995 /*************************************************************************
1996 |*
1997 |*	SwBorderAttrs::CalcTopLine(), CalcBottomLine(),
1998 |*				   CalcLeftLine(), CalcRightLine()
1999 |*
2000 |*	Beschreibung		Berechnung der Groessen fuer Umrandung und Schatten.
2001 |* 						Es kann auch ohne Linien ein Abstand erwuenscht sein,
2002 |* 						dieser wird  dann nicht vom Attribut sondern hier
2003 |* 						beruecksichtigt (bBorderDist, z.B. fuer Zellen).
2004 |*
2005 |*************************************************************************/
2006 
2007 void SwBorderAttrs::_CalcTopLine()
2008 {
2009 	nTopLine = (bBorderDist && !rBox.GetTop())
2010 							? rBox.GetDistance  (BOX_LINE_TOP)
2011 							: rBox.CalcLineSpace(BOX_LINE_TOP);
2012 	nTopLine = nTopLine + rShadow.CalcShadowSpace(SHADOW_TOP);
2013 	bTopLine = sal_False;
2014 }
2015 
2016 void SwBorderAttrs::_CalcBottomLine()
2017 {
2018 	nBottomLine = (bBorderDist && !rBox.GetBottom())
2019 							? rBox.GetDistance  (BOX_LINE_BOTTOM)
2020 							: rBox.CalcLineSpace(BOX_LINE_BOTTOM);
2021 	nBottomLine = nBottomLine + rShadow.CalcShadowSpace(SHADOW_BOTTOM);
2022 	bBottomLine = sal_False;
2023 }
2024 
2025 void SwBorderAttrs::_CalcLeftLine()
2026 {
2027 	nLeftLine = (bBorderDist && !rBox.GetLeft())
2028 							? rBox.GetDistance  (BOX_LINE_LEFT)
2029 							: rBox.CalcLineSpace(BOX_LINE_LEFT);
2030 	nLeftLine = nLeftLine + rShadow.CalcShadowSpace(SHADOW_LEFT);
2031 	bLeftLine = sal_False;
2032 }
2033 
2034 void SwBorderAttrs::_CalcRightLine()
2035 {
2036 	nRightLine = (bBorderDist && !rBox.GetRight())
2037 							? rBox.GetDistance  (BOX_LINE_RIGHT)
2038 							: rBox.CalcLineSpace(BOX_LINE_RIGHT);
2039 	nRightLine = nRightLine + rShadow.CalcShadowSpace(SHADOW_RIGHT);
2040 	bRightLine = sal_False;
2041 }
2042 
2043 /*************************************************************************/
2044 
2045 void SwBorderAttrs::_IsLine()
2046 {
2047 	bIsLine = rBox.GetTop() || rBox.GetBottom() ||
2048 			  rBox.GetLeft()|| rBox.GetRight();
2049 	bLine = sal_False;
2050 }
2051 
2052 /*************************************************************************
2053 |*
2054 |*	SwBorderAttrs::CmpLeftRightLine(), IsTopLine(), IsBottomLine()
2055 |*
2056 |*		Die Umrandungen benachbarter Absaetze werden nach folgendem
2057 |*		Algorithmus zusammengefasst:
2058 |*
2059 |*		1. Die Umrandung oben faellt weg, wenn der Vorgaenger dieselbe
2060 |*		   Umrandung oben aufweist und 3. Zutrifft.
2061 |*		   Zusaetzlich muss der Absatz mindestens rechts oder links oder
2062 |*		   unten eine Umrandung haben.
2063 |*		2. Die Umrandung unten faellt weg, wenn der Nachfolger dieselbe
2064 |*		   Umrandung untern aufweist und 3. Zustrifft.
2065 |*		   Zusaetzlich muss der Absatz mindestens rechts oder links oder
2066 |*		   oben eine Umrandung haben.
2067 |*		3. Die Umrandungen links und rechts vor Vorgaenger bzw. Nachfolger
2068 |*		   sind identisch.
2069 |*
2070 |*************************************************************************/
2071 inline int CmpLines( const SvxBorderLine *pL1, const SvxBorderLine *pL2 )
2072 {
2073 	return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) );
2074 }
2075 
2076 // OD 21.05.2003 #108789# - change name of 1st parameter - "rAttrs" -> "rCmpAttrs"
2077 // OD 21.05.2003 #108789# - compare <CalcRight()> and <rCmpAttrs.CalcRight()>
2078 //          instead of only the right LR-spacing, because R2L-layout has to be
2079 //          considered.
2080 sal_Bool SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rCmpAttrs,
2081 								  const SwFrm *pCaller,
2082 								  const SwFrm *pCmp ) const
2083 {
2084     return ( CmpLines( rCmpAttrs.GetBox().GetLeft(), GetBox().GetLeft()  ) &&
2085              CmpLines( rCmpAttrs.GetBox().GetRight(),GetBox().GetRight() ) &&
2086              CalcLeft( pCaller ) == rCmpAttrs.CalcLeft( pCmp ) &&
2087              // OD 21.05.2003 #108789# - compare <CalcRight> with <rCmpAttrs.CalcRight>.
2088              CalcRight( pCaller ) == rCmpAttrs.CalcRight( pCmp ) );
2089 }
2090 
2091 sal_Bool SwBorderAttrs::_JoinWithCmp( const SwFrm& _rCallerFrm,
2092                                   const SwFrm& _rCmpFrm ) const
2093 {
2094     sal_Bool bReturnVal = sal_False;
2095 
2096     SwBorderAttrAccess aCmpAccess( SwFrm::GetCache(), &_rCmpFrm );
2097     const SwBorderAttrs &rCmpAttrs = *aCmpAccess.Get();
2098     if ( rShadow == rCmpAttrs.GetShadow() &&
2099          CmpLines( rBox.GetTop(), rCmpAttrs.GetBox().GetTop() ) &&
2100          CmpLines( rBox.GetBottom(), rCmpAttrs.GetBox().GetBottom() ) &&
2101          CmpLeftRight( rCmpAttrs, &_rCallerFrm, &_rCmpFrm )
2102        )
2103     {
2104         bReturnVal = sal_True;
2105     }
2106 
2107     return bReturnVal;
2108 }
2109 
2110 // OD 21.05.2003 #108789# - method to determine, if borders are joined with
2111 // previous frame. Calculated value saved in cached value <bJoinedWithPrev>
2112 // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>
2113 void SwBorderAttrs::_CalcJoinedWithPrev( const SwFrm& _rFrm,
2114                                          const SwFrm* _pPrevFrm )
2115 {
2116     // set default
2117     bJoinedWithPrev = sal_False;
2118 
2119     if ( _rFrm.IsTxtFrm() )
2120     {
2121         // text frame can potentially join with previous text frame, if
2122         // corresponding attribute set is set at previous text frame.
2123         // OD 2004-02-26 #i25029# - If parameter <_pPrevFrm> is set, take this
2124         // one as previous frame.
2125         const SwFrm* pPrevFrm = _pPrevFrm ? _pPrevFrm : _rFrm.GetPrev();
2126         // OD 2004-02-13 #i25029# - skip hidden text frames.
2127         while ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
2128                 static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() )
2129         {
2130             pPrevFrm = pPrevFrm->GetPrev();
2131         }
2132         if ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
2133              pPrevFrm->GetAttrSet()->GetParaConnectBorder().GetValue()
2134            )
2135         {
2136             bJoinedWithPrev = _JoinWithCmp( _rFrm, *(pPrevFrm) );
2137         }
2138     }
2139 
2140     // valid cache status, if demanded
2141     // OD 2004-02-26 #i25029# - Do not validate cache, if parameter <_pPrevFrm>
2142     // is set.
2143     bCachedJoinedWithPrev = bCacheGetLine && !_pPrevFrm;
2144 }
2145 
2146 // OD 21.05.2003 #108789# - method to determine, if borders are joined with
2147 // next frame. Calculated value saved in cached value <bJoinedWithNext>
2148 void SwBorderAttrs::_CalcJoinedWithNext( const SwFrm& _rFrm )
2149 {
2150     // set default
2151     bJoinedWithNext = sal_False;
2152 
2153     if ( _rFrm.IsTxtFrm() )
2154     {
2155         // text frame can potentially join with next text frame, if
2156         // corresponding attribute set is set at current text frame.
2157         // OD 2004-02-13 #i25029# - get next frame, but skip hidden text frames.
2158         const SwFrm* pNextFrm = _rFrm.GetNext();
2159         while ( pNextFrm && pNextFrm->IsTxtFrm() &&
2160                 static_cast<const SwTxtFrm*>(pNextFrm)->IsHiddenNow() )
2161         {
2162             pNextFrm = pNextFrm->GetNext();
2163         }
2164         if ( pNextFrm && pNextFrm->IsTxtFrm() &&
2165              _rFrm.GetAttrSet()->GetParaConnectBorder().GetValue()
2166            )
2167         {
2168             bJoinedWithNext = _JoinWithCmp( _rFrm, *(pNextFrm) );
2169         }
2170     }
2171 
2172     // valid cache status, if demanded
2173     bCachedJoinedWithNext = bCacheGetLine;
2174 }
2175 
2176 // OD 21.05.2003 #108789# - accessor for cached values <bJoinedWithPrev>
2177 // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>, which is passed to
2178 // method <_CalcJoindWithPrev(..)>.
2179 sal_Bool SwBorderAttrs::JoinedWithPrev( const SwFrm& _rFrm,
2180                                     const SwFrm* _pPrevFrm ) const
2181 {
2182     if ( !bCachedJoinedWithPrev || _pPrevFrm )
2183     {
2184         // OD 2004-02-26 #i25029# - pass <_pPrevFrm> as 2nd parameter
2185         const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithPrev( _rFrm, _pPrevFrm );
2186     }
2187 
2188     return bJoinedWithPrev;
2189 }
2190 
2191 sal_Bool SwBorderAttrs::JoinedWithNext( const SwFrm& _rFrm ) const
2192 {
2193     if ( !bCachedJoinedWithNext )
2194     {
2195         const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithNext( _rFrm );
2196     }
2197 
2198     return bJoinedWithNext;
2199 }
2200 
2201 // OD 2004-02-26 #i25029# - added 2nd parameter <_pPrevFrm>, which is passed to
2202 // method <JoinedWithPrev>
2203 void SwBorderAttrs::_GetTopLine( const SwFrm& _rFrm,
2204                                  const SwFrm* _pPrevFrm )
2205 {
2206     sal_uInt16 nRet = CalcTopLine();
2207 
2208     // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
2209     // OD 2004-02-26 #i25029# - add 2nd parameter
2210     if ( JoinedWithPrev( _rFrm, _pPrevFrm ) )
2211     {
2212         nRet = 0;
2213     }
2214 
2215     bCachedGetTopLine = bCacheGetLine;
2216 
2217 	nGetTopLine = nRet;
2218 }
2219 
2220 void SwBorderAttrs::_GetBottomLine( const SwFrm& _rFrm )
2221 {
2222 	sal_uInt16 nRet = CalcBottomLine();
2223 
2224     // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
2225     if ( JoinedWithNext( _rFrm ) )
2226     {
2227         nRet = 0;
2228     }
2229 
2230     bCachedGetBottomLine = bCacheGetLine;
2231 
2232 	nGetBottomLine = nRet;
2233 }
2234 
2235 /*************************************************************************/
2236 
2237 SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCach, const SwFrm *pFrm ) :
2238     SwCacheAccess( rCach, (pFrm->IsCntntFrm() ?
2239 								(void*)((SwCntntFrm*)pFrm)->GetNode() :
2240 								(void*)((SwLayoutFrm*)pFrm)->GetFmt()),
2241 						   (sal_Bool)(pFrm->IsCntntFrm() ?
2242 				((SwModify*)((SwCntntFrm*)pFrm)->GetNode())->IsInCache() :
2243 				((SwModify*)((SwLayoutFrm*)pFrm)->GetFmt())->IsInCache()) ),
2244 	pConstructor( pFrm )
2245 {
2246 }
2247 
2248 /*************************************************************************/
2249 
2250 SwCacheObj *SwBorderAttrAccess::NewObj()
2251 {
2252 	((SwModify*)pOwner)->SetInCache( sal_True );
2253 	return new SwBorderAttrs( (SwModify*)pOwner, pConstructor );
2254 }
2255 
2256 SwBorderAttrs *SwBorderAttrAccess::Get()
2257 {
2258 	return (SwBorderAttrs*)SwCacheAccess::Get();
2259 }
2260 
2261 /*************************************************************************/
2262 
2263 SwOrderIter::SwOrderIter( const SwPageFrm *pPg, sal_Bool bFlys ) :
2264 	pPage( pPg ),
2265 	pCurrent( 0 ),
2266 	bFlysOnly( bFlys )
2267 {
2268 }
2269 
2270 /*************************************************************************/
2271 
2272 const SdrObject *SwOrderIter::Top()
2273 {
2274 	pCurrent = 0;
2275 	if ( pPage->GetSortedObjs() )
2276 	{
2277 		sal_uInt32 nTopOrd = 0;
2278         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2279 		if ( pObjs->Count() )
2280 		{
2281             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
2282 			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2283 			{
2284                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2285 				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2286 					continue;
2287 				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2288 				if ( nTmp >= nTopOrd )
2289 				{
2290 					nTopOrd = nTmp;
2291 					pCurrent = pObj;
2292 				}
2293 			}
2294 		}
2295 	}
2296 	return pCurrent;
2297 }
2298 
2299 /*************************************************************************/
2300 
2301 const SdrObject *SwOrderIter::Bottom()
2302 {
2303 	pCurrent = 0;
2304 	if ( pPage->GetSortedObjs() )
2305 	{
2306 		sal_uInt32 nBotOrd = USHRT_MAX;
2307         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2308 		if ( pObjs->Count() )
2309 		{
2310             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
2311 			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2312 			{
2313                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2314 				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2315 					continue;
2316 				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2317 				if ( nTmp < nBotOrd )
2318 				{
2319 					nBotOrd = nTmp;
2320 					pCurrent = pObj;
2321 				}
2322 			}
2323 		}
2324 	}
2325 	return pCurrent;
2326 }
2327 
2328 /*************************************************************************/
2329 
2330 const SdrObject *SwOrderIter::Next()
2331 {
2332 	const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
2333 	pCurrent = 0;
2334 	if ( pPage->GetSortedObjs() )
2335 	{
2336 		sal_uInt32 nOrd = USHRT_MAX;
2337         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2338 		if ( pObjs->Count() )
2339 		{
2340             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
2341 			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2342 			{
2343                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2344 				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2345 					continue;
2346 				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2347 				if ( nTmp > nCurOrd && nTmp < nOrd )
2348 				{
2349 					nOrd = nTmp;
2350 					pCurrent = pObj;
2351 				}
2352 			}
2353 		}
2354 	}
2355 	return pCurrent;
2356 }
2357 
2358 /*************************************************************************/
2359 
2360 const SdrObject *SwOrderIter::Prev()
2361 {
2362 	const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
2363 	pCurrent = 0;
2364 	if ( pPage->GetSortedObjs() )
2365 	{
2366 		sal_uInt32 nOrd = 0;
2367         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
2368 		if ( pObjs->Count() )
2369 		{
2370             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
2371 			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2372 			{
2373                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
2374 				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
2375 					continue;
2376 				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
2377 				if ( nTmp < nCurOrd && nTmp >= nOrd )
2378 				{
2379 					nOrd = nTmp;
2380 					pCurrent = pObj;
2381 				}
2382 			}
2383 		}
2384 	}
2385 	return pCurrent;
2386 }
2387 
2388 /*************************************************************************/
2389 
2390 //Unterstruktur eines LayoutFrms fuer eine Aktion aufheben und wieder
2391 //restaurieren.
2392 //Neuer Algorithmus: Es ist unuetz jeden Nachbarn einzeln zu betrachten und
2393 //die Pointer sauber zu setzen (Upper, Nachbarn, usw.)
2394 //Es reicht vollkommen jeweils eine Einzelkette zu loesen, und mit dem
2395 //Letzen der Einzelkette nachzuschauen ob noch eine weitere Kette
2396 //angeheangt werden muss. Es brauchen nur die Pointer korrigiert werden,
2397 //die zur Verkettung notwendig sind. So koennen Beipspielsweise die Pointer
2398 //auf die Upper auf den alten Uppern stehenbleiben. Korrigiert werden die
2399 //Pointer dann im RestoreCntnt. Zwischenzeitlich ist sowieso jeder Zugriff
2400 //verboten.
2401 //Unterwegs werden die Flys bei der Seite abgemeldet.
2402 
2403 // --> OD 2004-11-29 #115759# - 'remove' also drawing object from page and
2404 // at-fly anchored objects from page
2405 void MA_FASTCALL lcl_RemoveObjsFromPage( SwFrm* _pFrm )
2406 {
2407     ASSERT( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_RemoveFlysFromPage." );
2408     SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
2409 	for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
2410 	{
2411         SwAnchoredObject* pObj = rObjs[i];
2412         // --> OD 2004-11-29 #115759# - reset member, at which the anchored
2413         // object orients its vertical position
2414         pObj->ClearVertPosOrientFrm();
2415         // <--
2416         // --> OD 2005-03-03 #i43913#
2417         pObj->ResetLayoutProcessBools();
2418         // <--
2419         // --> OD 2004-11-29 #115759# - remove also lower objects of as-character
2420         // anchored Writer fly frames from page
2421         if ( pObj->ISA(SwFlyFrm) )
2422         {
2423             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
2424 
2425             // --> OD 2004-11-29 #115759# - remove also direct lowers of Writer
2426             // fly frame from page
2427             if ( pFlyFrm->GetDrawObjs() )
2428             {
2429                 ::lcl_RemoveObjsFromPage( pFlyFrm );
2430             }
2431             // <--
2432 
2433             SwCntntFrm* pCnt = pFlyFrm->ContainsCntnt();
2434             while ( pCnt )
2435             {
2436                 if ( pCnt->GetDrawObjs() )
2437                     ::lcl_RemoveObjsFromPage( pCnt );
2438                 pCnt = pCnt->GetNextCntntFrm();
2439             }
2440             if ( pFlyFrm->IsFlyFreeFrm() )
2441             {
2442                 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
2443                 pFlyFrm->GetPageFrm()->RemoveFlyFromPage( pFlyFrm );
2444             }
2445         }
2446         // <--
2447         // --> OD 2004-11-29 #115759# - remove also drawing objects from page
2448         else if ( pObj->ISA(SwAnchoredDrawObject) )
2449         {
2450             if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
2451             {
2452                 pObj->GetPageFrm()->RemoveDrawObjFromPage(
2453                                 *(static_cast<SwAnchoredDrawObject*>(pObj)) );
2454             }
2455         }
2456         // <--
2457 	}
2458 }
2459 
2460 SwFrm *SaveCntnt( SwLayoutFrm *pLay, SwFrm *pStart )
2461 {
2462 	if( pLay->IsSctFrm() && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
2463 		lcl_RemoveFtns( (SwColumnFrm*)pLay->Lower(), sal_True, sal_True );
2464 
2465 	SwFrm *pSav;
2466 	if ( 0 == (pSav = pLay->ContainsAny()) )
2467 		return 0;
2468 
2469 	if( pSav->IsInFtn() && !pLay->IsInFtn() )
2470 	{
2471 		do
2472 			pSav = pSav->FindNext();
2473 		while( pSav && pSav->IsInFtn() );
2474 		if( !pSav || !pLay->IsAnLower( pSav ) )
2475 			return NULL;
2476 	}
2477 
2478     // Tables should be saved as a whole, expection:
2479     // The contents of a section or a cell inside a table should be saved
2480     if ( pSav->IsInTab() && !( ( pLay->IsSctFrm() || pLay->IsCellFrm() ) && pLay->IsInTab() ) )
2481         while ( !pSav->IsTabFrm() )
2482             pSav = pSav->GetUpper();
2483 
2484 	if( pSav->IsInSct() )
2485 	{ // Jetzt wird der oberste Bereich gesucht, der innerhalb von pLay ist.
2486 		SwFrm* pSect = pLay->FindSctFrm();
2487 		SwFrm *pTmp = pSav;
2488 		do
2489 		{
2490 			pSav = pTmp;
2491 			pTmp = pSav->GetUpper() ? pSav->GetUpper()->FindSctFrm() : NULL;
2492 		} while ( pTmp != pSect );
2493 	}
2494 
2495 	SwFrm *pFloat = pSav;
2496 	if( !pStart )
2497 		pStart = pSav;
2498 	sal_Bool bGo = pStart == pSav;
2499 	do
2500 	{
2501 		if( bGo )
2502 			pFloat->GetUpper()->pLower = 0; 	//Die Teilkette ausklinken.
2503 
2504 		//Das Ende der Teilkette suchen, unterwegs die Flys abmelden.
2505 		do
2506 		{
2507 			if( bGo )
2508 			{
2509 				if ( pFloat->IsCntntFrm() )
2510 				{
2511 					if ( pFloat->GetDrawObjs() )
2512                         ::lcl_RemoveObjsFromPage( (SwCntntFrm*)pFloat );
2513 				}
2514 				else if ( pFloat->IsTabFrm() || pFloat->IsSctFrm() )
2515 				{
2516 					SwCntntFrm *pCnt = ((SwLayoutFrm*)pFloat)->ContainsCntnt();
2517 					if( pCnt )
2518 					{
2519 						do
2520 						{	if ( pCnt->GetDrawObjs() )
2521                                 ::lcl_RemoveObjsFromPage( pCnt );
2522 							pCnt = pCnt->GetNextCntntFrm();
2523 						} while ( pCnt && ((SwLayoutFrm*)pFloat)->IsAnLower( pCnt ) );
2524 					}
2525 				}
2526 				else {
2527 					ASSERT( !pFloat, "Neuer Float-Frame?" );
2528                 }
2529 			}
2530 			if ( pFloat->GetNext()	)
2531 			{
2532 				if( bGo )
2533 					pFloat->pUpper = NULL;
2534 				pFloat = pFloat->GetNext();
2535 				if( !bGo && pFloat == pStart )
2536 				{
2537 					bGo = sal_True;
2538 					pFloat->pPrev->pNext = NULL;
2539 					pFloat->pPrev = NULL;
2540 				}
2541 			}
2542 			else
2543 				break;
2544 
2545 		} while ( pFloat );
2546 
2547 		//Die naechste Teilkette suchen und die Ketten miteinander verbinden.
2548 		SwFrm *pTmp = pFloat->FindNext();
2549 		if( bGo )
2550 			pFloat->pUpper = NULL;
2551 
2552 		if( !pLay->IsInFtn() )
2553 			while( pTmp && pTmp->IsInFtn() )
2554 				pTmp = pTmp->FindNext();
2555 
2556 		if ( !pLay->IsAnLower( pTmp ) )
2557 			pTmp = 0;
2558 
2559 		if ( pTmp && bGo )
2560 		{
2561 			pFloat->pNext = pTmp;			//Die beiden Ketten verbinden.
2562 			pFloat->pNext->pPrev = pFloat;
2563 		}
2564 		pFloat = pTmp;
2565 		bGo = bGo || ( pStart == pFloat );
2566 	}  while ( pFloat );
2567 
2568 	return bGo ? pStart : NULL;
2569 }
2570 
2571 // --> OD 2004-11-29 #115759# - add also drawing objects to page and at-fly
2572 // anchored objects to page
2573 void MA_FASTCALL lcl_AddObjsToPage( SwFrm* _pFrm, SwPageFrm* _pPage )
2574 {
2575     ASSERT( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_AddFlysToPage." );
2576     SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
2577 	for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
2578 	{
2579         SwAnchoredObject* pObj = rObjs[i];
2580 
2581         // --> OD 2004-11-29 #115759# - unlock position of anchored object
2582         // in order to get the object's position calculated.
2583         pObj->UnlockPosition();
2584         // <--
2585         // --> OD 2004-11-29 #115759# - add also lower objects of as-character
2586         // anchored Writer fly frames from page
2587         if ( pObj->ISA(SwFlyFrm) )
2588         {
2589             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
2590             if ( pObj->ISA(SwFlyFreeFrm) )
2591             {
2592                 _pPage->AppendFlyToPage( pFlyFrm );
2593             }
2594             pFlyFrm->_InvalidatePos();
2595             pFlyFrm->_InvalidateSize();
2596             pFlyFrm->InvalidatePage( _pPage );
2597 
2598             // --> OD 2004-11-29 #115759# - add also at-fly anchored objects
2599             // to page
2600             if ( pFlyFrm->GetDrawObjs() )
2601             {
2602                 ::lcl_AddObjsToPage( pFlyFrm, _pPage );
2603             }
2604             // <--
2605 
2606             SwCntntFrm *pCnt = pFlyFrm->ContainsCntnt();
2607             while ( pCnt )
2608             {
2609                 if ( pCnt->GetDrawObjs() )
2610                     ::lcl_AddObjsToPage( pCnt, _pPage );
2611                 pCnt = pCnt->GetNextCntntFrm();
2612             }
2613         }
2614         // <--
2615         // --> OD 2004-11-29 #115759# - remove also drawing objects from page
2616         else if ( pObj->ISA(SwAnchoredDrawObject) )
2617         {
2618             if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
2619             {
2620                 pObj->InvalidateObjPos();
2621                 _pPage->AppendDrawObjToPage(
2622                                 *(static_cast<SwAnchoredDrawObject*>(pObj)) );
2623             }
2624         }
2625         // <--
2626 	}
2627 }
2628 
2629 void RestoreCntnt( SwFrm *pSav, SwLayoutFrm *pParent, SwFrm *pSibling, bool bGrow )
2630 {
2631 	ASSERT( pSav && pParent, "Kein Save oder Parent fuer Restore." );
2632     SWRECTFN( pParent )
2633 
2634 	//Wenn es bereits FlowFrms unterhalb des neuen Parent gibt, so wird die
2635 	//Kette, beginnend mit pSav,  hinter dem letzten angehaengt.
2636 	//Die Teile werden kurzerhand insertet und geeignet invalidiert.
2637 	//Unterwegs werden die Flys der CntntFrms bei der Seite angemeldet.
2638 
2639 	SwPageFrm *pPage = pParent->FindPageFrm();
2640 
2641 	if ( pPage )
2642 		pPage->InvalidatePage( pPage ); //Invalides Layout anmelden.
2643 
2644 	//Vorgaenger festellen und die Verbindung herstellen bzw. initialisieren.
2645 	pSav->pPrev = pSibling;
2646 	SwFrm* pNxt;
2647 	if ( pSibling )
2648 	{
2649 		pNxt = pSibling->pNext;
2650 		pSibling->pNext = pSav;
2651 		pSibling->_InvalidatePrt();
2652 		((SwCntntFrm*)pSibling)->InvalidatePage( pPage );//Invaliden Cntnt anmelden.
2653 		if ( ((SwCntntFrm*)pSibling)->GetFollow() )
2654 			pSibling->Prepare( PREP_CLEAR, 0, sal_False );
2655 	}
2656 	else
2657 	{	pNxt = pParent->pLower;
2658 		pParent->pLower = pSav;
2659 		pSav->pUpper = pParent;		//Schon mal setzen, sonst ist fuer das
2660 									//invalidate der Parent (z.B. ein Fly) nicht klar.
2661 		//Invaliden Cntnt anmelden.
2662 		if ( pSav->IsCntntFrm() )
2663 			((SwCntntFrm*)pSav)->InvalidatePage( pPage );
2664 		else
2665 		{   // pSav koennte auch ein leerer SectFrm sein
2666 			SwCntntFrm* pCnt = pParent->ContainsCntnt();
2667 			if( pCnt )
2668 				pCnt->InvalidatePage( pPage );
2669 		}
2670 	}
2671 
2672 	//Der Parent muss entsprechend gegrow'ed werden.
2673 	SwTwips nGrowVal = 0;
2674 	SwFrm* pLast;
2675 	do
2676 	{	pSav->pUpper = pParent;
2677 		nGrowVal += (pSav->Frm().*fnRect->fnGetHeight)();
2678 		pSav->_InvalidateAll();
2679 
2680         //Jetzt die Flys anmelden, fuer TxtFrms gleich geeignet invalidieren.
2681 		if ( pSav->IsCntntFrm() )
2682 		{
2683 			if ( pSav->IsTxtFrm() &&
2684 				 ((SwTxtFrm*)pSav)->GetCacheIdx() != USHRT_MAX )
2685 				((SwTxtFrm*)pSav)->Init();	//Ich bin sein Freund.
2686 
2687 			if ( pPage && pSav->GetDrawObjs() )
2688                 ::lcl_AddObjsToPage( (SwCntntFrm*)pSav, pPage );
2689 		}
2690 		else
2691 		{	SwCntntFrm *pBlub = ((SwLayoutFrm*)pSav)->ContainsCntnt();
2692 			if( pBlub )
2693 			{
2694 				do
2695 				{	if ( pPage && pBlub->GetDrawObjs() )
2696                         ::lcl_AddObjsToPage( pBlub, pPage );
2697 					if( pBlub->IsTxtFrm() && ((SwTxtFrm*)pBlub)->HasFtn() &&
2698 				 		((SwTxtFrm*)pBlub)->GetCacheIdx() != USHRT_MAX )
2699 						((SwTxtFrm*)pBlub)->Init();	//Ich bin sein Freund.
2700 					pBlub = pBlub->GetNextCntntFrm();
2701 				} while ( pBlub && ((SwLayoutFrm*)pSav)->IsAnLower( pBlub ));
2702 			}
2703 		}
2704 		pLast = pSav;
2705 		pSav = pSav->GetNext();
2706 
2707 	} while ( pSav );
2708 
2709 	if( pNxt )
2710 	{
2711 		pLast->pNext = pNxt;
2712 		pNxt->pPrev = pLast;
2713 	}
2714 
2715     if ( bGrow )
2716         pParent->Grow( nGrowVal );
2717 }
2718 
2719 /*************************************************************************
2720 |*
2721 |*	SqRt()				Berechnung der Quadratwurzel, damit die math.lib
2722 |*		nicht auch noch dazugelinkt werden muss.
2723 |*
2724 |*************************************************************************/
2725 
2726 sal_uLong MA_FASTCALL SqRt( BigInt nX )
2727 {
2728 	BigInt nErg = 1;
2729 
2730 	if ( !nX.IsNeg() )
2731 	{
2732 		BigInt nOldErg = 1;
2733 		for ( int i = 0; i <= 5; i++ )
2734 		{
2735 			nErg = (nOldErg + (nX / nOldErg)) / BigInt(2);
2736 			nOldErg = nErg;
2737 		}
2738 	}
2739 	return nErg >= BigInt(SAL_MAX_UINT32) ? ULONG_MAX : (sal_uLong)nErg;
2740 }
2741 
2742 /*************************************************************************/
2743 
2744 SwPageFrm * MA_FASTCALL InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper,
2745 						  sal_Bool bOdd, sal_Bool bInsertEmpty, sal_Bool bFtn,
2746 						  SwFrm *pSibling )
2747 {
2748 	SwPageFrm *pRet;
2749 	SwDoc *pDoc = ((SwLayoutFrm*)pUpper)->GetFmt()->GetDoc();
2750 	SwFrmFmt *pFmt = bOdd ? rDesc.GetRightFmt() : rDesc.GetLeftFmt();
2751 	//Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben
2752 	//eine Leerseite einfuegen.
2753 	if ( !pFmt )
2754 	{
2755 		pFmt = bOdd ? rDesc.GetLeftFmt() : rDesc.GetRightFmt();
2756 		ASSERT( pFmt, "Descriptor without any format?!" );
2757 		bInsertEmpty = !bInsertEmpty;
2758 	}
2759 	if( bInsertEmpty )
2760 	{
2761 		SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ?
2762 				((SwPageFrm*)pSibling->GetPrev())->GetPageDesc() : &rDesc;
2763 		pRet = new SwPageFrm( pDoc->GetEmptyPageFmt(), pUpper, pTmpDesc );
2764 		pRet->Paste( pUpper, pSibling );
2765 		pRet->PreparePage( bFtn );
2766 	}
2767 	pRet = new SwPageFrm( pFmt, pUpper, &rDesc );
2768 	pRet->Paste( pUpper, pSibling );
2769 	pRet->PreparePage( bFtn );
2770 	if ( pRet->GetNext() )
2771 		((SwRootFrm*)pRet->GetUpper())->AssertPageFlys( pRet );
2772 	return pRet;
2773 }
2774 
2775 
2776 /*************************************************************************
2777 |*
2778 |*	RegistFlys(), Regist()	Die beiden folgenden Methoden durchsuchen rekursiv
2779 |*		eine Layoutstruktur und melden alle FlyFrms, die einen beliebigen Frm
2780 |*		innerhalb der Struktur als Anker haben bei der Seite an.
2781 |*
2782 |*************************************************************************/
2783 
2784 void MA_FASTCALL lcl_Regist( SwPageFrm *pPage, const SwFrm *pAnch )
2785 {
2786     SwSortedObjs *pObjs = (SwSortedObjs*)pAnch->GetDrawObjs();
2787 	for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
2788 	{
2789         SwAnchoredObject* pObj = (*pObjs)[i];
2790         if ( pObj->ISA(SwFlyFrm) )
2791 		{
2792             SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
2793 			//Ggf. ummelden, nicht anmelden wenn bereits bekannt.
2794             // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
2795             SwPageFrm *pPg = pFly->IsFlyFreeFrm()
2796                              ? pFly->GetPageFrm() : pFly->FindPageFrm();
2797 			if ( pPg != pPage )
2798 			{
2799 				if ( pPg )
2800                     pPg->RemoveFlyFromPage( pFly );
2801                 pPage->AppendFlyToPage( pFly );
2802 			}
2803 			::RegistFlys( pPage, pFly );
2804 		}
2805 		else
2806 		{
2807             // --> OD 2008-04-22 #i87493#
2808             if ( pPage != pObj->GetPageFrm() )
2809             {
2810                 // --> OD 2004-07-02 #i28701#
2811                 if ( pObj->GetPageFrm() )
2812                     pObj->GetPageFrm()->RemoveDrawObjFromPage( *pObj );
2813                 pPage->AppendDrawObjToPage( *pObj );
2814                 // <--
2815             }
2816             // <--
2817 		}
2818 
2819         const SwFlyFrm* pFly = pAnch->FindFlyFrm();
2820         if ( pFly &&
2821              pObj->GetDrawObj()->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() &&
2822              pObj->GetDrawObj()->GetPage() )
2823         {
2824             //#i119945# set pFly's OrdNum to pObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
2825             pObj->DrawObj()->GetPage()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(),
2826                                                          pObj->GetDrawObj()->GetOrdNumDirect() );
2827         }
2828 	}
2829 }
2830 
2831 void RegistFlys( SwPageFrm *pPage, const SwLayoutFrm *pLay )
2832 {
2833 	if ( pLay->GetDrawObjs() )
2834 		::lcl_Regist( pPage, pLay );
2835 	const SwFrm *pFrm = pLay->Lower();
2836 	while ( pFrm )
2837 	{
2838 		if ( pFrm->IsLayoutFrm() )
2839 			::RegistFlys( pPage, (const SwLayoutFrm*)pFrm );
2840 		else if ( pFrm->GetDrawObjs() )
2841 			::lcl_Regist( pPage, pFrm );
2842 		pFrm = pFrm->GetNext();
2843 	}
2844 }
2845 
2846 /*************************************************************************
2847 |*
2848 |*	void Notify()
2849 |*
2850 |*	Beschreibung		Benachrichtigt den Hintergrund je nach der
2851 |*		Veraenderung zwischen altem und neuem Rechteckt.
2852 |*
2853 |*************************************************************************/
2854 
2855 void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld,
2856              const SwRect* pOldPrt )
2857 {
2858     const SwRect aFrm( pFly->GetObjRectWithSpaces() );
2859 	if ( rOld.Pos() != aFrm.Pos() )
2860 	{	//Positionsaenderung, alten und neuen Bereich invalidieren
2861 		if ( rOld.HasArea() &&
2862 			 rOld.Left()+pFly->GetFmt()->GetLRSpace().GetLeft() < WEIT_WECH )
2863 		{
2864 			pFly->NotifyBackground( pOld, rOld, PREP_FLY_LEAVE );
2865 		}
2866 		pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
2867 	}
2868 	else if ( rOld.SSize() != aFrm.SSize() )
2869 	{	//Groessenaenderung, den Bereich der Verlassen wurde bzw. jetzt
2870 		//ueberdeckt wird invalidieren.
2871 		//Der Einfachheit halber wird hier bewusst jeweils ein Twip
2872 		//unnoetig invalidiert.
2873 
2874 		ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
2875 		if( pSh && rOld.HasArea() )
2876 			pSh->InvalidateWindows( rOld );
2877 
2878         // --> OD 2005-08-19 #i51941# - consider case that fly frame isn't
2879         // registered at the old page <pOld>
2880         SwPageFrm* pPageFrm = pFly->FindPageFrm();
2881         if ( pOld != pPageFrm )
2882         {
2883             pFly->NotifyBackground( pPageFrm, aFrm, PREP_FLY_ARRIVE );
2884         }
2885         // <--
2886 
2887 		if ( rOld.Left() != aFrm.Left() )
2888         {
2889             SwRect aTmp( rOld );
2890 			aTmp.Union( aFrm );
2891 			aTmp.Left(	Min(aFrm.Left(), rOld.Left()) );
2892 			aTmp.Right( Max(aFrm.Left(), rOld.Left()) );
2893 			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2894 		}
2895 		SwTwips nOld = rOld.Right();
2896 		SwTwips nNew = aFrm.Right();
2897 		if ( nOld != nNew )
2898         {
2899             SwRect aTmp( rOld );
2900 			aTmp.Union( aFrm );
2901 			aTmp.Left(	Min(nNew, nOld) );
2902 			aTmp.Right( Max(nNew, nOld) );
2903 			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2904 		}
2905 		if ( rOld.Top() != aFrm.Top() )
2906         {
2907             SwRect aTmp( rOld );
2908 			aTmp.Union( aFrm );
2909 			aTmp.Top(	 Min(aFrm.Top(), rOld.Top()) );
2910 			aTmp.Bottom( Max(aFrm.Top(), rOld.Top()) );
2911 			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2912 		}
2913 		nOld = rOld.Bottom();
2914 		nNew = aFrm.Bottom();
2915 		if ( nOld != nNew )
2916         {
2917             SwRect aTmp( rOld );
2918 			aTmp.Union( aFrm );
2919 			aTmp.Top(	 Min(nNew, nOld) );
2920 			aTmp.Bottom( Max(nNew, nOld) );
2921 			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
2922 		}
2923 	}
2924     else if ( pOldPrt && *pOldPrt != pFly->Prt() &&
2925               pFly->GetFmt()->GetSurround().IsContour() )
2926     {
2927         // #i24097#
2928         pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
2929     }
2930 }
2931 
2932 /*************************************************************************/
2933 
2934 void lcl_CheckFlowBack( SwFrm* pFrm, const SwRect &rRect )
2935 {
2936     SwTwips nBottom = rRect.Bottom();
2937     while( pFrm )
2938     {
2939         if( pFrm->IsLayoutFrm() )
2940         {
2941             if( rRect.IsOver( pFrm->Frm() ) )
2942                 lcl_CheckFlowBack( ((SwLayoutFrm*)pFrm)->Lower(), rRect );
2943         }
2944         else if( !pFrm->GetNext() && nBottom > pFrm->Frm().Bottom() )
2945         {
2946             if( pFrm->IsCntntFrm() && ((SwCntntFrm*)pFrm)->HasFollow() )
2947                 pFrm->InvalidateSize();
2948             else
2949                 pFrm->InvalidateNextPos();
2950         }
2951         pFrm = pFrm->GetNext();
2952     }
2953 }
2954 
2955 void MA_FASTCALL lcl_NotifyCntnt( const SdrObject *pThis, SwCntntFrm *pCnt,
2956 	const SwRect &rRect, const PrepareHint eHint )
2957 {
2958 	if ( pCnt->IsTxtFrm() )
2959 	{
2960 		SwRect aCntPrt( pCnt->Prt() );
2961 		aCntPrt.Pos() += pCnt->Frm().Pos();
2962 		if ( eHint == PREP_FLY_ATTR_CHG )
2963 		{
2964             // --> OD 2004-10-20 #i35640# - use given rectangle <rRect> instead
2965             // of current bound rectangle
2966             if ( aCntPrt.IsOver( rRect ) )
2967             // <--
2968 				pCnt->Prepare( PREP_FLY_ATTR_CHG );
2969 		}
2970         // --> OD 2004-11-01 #i23129# - only invalidate, if the text frame
2971         // printing area overlaps with the given rectangle.
2972         else if ( aCntPrt.IsOver( rRect ) )
2973         // <--
2974 			pCnt->Prepare( eHint, (void*)&aCntPrt._Intersection( rRect ) );
2975 		if ( pCnt->GetDrawObjs() )
2976 		{
2977             const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
2978 			for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
2979 			{
2980                 SwAnchoredObject* pObj = rObjs[i];
2981                 if ( pObj->ISA(SwFlyFrm) )
2982 				{
2983                     SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
2984 					if ( pFly->IsFlyInCntFrm() )
2985 					{
2986 						SwCntntFrm *pCntnt = pFly->ContainsCntnt();
2987 						while ( pCntnt )
2988 						{
2989 							::lcl_NotifyCntnt( pThis, pCntnt, rRect, eHint );
2990 							pCntnt = pCntnt->GetNextCntntFrm();
2991 						}
2992 					}
2993 				}
2994 			}
2995 		}
2996 	}
2997 }
2998 
2999 void Notify_Background( const SdrObject* pObj,
3000                         SwPageFrm* pPage,
3001                         const SwRect& rRect,
3002                         const PrepareHint eHint,
3003                         const sal_Bool bInva )
3004 {
3005 
3006 	//Wenn der Frm gerade erstmalig sinnvoll positioniert wurde, braucht der
3007 	//alte Bereich nicht benachrichtigt werden.
3008 	if ( eHint == PREP_FLY_LEAVE && rRect.Top() == WEIT_WECH )
3009 		 return;
3010 
3011     SwLayoutFrm* pArea;
3012 	SwFlyFrm *pFlyFrm = 0;
3013 	SwFrm* pAnchor;
3014 	if( pObj->ISA(SwVirtFlyDrawObj) )
3015 	{
3016 		pFlyFrm = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
3017         pAnchor = pFlyFrm->AnchorFrm();
3018 	}
3019 	else
3020 	{
3021 		pFlyFrm = NULL;
3022         pAnchor = const_cast<SwFrm*>(
3023                     GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrm() );
3024 	}
3025 	if( PREP_FLY_LEAVE != eHint && pAnchor->IsInFly() )
3026 		pArea = pAnchor->FindFlyFrm();
3027 	else
3028         pArea = pPage;
3029 	SwCntntFrm *pCnt = 0;
3030 	if ( pArea )
3031 	{
3032         if( PREP_FLY_ARRIVE != eHint )
3033             lcl_CheckFlowBack( pArea, rRect );
3034 
3035 		//Es reagieren sowieso nur die auf den Anker folgenden auf den Fly, also
3036 		//brauchen diese nicht abgeklappert werden.
3037 		//Ausnahme sind ist natuerlich das LEAVE, denn der Fly koennte ja von
3038 		//"oben" kommen.
3039 		// Wenn der Anker auf der vorhergehenden Seite liegt, muss ebenfalls
3040 		// die gesamte Seite abgearbeitet werden. (47722)
3041         // OD 2004-05-13 #i28701# - If the wrapping style has to be considered
3042         // on the object positioning, the complete area has to be processed,
3043         // because content frames before the anchor frame also have to consider
3044         // the object for the text wrapping.
3045         // --> OD 2004-08-25 #i3317# - The complete area has always been
3046         // processed.
3047         {
3048 			pCnt = pArea->ContainsCntnt();
3049         }
3050         // <--
3051 	}
3052 	SwFrm *pLastTab = 0;
3053 
3054     while ( pCnt && pArea && pArea->IsAnLower( pCnt ) )
3055 	{
3056 		::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
3057 		if ( pCnt->IsInTab() )
3058 		{
3059 			SwLayoutFrm* pCell = pCnt->GetUpper();
3060             // --> OD 2005-01-14 #i40606# - use <GetLastBoundRect()>
3061             // instead of <GetCurrentBoundRect()>, because a recalculation
3062             // of the bounding rectangle isn't intended here.
3063             if ( pCell->IsCellFrm() &&
3064                  ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) ||
3065                    pCell->Frm().IsOver( rRect ) ) )
3066             // <--
3067 			{
3068 				const SwFmtVertOrient &rOri = pCell->GetFmt()->GetVertOrient();
3069                 if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
3070 					pCell->InvalidatePrt();
3071 			}
3072 			SwTabFrm *pTab = pCnt->FindTabFrm();
3073 			if ( pTab != pLastTab )
3074 			{
3075 				pLastTab = pTab;
3076                 // --> OD 2005-01-14 #i40606# - use <GetLastBoundRect()>
3077                 // instead of <GetCurrentBoundRect()>, because a recalculation
3078                 // of the bounding rectangle isn't intended here.
3079                 if ( pTab->Frm().IsOver( pObj->GetLastBoundRect() ) ||
3080                      pTab->Frm().IsOver( rRect ) )
3081                 // <--
3082 				{
3083                     if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) )
3084 						pTab->InvalidatePrt();
3085 				}
3086 			}
3087 		}
3088 		pCnt = pCnt->GetNextCntntFrm();
3089 	}
3090 // #108745# Sorry, but this causes nothing but trouble. I remove these lines
3091 // taking the risk that the footer frame will have a wrong height
3092 //  if( pPage->Lower() )
3093 //  {
3094 //      SwFrm* pFrm = pPage->Lower();
3095 //      while( pFrm->GetNext() )
3096 //          pFrm = pFrm->GetNext();
3097 //      if( pFrm->IsFooterFrm() &&
3098 //          ( ( pFrm->Frm().IsOver( pObj->GetBoundRect() ) ||
3099 //              pFrm->Frm().IsOver( rRect ) ) ) )
3100 //           pFrm->InvalidateSize();
3101 //  }
3102     // --> OD 2007-07-24 #128702# - make code robust
3103     if ( pPage && pPage->GetSortedObjs() )
3104     // <--
3105 	{
3106 		pObj->GetOrdNum();
3107         const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
3108 		for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
3109 		{
3110             SwAnchoredObject* pAnchoredObj = rObjs[i];
3111             if ( pAnchoredObj->ISA(SwFlyFrm) )
3112 			{
3113                 if( pAnchoredObj->GetDrawObj() == pObj )
3114 					continue;
3115                 SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
3116 				if ( pFly->Frm().Top() == WEIT_WECH )
3117 					continue;
3118 
3119 				if ( !pFlyFrm ||
3120                         (!pFly->IsLowerOf( pFlyFrm ) &&
3121 						pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect()))
3122 				{
3123 					pCnt = pFly->ContainsCntnt();
3124 					while ( pCnt )
3125 					{
3126 						::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
3127 						pCnt = pCnt->GetNextCntntFrm();
3128 					}
3129 				}
3130 				if( pFly->IsFlyLayFrm() )
3131 				{
3132 					if( pFly->Lower() && pFly->Lower()->IsColumnFrm() &&
3133 						pFly->Frm().Bottom() >= rRect.Top() &&
3134 						pFly->Frm().Top() <= rRect.Bottom() &&
3135 						pFly->Frm().Right() >= rRect.Left() &&
3136 						pFly->Frm().Left() <= rRect.Right() )
3137 					 {
3138                         pFly->InvalidateSize();
3139 					 }
3140 				}
3141 				//Flys, die ueber mir liegen muessen/mussten evtl.
3142 				//ausweichen, wenn sie eine automatische Ausrichtung haben.
3143 				//das ist unabhaengig von meinem Attribut, weil dies sich
3144 				//gerade geaendert haben kann und eben deshalb
3145 				//umformatiert wurde.
3146 				else if ( pFly->IsFlyAtCntFrm() &&
3147 						pObj->GetOrdNumDirect() <
3148 						pFly->GetVirtDrawObj()->GetOrdNumDirect() &&
3149                         pFlyFrm && !pFly->IsLowerOf( pFlyFrm ) )
3150 				{
3151 					const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
3152                     if ( text::HoriOrientation::NONE != rH.GetHoriOrient()  &&
3153                             text::HoriOrientation::CENTER != rH.GetHoriOrient()  &&
3154                             ( !pFly->IsAutoPos() || text::RelOrientation::CHAR != rH.GetRelationOrient() ) &&
3155 							(pFly->Frm().Bottom() >= rRect.Top() &&
3156 							pFly->Frm().Top() <= rRect.Bottom()) )
3157 						pFly->InvalidatePos();
3158 				}
3159 			}
3160 		}
3161 	}
3162 	if ( pFlyFrm && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT
3163 		pAnchor->GetUpper()->InvalidateSize();
3164 
3165     // --> OD 2008-01-30 #i82258# - make code robust
3166     ViewShell* pSh = 0;
3167     if ( bInva && pPage &&
3168         0 != (pSh = pPage->getRootFrm()->GetCurrShell()) )
3169     {
3170         pSh->InvalidateWindows( rRect );
3171     }
3172     // <--
3173 }
3174 
3175 /*************************************************************************
3176 |*
3177 |*	GetVirtualUpper() liefert bei absatzgebundenen Objekten den Upper
3178 |*  des Ankers. Falls es sich dabei um verkettete Rahmen oder
3179 |*	Fussnoten handelt, wird ggf. der "virtuelle" Upper ermittelt.
3180 |*
3181 |*************************************************************************/
3182 
3183 const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos )
3184 {
3185 	if( pFrm->IsTxtFrm() )
3186 	{
3187 		pFrm = pFrm->GetUpper();
3188 		if( !pFrm->Frm().IsInside( rPos ) )
3189 		{
3190 			if( pFrm->IsFtnFrm() )
3191 			{
3192 				const SwFtnFrm* pTmp = ((SwFtnFrm*)pFrm)->GetFollow();
3193 				while( pTmp )
3194 				{
3195 					if( pTmp->Frm().IsInside( rPos ) )
3196 						return pTmp;
3197 					pTmp = pTmp->GetFollow();
3198 				}
3199 			}
3200 			else
3201 			{
3202 				SwFlyFrm* pTmp = (SwFlyFrm*)pFrm->FindFlyFrm();
3203 				while( pTmp )
3204 				{
3205 					if( pTmp->Frm().IsInside( rPos ) )
3206 						return pTmp;
3207 					pTmp = pTmp->GetNextLink();
3208 				}
3209 			}
3210 		}
3211 	}
3212 	return pFrm;
3213 }
3214 
3215 /*************************************************************************/
3216 
3217 sal_Bool Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj )
3218 {
3219 	Point aPos;
3220 	const SwFrm* pFrm;
3221 	if( pObj->ISA(SwVirtFlyDrawObj) )
3222 	{
3223 		const SwFlyFrm* pFly = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm();
3224         pFrm = pFly->GetAnchorFrm();
3225 		aPos = pFly->Frm().Pos();
3226 	}
3227 	else
3228 	{
3229         pFrm = ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchorFrm(pObj);
3230 		aPos = pObj->GetCurrentBoundRect().TopLeft();
3231 	}
3232 	ASSERT( pFrm, "8-( Fly is lost in Space." );
3233 	pFrm = GetVirtualUpper( pFrm, aPos );
3234 	do
3235 	{	if ( pFrm == pCurrFrm )
3236 			return sal_True;
3237 		if( pFrm->IsFlyFrm() )
3238 		{
3239 			aPos = pFrm->Frm().Pos();
3240             pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
3241 		}
3242 		else
3243 			pFrm = pFrm->GetUpper();
3244 	} while ( pFrm );
3245 	return sal_False;
3246 }
3247 
3248 const SwFrm *FindKontext( const SwFrm *pFrm, sal_uInt16 nAdditionalKontextTyp )
3249 {
3250 	//Liefert die Umgebung des Frm in die kein Fly aus einer anderen
3251 	//Umgebung hineinragen kann.
3252 	const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
3253 						FRM_FTN  | FRM_FLY      |
3254 						FRM_TAB  | FRM_ROW		| FRM_CELL |
3255 						nAdditionalKontextTyp;
3256 	do
3257 	{	if ( pFrm->GetType() & nTyp )
3258 			break;
3259 		pFrm = pFrm->GetUpper();
3260 	} while( pFrm );
3261 	return pFrm;
3262 }
3263 
3264 sal_Bool IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm )
3265 {
3266 	const SwFrm *pKontext = FindKontext( pInnerFrm, 0 );
3267 
3268 	const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
3269 						FRM_FTN  | FRM_FLY      |
3270 						FRM_TAB  | FRM_ROW 		| FRM_CELL;
3271 	do
3272 	{	if ( pFrm->GetType() & nTyp )
3273 		{
3274 			if( pFrm == pKontext )
3275 				return sal_True;
3276 			if( pFrm->IsCellFrm() )
3277 				return sal_False;
3278 		}
3279 		if( pFrm->IsFlyFrm() )
3280 		{
3281 			Point aPos( pFrm->Frm().Pos() );
3282             pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
3283 		}
3284 		else
3285 			pFrm = pFrm->GetUpper();
3286 	} while( pFrm );
3287 
3288 	return sal_False;
3289 }
3290 
3291 
3292 //---------------------------------
3293 
3294 SwTwips MA_FASTCALL lcl_CalcCellRstHeight( SwLayoutFrm *pCell )
3295 {
3296 	if ( pCell->Lower()->IsCntntFrm() || pCell->Lower()->IsSctFrm() )
3297 	{
3298 		SwFrm *pLow = pCell->Lower();
3299 		long nHeight = 0, nFlyAdd = 0;
3300 		do
3301 		{
3302 			long nLow = pLow->Frm().Height();
3303 			if( pLow->IsTxtFrm() && ((SwTxtFrm*)pLow)->IsUndersized() )
3304 				nLow += ((SwTxtFrm*)pLow)->GetParHeight()-pLow->Prt().Height();
3305 			else if( pLow->IsSctFrm() && ((SwSectionFrm*)pLow)->IsUndersized() )
3306 				nLow += ((SwSectionFrm*)pLow)->Undersize();
3307 			nFlyAdd = Max( 0L, nFlyAdd - nLow );
3308 			nFlyAdd = Max( nFlyAdd, ::CalcHeightWidthFlys( pLow ) );
3309 			nHeight += nLow;
3310 			pLow = pLow->GetNext();
3311 		} while ( pLow );
3312 		if ( nFlyAdd )
3313 			nHeight += nFlyAdd;
3314 
3315 		//Der Border will natuerlich auch mitspielen, er kann leider nicht
3316 		//aus PrtArea und Frm errechnet werden, da diese in beliebiger
3317 		//Kombination ungueltig sein koennen.
3318 		SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell );
3319 		const SwBorderAttrs &rAttrs = *aAccess.Get();
3320 		nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom();
3321 
3322 		return pCell->Frm().Height() - nHeight;
3323 	}
3324 	else
3325 	{
3326 		long nRstHeight = 0;
3327 		SwFrm *pLow = pCell->Lower();
3328 		do
3329 		{	nRstHeight += ::CalcRowRstHeight( (SwLayoutFrm*)pLow );
3330 			pLow = pLow->GetNext();
3331 
3332 		} while ( pLow );
3333 
3334 		return nRstHeight;
3335 	}
3336 }
3337 
3338 SwTwips MA_FASTCALL CalcRowRstHeight( SwLayoutFrm *pRow )
3339 {
3340 	SwTwips nRstHeight = LONG_MAX;
3341 	SwLayoutFrm *pLow = (SwLayoutFrm*)pRow->Lower();
3342 	while ( pLow )
3343 	{
3344 		nRstHeight = Min( nRstHeight, ::lcl_CalcCellRstHeight( pLow ) );
3345 		pLow = (SwLayoutFrm*)pLow->GetNext();
3346 	}
3347 	return nRstHeight;
3348 }
3349 
3350 const SwFrm* MA_FASTCALL FindPage( const SwRect &rRect, const SwFrm *pPage )
3351 {
3352 	if ( !rRect.IsOver( pPage->Frm() ) )
3353 	{
3354         const SwRootFrm* pRootFrm = static_cast<const SwRootFrm*>(pPage->GetUpper());
3355         const SwFrm* pTmpPage = pRootFrm ? pRootFrm->GetPageAtPos( rRect.TopLeft(), &rRect.SSize(), true ) : 0;
3356         if ( pTmpPage )
3357             pPage = pTmpPage;
3358     }
3359 
3360     return pPage;
3361 }
3362 
3363 #include <svl/smplhint.hxx>
3364 class SwFrmHolder : private SfxListener
3365 {
3366     SwFrm* pFrm;
3367     bool bSet;
3368     virtual void Notify(  SfxBroadcaster& rBC, const SfxHint& rHint );
3369 public:
3370     SwFrmHolder() : pFrm(0), bSet(false) {}
3371     void SetFrm( SwFrm* pHold );
3372     SwFrm* GetFrm() { return pFrm; }
3373     void Reset();
3374     bool IsSet() { return bSet; }
3375 };
3376 
3377 void SwFrmHolder::SetFrm( SwFrm* pHold )
3378 {
3379     bSet = true;
3380     pFrm = pHold;
3381     StartListening(*pHold);
3382 }
3383 
3384 void SwFrmHolder::Reset()
3385 {
3386     if (pFrm)
3387         EndListening(*pFrm);
3388     bSet = false;
3389     pFrm = 0;
3390 }
3391 
3392 void SwFrmHolder::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
3393 {
3394     if ( rHint.IsA(TYPE(SfxSimpleHint)) )
3395     {
3396         if ( ( (SfxSimpleHint&) rHint ).GetId() == SFX_HINT_DYING && &rBC == pFrm )
3397             pFrm = 0;
3398     }
3399 }
3400 
3401 SwFrm* GetFrmOfModify( const SwRootFrm* pLayout, SwModify const& rMod, sal_uInt16 const nFrmType,
3402         const Point* pPoint, const SwPosition *pPos, const sal_Bool bCalcFrm )
3403 {
3404 	SwFrm *pMinFrm = 0, *pTmpFrm;
3405     SwFrmHolder aHolder;
3406 	SwRect aCalcRect;
3407     bool bClientIterChanged = false;
3408 
3409 	SwIterator<SwFrm,SwModify> aIter( rMod );
3410 	do {
3411 		pMinFrm = 0;
3412         aHolder.Reset();
3413         sal_uInt64 nMinDist = 0;
3414         bClientIterChanged = false;
3415 
3416 		for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
3417         {
3418 			if( pTmpFrm->GetType() & nFrmType &&
3419                 ( !pLayout || pLayout == pTmpFrm->getRootFrm() ) &&
3420 				(!pTmpFrm->IsFlowFrm() ||
3421 				 !SwFlowFrm::CastFlowFrm( pTmpFrm )->IsFollow() ))
3422 			{
3423 				if( pPoint )
3424 				{
3425                     // watch for Frm being deleted
3426                     if ( pMinFrm )
3427                         aHolder.SetFrm( pMinFrm );
3428                     else
3429                         aHolder.Reset();
3430 
3431 					if( bCalcFrm )
3432                     {
3433                         // --> OD 2005-03-04 #b6234250# - format parent Writer
3434                         // fly frame, if it isn't been formatted yet.
3435                         // Note: The Writer fly frame could be the frame itself.
3436                         SwFlyFrm* pFlyFrm( pTmpFrm->FindFlyFrm() );
3437                         if ( pFlyFrm &&
3438                              pFlyFrm->Frm().Pos().X() == WEIT_WECH &&
3439                              pFlyFrm->Frm().Pos().Y() == WEIT_WECH )
3440                         {
3441                             SwObjectFormatter::FormatObj( *pFlyFrm );
3442                         }
3443                         // <--
3444                         pTmpFrm->Calc();
3445                     }
3446 
3447                     // #127369#
3448                     // aIter.IsChanged checks if the current pTmpFrm has been deleted while
3449                     // it is the current iterator
3450                     // FrmHolder watches for deletion of the current pMinFrm
3451                     if( aIter.IsChanged() || ( aHolder.IsSet() && !aHolder.GetFrm() ) )
3452                     {
3453                         // restart iteration
3454                         bClientIterChanged = true;
3455                         break;
3456                     }
3457 
3458 					// bei Flys ggfs. ueber den Parent gehen wenn sie selbst
3459 					// nocht nicht "formatiert" sind
3460 					if( !bCalcFrm && nFrmType & FRM_FLY &&
3461                         ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm() &&
3462 						WEIT_WECH == pTmpFrm->Frm().Pos().X() &&
3463 						WEIT_WECH == pTmpFrm->Frm().Pos().Y() )
3464                         aCalcRect = ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm()->Frm();
3465 					else
3466 						aCalcRect = pTmpFrm->Frm();
3467 
3468                     if ( aCalcRect.IsInside( *pPoint ) )
3469                     {
3470 					    pMinFrm = pTmpFrm;
3471 						break;
3472                     }
3473 
3474                     // Point not in rectangle. Compare distances:
3475                     const Point aCalcRectCenter = aCalcRect.Center();
3476                     const Point aDiff = aCalcRectCenter - *pPoint;
3477                     const sal_uInt64 nCurrentDist = aDiff.X() * aDiff.X() + aDiff.Y() * aDiff.Y(); // opt: no sqrt
3478                     if ( !pMinFrm || nCurrentDist < nMinDist )
3479                     {
3480         				pMinFrm = pTmpFrm;
3481 	        			nMinDist = nCurrentDist;
3482                     }
3483 				}
3484 				else
3485 				{
3486 					// Wenn kein pPoint angegeben ist, dann reichen
3487 					// wir irgendeinen raus: den ersten!
3488 					pMinFrm = pTmpFrm;
3489 					break;
3490 				}
3491 			}
3492         }
3493 	} while( bClientIterChanged );
3494 
3495 	if( pPos && pMinFrm && pMinFrm->IsTxtFrm() )
3496 		return ((SwTxtFrm*)pMinFrm)->GetFrmAtPos( *pPos );
3497 
3498 	return pMinFrm;
3499 }
3500 
3501 sal_Bool IsExtraData( const SwDoc *pDoc )
3502 {
3503 	const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo();
3504 	return rInf.IsPaintLineNumbers() ||
3505 		   rInf.IsCountInFlys() ||
3506            ((sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE &&
3507 			pDoc->GetRedlineTbl().Count());
3508 }
3509 
3510 // OD 22.09.2003 #110978#
3511 const SwRect SwPageFrm::PrtWithoutHeaderAndFooter() const
3512 {
3513     SwRect aPrtWithoutHeaderFooter( Prt() );
3514     aPrtWithoutHeaderFooter.Pos() += Frm().Pos();
3515 
3516     const SwFrm* pLowerFrm = Lower();
3517     while ( pLowerFrm )
3518     {
3519         // Note: independent on text direction page header and page footer are
3520         //       always at top respectively at bottom of the page frame.
3521         if ( pLowerFrm->IsHeaderFrm() )
3522         {
3523             aPrtWithoutHeaderFooter.Top( aPrtWithoutHeaderFooter.Top() +
3524                                          pLowerFrm->Frm().Height() );
3525         }
3526         if ( pLowerFrm->IsFooterFrm() )
3527         {
3528             aPrtWithoutHeaderFooter.Bottom( aPrtWithoutHeaderFooter.Bottom() -
3529                                             pLowerFrm->Frm().Height() );
3530         }
3531 
3532         pLowerFrm = pLowerFrm->GetNext();
3533     }
3534 
3535     return aPrtWithoutHeaderFooter;
3536 }
3537 
3538 /** method to determine the spacing values of a frame
3539 
3540     OD 2004-03-10 #i28701#
3541     OD 2009-08-28 #i102458#
3542     Add output parameter <obIsLineSpacingProportional>
3543 
3544     @author OD
3545 */
3546 void GetSpacingValuesOfFrm( const SwFrm& rFrm,
3547                             SwTwips& onLowerSpacing,
3548                             SwTwips& onLineSpacing,
3549                             bool& obIsLineSpacingProportional )
3550 {
3551     if ( !rFrm.IsFlowFrm() )
3552     {
3553         onLowerSpacing = 0;
3554         onLineSpacing = 0;
3555     }
3556     else
3557     {
3558         const SvxULSpaceItem& rULSpace = rFrm.GetAttrSet()->GetULSpace();
3559         onLowerSpacing = rULSpace.GetLower();
3560 
3561         onLineSpacing = 0;
3562         obIsLineSpacingProportional = false;
3563         if ( rFrm.IsTxtFrm() )
3564         {
3565             onLineSpacing = static_cast<const SwTxtFrm&>(rFrm).GetLineSpace();
3566             obIsLineSpacingProportional =
3567                 onLineSpacing != 0 &&
3568                 static_cast<const SwTxtFrm&>(rFrm).GetLineSpace( true ) == 0;
3569         }
3570 
3571         ASSERT( onLowerSpacing >= 0 && onLineSpacing >= 0,
3572                 "<GetSpacingValuesOfFrm(..)> - spacing values aren't positive!" );
3573     }
3574 }
3575 
3576 /** method to get the content of the table cell, skipping content from nested tables
3577 */
3578 const SwCntntFrm* GetCellCntnt( const SwLayoutFrm& rCell )
3579 {
3580     const SwCntntFrm* pCntnt = rCell.ContainsCntnt();
3581     const SwTabFrm* pTab = rCell.FindTabFrm();
3582 
3583     while ( pCntnt && rCell.IsAnLower( pCntnt ) )
3584     {
3585         const SwTabFrm* pTmpTab = pCntnt->FindTabFrm();
3586         if ( pTmpTab != pTab )
3587         {
3588             pCntnt = pTmpTab->FindLastCntnt();
3589             if ( pCntnt )
3590 
3591                 pCntnt = pCntnt->FindNextCnt();
3592 
3593         }
3594         else
3595             break;
3596     }
3597     return pCntnt;
3598 }
3599 
3600 /** Can be used to check if a frame has been deleted
3601  */
3602 bool SwDeletionChecker::HasBeenDeleted()
3603 {
3604     if ( !mpFrm || !mpRegIn )
3605         return false;
3606 
3607     SwIterator<SwFrm,SwModify> aIter(*mpRegIn);
3608     SwFrm* pLast = aIter.First();
3609     while ( pLast )
3610     {
3611         if ( pLast == mpFrm )
3612             return false;
3613         pLast = aIter.Next();
3614     }
3615 
3616     return true;
3617 }
3618 
3619 
3620