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