xref: /aoo41x/main/sw/source/core/layout/flycnt.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 #include <tools/bigint.hxx>
32 #include "pagefrm.hxx"
33 #include "cntfrm.hxx"
34 #include "flyfrm.hxx"
35 #include "txtfrm.hxx"
36 #include <doc.hxx>
37 #include <IDocumentUndoRedo.hxx>
38 #include "viewsh.hxx"
39 #include "viewimp.hxx"
40 #include "pam.hxx"
41 #include "frmfmt.hxx"
42 #include "frmtool.hxx"
43 #include "dflyobj.hxx"
44 #include "hints.hxx"
45 #include "ndtxt.hxx"
46 #include "swundo.hxx"
47 #include "errhdl.hxx"
48 #include <editeng/ulspitem.hxx>
49 #include <editeng/lrspitem.hxx>
50 #include <fmtanchr.hxx>
51 #include <fmtornt.hxx>
52 #include <fmtfsize.hxx>
53 #include <fmtsrnd.hxx>
54 
55 #include "tabfrm.hxx"
56 #include "flyfrms.hxx"
57 #include "crstate.hxx"
58 #include "sectfrm.hxx"
59 
60 // OD 29.10.2003 #113049#
61 #include <tocntntanchoredobjectposition.hxx>
62 // OD 2004-05-24 #i28701#
63 #include <dcontact.hxx>
64 #include <sortedobjs.hxx>
65 // --> OD 2005-09-29 #125370#,#125957#
66 #include <layouter.hxx>
67 // <--
68 // --> OD 2005-11-17 #i56300#
69 #include <objectformattertxtfrm.hxx>
70 // <--
71 // --> OD 2006-03-06 #125892#
72 #include <HandleAnchorNodeChg.hxx>
73 // <--
74 
75 using namespace ::com::sun::star;
76 
77 
78 /*************************************************************************
79 |*
80 |*	SwFlyAtCntFrm::SwFlyAtCntFrm()
81 |*
82 |*	Ersterstellung		MA 11. Nov. 92
83 |*	Letzte Aenderung	MA 09. Apr. 99
84 |*
85 |*************************************************************************/
86 
87 SwFlyAtCntFrm::SwFlyAtCntFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
88     SwFlyFreeFrm( pFmt, pSib, pAnch )
89 {
90 	bAtCnt = sal_True;
91     bAutoPosition = (FLY_AT_CHAR == pFmt->GetAnchor().GetAnchorId());
92 }
93 
94 // --> OD 2004-06-29 #i28701#
95 TYPEINIT1(SwFlyAtCntFrm,SwFlyFreeFrm);
96 // <--
97 /*************************************************************************
98 |*
99 |*	SwFlyAtCntFrm::Modify()
100 |*
101 |*	Ersterstellung		MA 08. Feb. 93
102 |*	Letzte Aenderung	MA 23. Nov. 94
103 |*
104 |*************************************************************************/
105 
106 void SwFlyAtCntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
107 {
108 	sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
109 	const SwFmtAnchor *pAnch = 0;
110 
111     if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET ==
112 		((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, sal_False,
113 			(const SfxPoolItem**)&pAnch ))
114 		;		// Beim GetItemState wird der AnkerPointer gesetzt !
115 
116 	else if( RES_ANCHOR == nWhich )
117 	{
118 		//Ankerwechsel, ich haenge mich selbst um.
119 		//Es darf sich nicht um einen Wechsel des Ankertyps handeln,
120 		//dies ist nur ueber die SwFEShell moeglich.
121 		pAnch = (const SwFmtAnchor*)pNew;
122 	}
123 
124 	if( pAnch )
125 	{
126 		ASSERT( pAnch->GetAnchorId() == GetFmt()->GetAnchor().GetAnchorId(),
127 				"Unzulaessiger Wechsel des Ankertyps." );
128 
129 		//Abmelden, neuen Anker besorgen und 'dranhaengen.
130         SwRect aOld( GetObjRectWithSpaces() );
131 		SwPageFrm *pOldPage = FindPageFrm();
132         const SwFrm *pOldAnchor = GetAnchorFrm();
133         SwCntntFrm *pCntnt = (SwCntntFrm*)GetAnchorFrm();
134         AnchorFrm()->RemoveFly( this );
135 
136 		const sal_Bool bBodyFtn = (pCntnt->IsInDocBody() || pCntnt->IsInFtn());
137 
138 		//Den neuen Anker anhand des NodeIdx suchen, am alten und
139 		//neuen NodeIdx kann auch erkannt werden, in welche Richtung
140 		//gesucht werden muss.
141 		const SwNodeIndex aNewIdx( pAnch->GetCntntAnchor()->nNode );
142 		SwNodeIndex aOldIdx( *pCntnt->GetNode() );
143 
144 		//fix: Umstellung, ehemals wurde in der do-while-Schleife nach vorn bzw.
145 		//nach hinten gesucht; je nachdem wie welcher Index kleiner war.
146 		//Das kann aber u.U. zu einer Endlosschleife fuehren. Damit
147 		//wenigstens die Schleife unterbunden wird suchen wir nur in eine
148 		//Richtung. Wenn der neue Anker nicht gefunden wird koennen wir uns
149 		//immer noch vom Node einen Frame besorgen. Die Change, dass dies dann
150 		//der richtige ist, ist gut.
151         const bool bNext = aOldIdx < aNewIdx;
152         // --> OD 2006-02-28 #125892#
153         // consider the case that at found anchor frame candidate already a
154         // fly frame of the given fly format is registered.
155         // --> OD 2006-03-15 #133407# - consider, that <pCntnt> is the already
156         // the new anchor frame.
157         bool bFound( aOldIdx == aNewIdx );
158         // <--
159         while ( pCntnt && !bFound )
160 		{
161 			do
162             {
163                 if ( bNext )
164 					pCntnt = pCntnt->GetNextCntntFrm();
165 				else
166 					pCntnt = pCntnt->GetPrevCntntFrm();
167 			} while ( pCntnt &&
168                       !( bBodyFtn == ( pCntnt->IsInDocBody() ||
169                                        pCntnt->IsInFtn() ) ) );
170             if ( pCntnt )
171 				aOldIdx = *pCntnt->GetNode();
172 
173             // --> OD 2006-02-28 #125892#
174             // check, if at found anchor frame candidate already a fly frame
175             // of the given fly frame format is registered.
176             bFound = aOldIdx == aNewIdx;
177             if ( bFound && pCntnt->GetDrawObjs() )
178             {
179                 SwFrmFmt* pMyFlyFrmFmt( &GetFrmFmt() );
180                 SwSortedObjs &rObjs = *pCntnt->GetDrawObjs();
181                 for( sal_uInt16 i = 0; i < rObjs.Count(); ++i)
182                 {
183                     SwFlyFrm* pFlyFrm = dynamic_cast<SwFlyFrm*>(rObjs[i]);
184                     if ( pFlyFrm &&
185                          &(pFlyFrm->GetFrmFmt()) == pMyFlyFrmFmt )
186                     {
187                         bFound = false;
188                         break;
189                     }
190                 }
191             }
192             // <--
193 		}
194         // <--
195 		if ( !pCntnt )
196 		{
197 			SwCntntNode *pNode = aNewIdx.GetNode().GetCntntNode();
198 			pCntnt = pNode->getLayoutFrm( getRootFrm(), &pOldAnchor->Frm().Pos(), 0, sal_False );
199 			ASSERT( pCntnt, "Neuen Anker nicht gefunden" );
200 		}
201 		//Flys haengen niemals an einem Follow sondern immer am
202 		//Master, den suchen wir uns jetzt.
203         SwCntntFrm* pFlow = pCntnt;
204         while ( pFlow->IsFollow() )
205             pFlow = pFlow->FindMaster();
206         pCntnt = pFlow;
207 
208 		//und schwupp angehaengt das teil...
209 		pCntnt->AppendFly( this );
210 		if ( pOldPage && pOldPage != FindPageFrm() )
211 			NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE );
212 
213 		//Fix(3495)
214 		_InvalidatePos();
215 		InvalidatePage();
216         SetNotifyBack();
217         // --> OD 2004-06-24 #i28701# - reset member <maLastCharRect> and
218         // <mnLastTopOfLine> for to-character anchored objects.
219         ClearCharRectAndTopOfLine();
220     }
221 	else
222 		SwFlyFrm::Modify( pOld, pNew );
223 }
224 
225 /*************************************************************************
226 |*
227 |*	SwFlyAtCntFrm::MakeAll()
228 |*
229 |*	Beschreibung		Bei einem Absatzgebunden Fly kann es durchaus sein,
230 |*		das der Anker auf die Veraenderung des Flys reagiert. Auf diese
231 |* 		Reaktion hat der Fly natuerlich auch wieder zu reagieren.
232 |* 		Leider kann dies zu Oszillationen fuehren z.b. Der Fly will nach
233 |* 		unten, dadurch kann der Inhalt nach oben, der TxtFrm wird kleiner,
234 |*		der Fly muss wieder hoeher woduch der Text wieder nach unten
235 |*		verdraengt wird...
236 |*		Um derartige Oszillationen zu vermeiden, wird ein kleiner Positions-
237 |* 		stack aufgebaut. Wenn der Fly ein Position erreicht, die er bereits
238 |* 		einmal einnahm, so brechen wir den Vorgang ab. Um keine Risiken
239 |* 		einzugehen, wird der Positionsstack so aufgebaut, dass er fuenf
240 |* 		Positionen zurueckblickt.
241 |* 		Wenn der Stack ueberlaeuft, wird ebenfalls abgebrochen.
242 |* 		Der Abbruch fuer dazu, dass der Fly am Ende eine unguenste Position
243 |* 		einnimmt. Damit es nicht durch einen wiederholten Aufruf von
244 |* 		Aussen zu einer 'grossen Oszillation' kommen kann wird im Abbruch-
245 |*		fall das Attribut des Rahmens auf automatische Ausrichtung oben
246 |* 		eingestellt.
247 |*
248 |*	Ersterstellung		MA 12. Nov. 92
249 |*	Letzte Aenderung	MA 20. Sep. 96
250 |*
251 |*************************************************************************/
252 //Wir brauchen ein Paar Hilfsklassen zur Kontrolle der Ozillation und ein paar
253 //Funktionen um die Uebersicht zu gewaehrleisten.
254 // OD 2004-08-25 #i3317# - re-factoring of the position stack
255 class SwOszControl
256 {
257 	static const SwFlyFrm *pStk1;
258 	static const SwFlyFrm *pStk2;
259 	static const SwFlyFrm *pStk3;
260 	static const SwFlyFrm *pStk4;
261 	static const SwFlyFrm *pStk5;
262 
263 	const SwFlyFrm *pFly;
264     // --> OD 2004-08-25 #i3317#
265     sal_uInt8 mnPosStackSize;
266     std::vector<Point*> maObjPositions;
267     // <--
268 
269 public:
270 	SwOszControl( const SwFlyFrm *pFrm );
271 	~SwOszControl();
272     bool ChkOsz();
273 	static sal_Bool IsInProgress( const SwFlyFrm *pFly );
274 };
275 const SwFlyFrm *SwOszControl::pStk1 = 0;
276 const SwFlyFrm *SwOszControl::pStk2 = 0;
277 const SwFlyFrm *SwOszControl::pStk3 = 0;
278 const SwFlyFrm *SwOszControl::pStk4 = 0;
279 const SwFlyFrm *SwOszControl::pStk5 = 0;
280 
281 SwOszControl::SwOszControl( const SwFlyFrm *pFrm )
282     : pFly( pFrm ),
283       // --> OD 2004-08-25 #i3317#
284       mnPosStackSize( 20 )
285       // <--
286 {
287 	if ( !SwOszControl::pStk1 )
288 		SwOszControl::pStk1 = pFly;
289 	else if ( !SwOszControl::pStk2 )
290 		SwOszControl::pStk2 = pFly;
291 	else if ( !SwOszControl::pStk3 )
292 		SwOszControl::pStk3 = pFly;
293 	else if ( !SwOszControl::pStk4 )
294 		SwOszControl::pStk4 = pFly;
295 	else if ( !SwOszControl::pStk5 )
296 		SwOszControl::pStk5 = pFly;
297 }
298 
299 SwOszControl::~SwOszControl()
300 {
301 	if ( SwOszControl::pStk1 == pFly )
302 		SwOszControl::pStk1 = 0;
303 	else if ( SwOszControl::pStk2 == pFly )
304 		SwOszControl::pStk2 = 0;
305 	else if ( SwOszControl::pStk3 == pFly )
306 		SwOszControl::pStk3 = 0;
307 	else if ( SwOszControl::pStk4 == pFly )
308 		SwOszControl::pStk4 = 0;
309 	else if ( SwOszControl::pStk5 == pFly )
310 		SwOszControl::pStk5 = 0;
311     // --> OD 2004-08-25 #i3317#
312     while ( !maObjPositions.empty() )
313     {
314         Point* pPos = maObjPositions.back();
315         delete pPos;
316 
317         maObjPositions.pop_back();
318     }
319     // <--
320 }
321 
322 sal_Bool SwOszControl::IsInProgress( const SwFlyFrm *pFly )
323 {
324     if ( SwOszControl::pStk1 && !pFly->IsLowerOf( SwOszControl::pStk1 ) )
325 		return sal_True;
326     if ( SwOszControl::pStk2 && !pFly->IsLowerOf( SwOszControl::pStk2 ) )
327 		return sal_True;
328     if ( SwOszControl::pStk3 && !pFly->IsLowerOf( SwOszControl::pStk3 ) )
329 		return sal_True;
330     if ( SwOszControl::pStk4 && !pFly->IsLowerOf( SwOszControl::pStk4 ) )
331 		return sal_True;
332     if ( SwOszControl::pStk5 && !pFly->IsLowerOf( SwOszControl::pStk5 ) )
333 		return sal_True;
334 	return sal_False;
335 }
336 
337 bool SwOszControl::ChkOsz()
338 {
339     bool bOscillationDetected = false;
340 
341     if ( maObjPositions.size() == mnPosStackSize )
342     {
343         // position stack is full -> oscillation
344         bOscillationDetected = true;
345     }
346     else
347     {
348         Point* pNewObjPos = new Point( pFly->GetObjRect().Pos() );
349         for ( std::vector<Point*>::iterator aObjPosIter = maObjPositions.begin();
350               aObjPosIter != maObjPositions.end();
351               ++aObjPosIter )
352         {
353             if ( *(pNewObjPos) == *(*aObjPosIter) )
354             {
355                 // position already occured -> oscillation
356                 bOscillationDetected = true;
357                 delete pNewObjPos;
358                 break;
359             }
360         }
361         if ( !bOscillationDetected )
362         {
363             maObjPositions.push_back( pNewObjPos );
364         }
365     }
366 
367     return bOscillationDetected;
368 }
369 
370 void SwFlyAtCntFrm::MakeAll()
371 {
372     // OD 2004-01-19 #110582#
373     if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
374     {
375         return;
376     }
377 
378     if ( !SwOszControl::IsInProgress( this ) && !IsLocked() && !IsColLocked() )
379     {
380         // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
381         if( !GetPageFrm() && GetAnchorFrm() && GetAnchorFrm()->IsInFly() )
382         {
383             SwFlyFrm* pFly = AnchorFrm()->FindFlyFrm();
384             SwPageFrm *pTmpPage = pFly ? pFly->FindPageFrm() : NULL;
385             if( pTmpPage )
386                 pTmpPage->AppendFlyToPage( this );
387         }
388         // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
389         if( GetPageFrm() )
390         {
391             bSetCompletePaintOnInvalidate = sal_True;
392             {
393                 SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
394                 const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
395                 if( rFrmSz.GetHeightPercent() != 0xFF &&
396                     rFrmSz.GetHeightPercent() >= 100 )
397                 {
398                     pFmt->LockModify();
399                     SwFmtSurround aMain( pFmt->GetSurround() );
400                     if ( aMain.GetSurround() == SURROUND_NONE )
401                     {
402                         aMain.SetSurround( SURROUND_THROUGHT );
403                         pFmt->SetFmtAttr( aMain );
404                     }
405                     pFmt->UnlockModify();
406                 }
407             }
408 
409             SwOszControl aOszCntrl( this );
410 
411             // --> OD 2005-02-22 #i43255#
412             // --> OD 2005-06-07 #i50356# - format the anchor frame, which
413             // contains the anchor position. E.g., for at-character anchored
414             // object this can be the follow frame of the anchor frame.
415             const bool bFormatAnchor =
416                     !static_cast<const SwTxtFrm*>( GetAnchorFrmContainingAnchPos() )->IsAnyJoinLocked() &&
417                     !ConsiderObjWrapInfluenceOnObjPos() &&
418                     !ConsiderObjWrapInfluenceOfOtherObjs();
419             // <--
420 
421             const SwFrm* pFooter = GetAnchorFrm()->FindFooterOrHeader();
422             if( pFooter && !pFooter->IsFooterFrm() )
423                 pFooter = NULL;
424             bool bOsz = false;
425             sal_Bool bExtra = Lower() && Lower()->IsColumnFrm();
426             // --> OD 2004-08-25 #i3317# - boolean, to apply temporarly the
427             // 'straightforward positioning process' for the frame due to its
428             // overlapping with a previous column.
429             bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
430             // <--
431             // --> OD 2004-10-22 #i35911# - boolean, to apply temporarly the
432             // 'straightforward positioning process' for the frame due to fact
433             // that it causes the complete content of its layout environment
434             // to move forward.
435             // --> OD 2005-01-14 #i40444# - extend usage of this boolean:
436             // apply temporarly the 'straightforward positioning process' for
437             // the frame due to the fact that the frame clears the area for
438             // the anchor frame, thus it has to move forward.
439             bool bConsiderWrapInfluenceDueToMovedFwdAnchor( false );
440             // <--
441             do {
442                 SWRECTFN( this )
443                 Point aOldPos( (Frm().*fnRect->fnGetPos)() );
444                 SwFlyFreeFrm::MakeAll();
445                 const bool bPosChgDueToOwnFormat =
446                                         aOldPos != (Frm().*fnRect->fnGetPos)();
447                 // --> OD 2004-08-25 #i3317#
448                 if ( !ConsiderObjWrapInfluenceOnObjPos() &&
449                      OverlapsPrevColumn() )
450                 {
451                     bConsiderWrapInfluenceDueToOverlapPrevCol = true;
452                 }
453                 // <--
454                 // OD 2004-05-12 #i28701# - no format of anchor frame, if
455                 // wrapping style influence is considered on object positioning
456                 if ( bFormatAnchor )
457                 {
458                     SwTxtFrm* pAnchPosAnchorFrm =
459                             dynamic_cast<SwTxtFrm*>(GetAnchorFrmContainingAnchPos());
460                     ASSERT( pAnchPosAnchorFrm,
461                             "<SwFlyAtCntFrm::MakeAll()> - anchor frame of wrong type -> crash" );
462                     // --> OD 2006-01-27 #i58182# - For the usage of new method
463                     // <SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..)>
464                     // to check move forward of anchor frame due to the object
465                     // positioning it's needed to know, if the object is anchored
466                     // at the master frame before the anchor frame is formatted.
467                     const bool bAnchoredAtMaster( !pAnchPosAnchorFrm->IsFollow() );
468                     // <--
469 
470                     // --> OD 2005-11-17 #i56300#
471                     // perform complete format of anchor text frame and its
472                     // previous frames, which have become invalid due to the
473                     // fly frame format.
474                     SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( *pAnchPosAnchorFrm );
475                     // <--
476                     // --> OD 2004-10-22 #i35911#
477                     // --> OD 2005-01-14 #i40444#
478                     // --> OD 2006-01-27 #i58182# - usage of new method
479                     // <SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..)>
480                     sal_uInt32 nToPageNum( 0L );
481                     bool bDummy( false );
482                     if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition(
483                                         *this, GetPageFrm()->GetPhyPageNum(),
484                                         bAnchoredAtMaster, nToPageNum, bDummy ) )
485                     {
486                         bConsiderWrapInfluenceDueToMovedFwdAnchor = true;
487                         // --> OD 2005-09-29 #125370#,#125957# - mark anchor text frame
488                         // directly, that it is moved forward by object positioning.
489                         SwTxtFrm* pAnchorTxtFrm( static_cast<SwTxtFrm*>(AnchorFrm()) );
490                         bool bInsert( true );
491                         sal_uInt32 nAnchorFrmToPageNum( 0L );
492                         const SwDoc& rDoc = *(GetFrmFmt().GetDoc());
493                         if ( SwLayouter::FrmMovedFwdByObjPos(
494                                                 rDoc, *pAnchorTxtFrm, nAnchorFrmToPageNum ) )
495                         {
496                             if ( nAnchorFrmToPageNum < nToPageNum )
497                                 SwLayouter::RemoveMovedFwdFrm( rDoc, *pAnchorTxtFrm );
498                             else
499                                 bInsert = false;
500                         }
501                         if ( bInsert )
502                         {
503                             SwLayouter::InsertMovedFwdFrm( rDoc, *pAnchorTxtFrm,
504                                                            nToPageNum );
505                         }
506                         // <--
507                     }
508                     // <--
509                 }
510 
511                 if ( aOldPos != (Frm().*fnRect->fnGetPos)() ||
512                      ( !GetValidPosFlag() &&
513                        ( pFooter || bPosChgDueToOwnFormat ) ) )
514                 {
515                     bOsz = aOszCntrl.ChkOsz();
516 
517                     // --> OD 2006-04-13 #b6403541#
518                     // special loop prevention for dedicated document:
519                     if ( bOsz &&
520                          HasFixSize() && IsClipped() &&
521                          GetAnchorFrm()->GetUpper()->IsCellFrm() )
522                     {
523                         SwFrmFmt* pFmt = GetFmt();
524                         const SwFmtFrmSize& rFrmSz = pFmt->GetFrmSize();
525                         if ( rFrmSz.GetWidthPercent() &&
526                              rFrmSz.GetHeightPercent() == 0xFF )
527                         {
528                             SwFmtSurround aSurround( pFmt->GetSurround() );
529                             if ( aSurround.GetSurround() == SURROUND_NONE )
530                             {
531                                 pFmt->LockModify();
532                                 aSurround.SetSurround( SURROUND_THROUGHT );
533                                 pFmt->SetFmtAttr( aSurround );
534                                 pFmt->UnlockModify();
535                                 bOsz = false;
536 #if OSL_DEBUG_LEVEL > 1
537                                 ASSERT( false,
538                                         "<SwFlyAtCntFrm::MakeAll()> - special loop prevention for dedicated document of b6403541 applied" );
539 #endif
540                             }
541                         }
542                     }
543                     // <--
544                 }
545 
546                 if ( bExtra && Lower() && !Lower()->GetValidPosFlag() )
547                 {
548                     // Wenn ein mehrspaltiger Rahmen wg. Positionswechsel ungueltige
549                     // Spalten hinterlaesst, so drehen wir lieber hier eine weitere
550                     // Runde und formatieren unseren Inhalt via FormatWidthCols nochmal.
551                         _InvalidateSize();
552                     bExtra = sal_False; // Sicherhaltshalber gibt es nur eine Ehrenrunde.
553                 }
554             } while ( !IsValid() && !bOsz &&
555                       // --> OD 2004-08-25 #i3317#
556                       !bConsiderWrapInfluenceDueToOverlapPrevCol &&
557                       // <--
558                       // --> OD 2005-01-14 #i40444#
559                       !bConsiderWrapInfluenceDueToMovedFwdAnchor &&
560                       // <--
561                       GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) );
562 
563             // --> OD 2004-08-25 #i3317# - instead of attribute change apply
564             // temporarly the 'straightforward positioning process'.
565             // --> OD 2007-11-29 #i80924#
566             // handle special case during splitting of table rows
567             if ( bConsiderWrapInfluenceDueToMovedFwdAnchor &&
568                  GetAnchorFrm()->IsInTab() &&
569                  GetAnchorFrm()->IsInFollowFlowRow() )
570             {
571                 const SwFrm* pCellFrm = GetAnchorFrm();
572                 while ( pCellFrm && !pCellFrm->IsCellFrm() )
573                 {
574                     pCellFrm = pCellFrm->GetUpper();
575                 }
576                 if ( pCellFrm )
577                 {
578                     SWRECTFN( pCellFrm )
579                     if ( (pCellFrm->Frm().*fnRect->fnGetTop)() == 0 &&
580                          (pCellFrm->Frm().*fnRect->fnGetHeight)() == 0 )
581                     {
582                         bConsiderWrapInfluenceDueToMovedFwdAnchor = false;
583                     }
584                 }
585             }
586             // <--
587             if ( bOsz || bConsiderWrapInfluenceDueToOverlapPrevCol ||
588                  // --> OD 2005-01-14 #i40444#
589                  bConsiderWrapInfluenceDueToMovedFwdAnchor )
590                  // <--
591             {
592                 SetTmpConsiderWrapInfluence( true );
593                 SetRestartLayoutProcess( true );
594                 // --> OD 2006-07-24 #b6449874#
595                 SetTmpConsiderWrapInfluenceOfOtherObjs( true );
596                 // <--
597             }
598             // <--
599             bSetCompletePaintOnInvalidate = sal_False;
600         }
601     }
602 }
603 
604 /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
605 
606     OD 2004-05-11 #i28701#
607 
608     @author OD
609 */
610 bool SwFlyAtCntFrm::IsFormatPossible() const
611 {
612     return SwFlyFreeFrm::IsFormatPossible() &&
613            !SwOszControl::IsInProgress( this );
614 }
615 
616 /*************************************************************************
617 |*
618 |*	FindAnchor() und Hilfsfunktionen.
619 |*
620 |*	Beschreibung:		Sucht ausgehend von pOldAnch einen Anker fuer
621 |*		Absatzgebundene Objekte.
622 |*		Wird beim Draggen von Absatzgebundenen Objekten zur Ankeranzeige sowie
623 |*		fuer Ankerwechsel benoetigt.
624 |*	Ersterstellung		MA 22. Jun. 93
625 |*	Letzte Aenderung	MA 30. Jan. 95
626 |*
627 |*************************************************************************/
628 
629 class SwDistance
630 {
631 public:
632 	SwTwips nMain, nSub;
633 	SwDistance() { nMain = nSub = 0; }
634 	SwDistance& operator=( const SwDistance &rTwo )
635 		{ nMain = rTwo.nMain; nSub = rTwo.nSub; return *this; }
636 	sal_Bool operator<( const SwDistance& rTwo )
637 		{ return nMain < rTwo.nMain || ( nMain == rTwo.nMain && nSub &&
638 		  rTwo.nSub && nSub < rTwo.nSub ); }
639 	sal_Bool operator<=( const SwDistance& rTwo )
640 		{ return nMain < rTwo.nMain || ( nMain == rTwo.nMain && ( !nSub ||
641 		  !rTwo.nSub || nSub <= rTwo.nSub ) ); }
642 };
643 
644 const SwFrm * MA_FASTCALL lcl_CalcDownDist( SwDistance &rRet,
645 										 const Point &rPt,
646 										 const SwCntntFrm *pCnt )
647 {
648 	rRet.nSub = 0;
649 	//Wenn der Point direkt innerhalb des Cnt steht ist die Sache klar und
650 	//der Cntnt hat automatisch eine Entfernung von 0
651 	if ( pCnt->Frm().IsInside( rPt ) )
652 	{
653 		rRet.nMain = 0;
654 		return pCnt;
655 	}
656 	else
657 	{
658 		const SwLayoutFrm *pUp = pCnt->IsInTab() ? pCnt->FindTabFrm()->GetUpper() : pCnt->GetUpper();
659 		// einspaltige Bereiche muessen zu ihrem Upper durchschalten
660 		while( pUp->IsSctFrm() )
661 			pUp = pUp->GetUpper();
662         const bool bVert = pUp->IsVertical();
663         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
664         const bool bVertL2R = pUp->IsVertLR();
665 
666 		//Dem Textflus folgen.
667         // --> OD 2009-01-12 #i70582#
668         // --> OD 2009-03-05 - adopted for Support for Classical Mongolian Script
669         const SwTwips nTopForObjPos =
670             bVert
671             ? ( bVertL2R
672                 ? ( pCnt->Frm().Left() +
673                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
674                 : ( pCnt->Frm().Left() +
675                     pCnt->Frm().Width() -
676                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
677             : ( pCnt->Frm().Top() +
678                 pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
679         // <--
680         if ( pUp->Frm().IsInside( rPt ) )
681 		{
682             // OD 26.09.2003 - <rPt> point is inside environment of given content frame
683             // --> OD 2009-01-12 #i70582#
684             if( bVert )
685             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
686             {
687                	if ( bVertL2R )
688                     rRet.nMain =  rPt.X() - nTopForObjPos;
689 				else
690                     rRet.nMain =  nTopForObjPos - rPt.X();
691             }
692             else
693                 rRet.nMain =  rPt.Y() - nTopForObjPos;
694             // <--
695 			return pCnt;
696 		}
697         else if ( rPt.Y() <= pUp->Frm().Top() )
698         {
699             // OD 26.09.2003 - <rPt> point is above environment of given content frame
700             // OD: correct for vertical layout?
701             rRet.nMain = LONG_MAX;
702         }
703         else if( rPt.X() < pUp->Frm().Left() &&
704                  rPt.Y() <= ( bVert ? pUp->Frm().Top() : pUp->Frm().Bottom() ) )
705 		{
706             // OD 26.09.2003 - <rPt> point is left of environment of given content frame
707             // OD: seems not to be correct for vertical layout!?
708             const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, sal_False, pCnt );
709             if( !pLay ||
710                 (bVert && (pLay->Frm().Top() + pLay->Prt().Bottom()) <rPt.Y())||
711                 (!bVert && (pLay->Frm().Left() + pLay->Prt().Right())<rPt.X()) )
712 			{
713                 // OD 26.09.2003 - <rPt> point is in left border of environment
714                 // --> OD 2009-01-12 #i70582#
715                 if( bVert )
716                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
717                 {
718                    	if ( bVertL2R )
719                         rRet.nMain = rPt.X() - nTopForObjPos;
720 	    			else
721                         rRet.nMain =  nTopForObjPos - rPt.X();
722                 }
723                 else
724                     rRet.nMain = rPt.Y() - nTopForObjPos;
725                 // <--
726 				return pCnt;
727 			}
728 			else
729 				rRet.nMain = LONG_MAX;
730 		}
731         else
732 		{
733             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
734             // --> OD 2009-01-12 #i70582#
735             rRet.nMain = bVert
736                 ? ( bVertL2R
737                     ? ( (pUp->Frm().Left() + pUp->Prt().Right()) - nTopForObjPos )
738                     : ( nTopForObjPos - (pUp->Frm().Left() + pUp->Prt().Left() ) ) )
739                 : ( (pUp->Frm().Top() + pUp->Prt().Bottom()) - nTopForObjPos );
740 
741 			const SwFrm *pPre = pCnt;
742 			const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, sal_True, pCnt );
743 			SwTwips nFrmTop = 0;
744             SwTwips nPrtHeight = 0;
745 			sal_Bool bSct = sal_False;
746 			const SwSectionFrm *pSect = pUp->FindSctFrm();
747 			if( pSect )
748 			{
749 				rRet.nSub = rRet.nMain;
750 				rRet.nMain = 0;
751 			}
752 			if( pSect && !pSect->IsAnLower( pLay ) )
753 			{
754 				bSct = sal_False;
755 				const SwSectionFrm* pNxtSect = pLay ? pLay->FindSctFrm() : 0;
756 				if( pSect->IsAnFollow( pNxtSect ) )
757 				{
758                     if( pLay->IsVertical() )
759                     {
760                     	//Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
761                         if ( pLay->IsVertLR() )
762                         	nFrmTop = pLay->Frm().Left();
763                         else
764                         	nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
765                         nPrtHeight = pLay->Prt().Width();
766                     }
767                     else
768                     {
769                         nFrmTop = pLay->Frm().Top();
770                         nPrtHeight = pLay->Prt().Height();
771                     }
772 					pSect = pNxtSect;
773 				}
774 				else
775 				{
776 					pLay = pSect->GetUpper();
777                     if( pLay->IsVertical() )
778                     {
779                         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
780                         if ( pLay->IsVertLR() )
781 						{
782 							nFrmTop = pSect->Frm().Right();
783                         	nPrtHeight = pLay->Frm().Left() + pLay->Prt().Left()
784                             	         + pLay->Prt().Width() - pSect->Frm().Left()
785                                 	     - pSect->Frm().Width();
786                          }
787                          else
788                          {
789                          	nFrmTop = pSect->Frm().Left();
790                          	nPrtHeight = pSect->Frm().Left() - pLay->Frm().Left()
791                                      - pLay->Prt().Left();
792                           }
793                     }
794                     else
795                     {
796                         nFrmTop = pSect->Frm().Bottom();
797                         nPrtHeight = pLay->Frm().Top() + pLay->Prt().Top()
798                                      + pLay->Prt().Height() - pSect->Frm().Top()
799                                      - pSect->Frm().Height();
800                     }
801 					pSect = 0;
802 				}
803 			}
804 			else if( pLay )
805 			{
806                 if( pLay->IsVertical() )
807                 {
808                     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
809                     if ( pLay->IsVertLR() )
810 		    		{
811                     	nFrmTop = pLay->Frm().Left();
812                     	nPrtHeight = pLay->Prt().Width();
813                     }
814                     else
815                     {
816                     	nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
817                     	nPrtHeight = pLay->Prt().Width();
818                     }
819                 }
820                 else
821                 {
822                     nFrmTop = pLay->Frm().Top();
823                     nPrtHeight = pLay->Prt().Height();
824                 }
825 				bSct = 0 != pSect;
826 			}
827 			while ( pLay && !pLay->Frm().IsInside( rPt ) &&
828 					( pLay->Frm().Top() <= rPt.Y() || pLay->IsInFly() ||
829 					  ( pLay->IsInSct() &&
830 					  pLay->FindSctFrm()->GetUpper()->Frm().Top() <= rPt.Y())) )
831 			{
832 				if ( pLay->IsFtnContFrm() )
833 				{
834 					if ( !((SwLayoutFrm*)pLay)->Lower() )
835 					{
836 						SwFrm *pDel = (SwFrm*)pLay;
837 						pDel->Cut();
838 						delete pDel;
839 						return pPre;
840 					}
841 					return 0;
842 				}
843 				else
844 				{
845 					if( bSct || pSect )
846 						rRet.nSub += nPrtHeight;
847 					else
848 						rRet.nMain += nPrtHeight;
849 					pPre = pLay;
850 					pLay = pLay->GetLeaf( MAKEPAGE_NONE, sal_True, pCnt );
851 					if( pSect && !pSect->IsAnLower( pLay ) )
852 					{   // If we're leaving a SwSectionFrm, the next Leaf-Frm
853 						// is the part of the upper below the SectionFrm.
854 						const SwSectionFrm* pNxtSect = pLay ?
855 							pLay->FindSctFrm() : NULL;
856 						bSct = sal_False;
857 						if( pSect->IsAnFollow( pNxtSect ) )
858 						{
859 							pSect = pNxtSect;
860                             if( pLay->IsVertical() )
861                             {
862                                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
863                                 if ( pLay->IsVertLR() )
864 								{
865 								    nFrmTop = pLay->Frm().Left();
866                                 	nPrtHeight = pLay->Prt().Width();
867                                 }
868                                 else
869                                 {
870                                 	nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
871                                 	nPrtHeight = pLay->Prt().Width();
872                                 }
873                             }
874                             else
875                             {
876                                 nFrmTop = pLay->Frm().Top();
877                                 nPrtHeight = pLay->Prt().Height();
878                             }
879 						}
880 						else
881 						{
882 							pLay = pSect->GetUpper();
883                             if( pLay->IsVertical() )
884                             {
885                                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
886                                 if ( pLay->IsVertLR() )
887 								{
888                                 	nFrmTop = pSect->Frm().Right();
889                                 	nPrtHeight = pLay->Frm().Left()+pLay->Prt().Left()
890                                      		+ pLay->Prt().Width() - pSect->Frm().Left()
891                                      		- pSect->Frm().Width();
892                                 }
893                                 else
894                                 {
895                                 	nFrmTop = pSect->Frm().Left();
896                                 	nPrtHeight = pSect->Frm().Left() -
897                                         	pLay->Frm().Left() - pLay->Prt().Left();
898                                 }
899                             }
900                             else
901                             {
902                                 nFrmTop = pSect->Frm().Bottom();
903                                 nPrtHeight = pLay->Frm().Top()+pLay->Prt().Top()
904                                      + pLay->Prt().Height() - pSect->Frm().Top()
905                                      - pSect->Frm().Height();
906                             }
907 							pSect = 0;
908 						}
909 					}
910 					else if( pLay )
911 					{
912                         if( pLay->IsVertical() )
913                         {
914                              //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
915                              if ( pLay->IsVertLR() )
916 			     			 {
917 			     				nFrmTop = pLay->Frm().Left();
918                              	nPrtHeight = pLay->Prt().Width();
919                              }
920                              else
921                              {
922                              	nFrmTop = pLay->Frm().Left() + pLay->Frm().Width();
923                              	nPrtHeight = pLay->Prt().Width();
924                              }
925                         }
926                         else
927                         {
928                             nFrmTop = pLay->Frm().Top();
929                             nPrtHeight = pLay->Prt().Height();
930                         }
931 						bSct = 0 != pSect;
932 					}
933 				}
934 			}
935 			if ( pLay )
936 			{
937 				if ( pLay->Frm().IsInside( rPt ) )
938 				{
939                     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
940                     SwTwips nDiff = pLay->IsVertical() ? ( pLay->IsVertLR() ? ( rPt.X() - nFrmTop ) : ( nFrmTop - rPt.X() ) )
941                                                        : ( rPt.Y() - nFrmTop );
942                     if( bSct || pSect )
943                         rRet.nSub += nDiff;
944                     else
945                         rRet.nMain += nDiff;
946 				}
947 				if ( pLay->IsFtnContFrm() && !((SwLayoutFrm*)pLay)->Lower() )
948 				{
949 					SwFrm *pDel = (SwFrm*)pLay;
950 					pDel->Cut();
951 					delete pDel;
952 					return 0;
953 				}
954 				return pLay;
955 			}
956 			else
957 				rRet.nMain = LONG_MAX;
958 		}
959 	}
960 	return 0;
961 }
962 
963 sal_uLong MA_FASTCALL lcl_FindCntDiff( const Point &rPt, const SwLayoutFrm *pLay,
964 						  const SwCntntFrm *& rpCnt,
965 						  const sal_Bool bBody, const sal_Bool bFtn )
966 {
967 	//Sucht unterhalb von pLay den dichtesten Cnt zum Point. Der Bezugspunkt
968 	//der Cntnts ist immer die linke obere Ecke.
969 	//Der Cnt soll moeglichst ueber dem Point liegen.
970 
971 #if OSL_DEBUG_LEVEL > 1
972 	Point arPoint( rPt );
973 #endif
974 
975 	rpCnt = 0;
976 	sal_uLong nDistance = ULONG_MAX;
977 	sal_uLong nNearest	= ULONG_MAX;
978 	const SwCntntFrm *pCnt = pLay->ContainsCntnt();
979 
980 	while ( pCnt && (bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn()))
981 	{
982 		pCnt = pCnt->GetNextCntntFrm();
983 		if ( !pLay->IsAnLower( pCnt ) )
984 			pCnt = 0;
985 	}
986 	const SwCntntFrm *pNearest = pCnt;
987 	if ( pCnt )
988 	{
989 		do
990 		{
991 			//Jetzt die Entfernung zwischen den beiden Punkten berechnen.
992 			//'Delta' X^2 + 'Delta'Y^2 = 'Entfernung'^2
993 			sal_uInt32 dX = Max( pCnt->Frm().Left(), rPt.X() ) -
994 					   Min( pCnt->Frm().Left(), rPt.X() ),
995 				  dY = Max( pCnt->Frm().Top(), rPt.Y() ) -
996 					   Min( pCnt->Frm().Top(), rPt.Y() );
997 			BigInt dX1( dX ), dY1( dY );
998 			dX1 *= dX1; dY1 *= dY1;
999 			const sal_uLong nDiff = ::SqRt( dX1 + dY1 );
1000 			if ( pCnt->Frm().Top() <= rPt.Y() )
1001 			{
1002 				if ( nDiff < nDistance )
1003 				{	//Der ist dichter dran
1004 					nDistance = nNearest = nDiff;
1005 					rpCnt = pNearest = pCnt;
1006 				}
1007 			}
1008 			else if ( nDiff < nNearest )
1009 			{
1010 				nNearest = nDiff;
1011 				pNearest = pCnt;
1012 			}
1013 			pCnt = pCnt->GetNextCntntFrm();
1014 			while ( pCnt &&
1015 					(bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn()))
1016 				pCnt = pCnt->GetNextCntntFrm();
1017 
1018 		}  while ( pCnt && pLay->IsAnLower( pCnt ) );
1019 	}
1020 	if ( nDistance == ULONG_MAX )
1021 	{	rpCnt = pNearest;
1022 		return nNearest;
1023 	}
1024 	return nDistance;
1025 }
1026 
1027 const SwCntntFrm * MA_FASTCALL lcl_FindCnt( const Point &rPt, const SwCntntFrm *pCnt,
1028 								  const sal_Bool bBody, const sal_Bool bFtn )
1029 {
1030 	//Sucht ausgehen von pCnt denjenigen CntntFrm, dessen linke obere
1031 	//Ecke am dichtesten am Point liegt.
1032 	//Liefert _immer_ einen CntntFrm zurueck.
1033 
1034 	//Zunaechst wird versucht den dichtesten Cntnt innerhalt derjenigen
1035 	//Seite zu suchen innerhalb derer der Cntnt steht.
1036 	//Ausgehend von der Seite muessen die Seiten in beide
1037 	//Richtungen beruecksichtigt werden.
1038 	//Falls moeglich wird ein Cntnt geliefert, dessen Y-Position ueber der
1039 	//des Point sitzt.
1040 	const SwCntntFrm  *pRet, *pNew;
1041 	const SwLayoutFrm *pLay = pCnt->FindPageFrm();
1042 	sal_uLong nDist;
1043 
1044 	nDist = ::lcl_FindCntDiff( rPt, pLay, pNew, bBody, bFtn );
1045 	if ( pNew )
1046 		pRet = pNew;
1047 	else
1048 	{	pRet  = pCnt;
1049 		nDist = ULONG_MAX;
1050 	}
1051 	const SwCntntFrm *pNearest = pRet;
1052 	sal_uLong nNearest = nDist;
1053 
1054 	if ( pLay )
1055 	{
1056 		const SwLayoutFrm *pPge = pLay;
1057 		sal_uLong nOldNew = ULONG_MAX;
1058 		for ( sal_uInt16 i = 0; pPge->GetPrev() && (i < 3); ++i )
1059 		{
1060 			pPge = (SwLayoutFrm*)pPge->GetPrev();
1061 			const sal_uLong nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn );
1062 			if ( nNew < nDist )
1063 			{
1064 				if ( pNew->Frm().Top() <= rPt.Y() )
1065 				{
1066 					pRet = pNearest = pNew;
1067 					nDist = nNearest = nNew;
1068 				}
1069 				else if ( nNew < nNearest )
1070 				{
1071 					pNearest = pNew;
1072 					nNearest = nNew;
1073 				}
1074 			}
1075 			else if ( nOldNew != ULONG_MAX && nNew > nOldNew )
1076 				break;
1077 			else
1078 				nOldNew = nNew;
1079 
1080 		}
1081 		pPge = pLay;
1082 		nOldNew = ULONG_MAX;
1083 		for ( sal_uInt16 j = 0; pPge->GetNext() && (j < 3); ++j )
1084 		{
1085 			pPge = (SwLayoutFrm*)pPge->GetNext();
1086 			const sal_uLong nNew = ::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn );
1087 			if ( nNew < nDist )
1088 			{
1089 				if ( pNew->Frm().Top() <= rPt.Y() )
1090 				{
1091 					pRet = pNearest = pNew;
1092 					nDist = nNearest = nNew;
1093 				}
1094 				else if ( nNew < nNearest )
1095 				{
1096 					pNearest = pNew;
1097 					nNearest = nNew;
1098 				}
1099 			}
1100 			else if ( nOldNew != ULONG_MAX && nNew > nOldNew )
1101 				break;
1102 			else
1103 				nOldNew = nNew;
1104 		}
1105 	}
1106 	if ( (pRet->Frm().Top() > rPt.Y()) )
1107 		return pNearest;
1108 	else
1109 		return pRet;
1110 }
1111 
1112 void lcl_PointToPrt( Point &rPoint, const SwFrm *pFrm )
1113 {
1114 	SwRect aTmp( pFrm->Prt() );
1115 	aTmp += pFrm->Frm().Pos();
1116 	if ( rPoint.X() < aTmp.Left() )
1117 		rPoint.X() = aTmp.Left();
1118 	else if ( rPoint.X() > aTmp.Right() )
1119 		rPoint.X() = aTmp.Right();
1120 	if ( rPoint.Y() < aTmp.Top() )
1121 		rPoint.Y() = aTmp.Top();
1122 	else if ( rPoint.Y() > aTmp.Bottom() )
1123 		rPoint.Y() = aTmp.Bottom();
1124 
1125 }
1126 
1127 const SwCntntFrm *FindAnchor( const SwFrm *pOldAnch, const Point &rNew,
1128 							  const sal_Bool bBodyOnly )
1129 {
1130     //Zu der angegebenen DokumentPosition wird der dichteste Cnt im
1131 	//Textfluss gesucht. AusgangsFrm ist der uebergebene Anker.
1132     const SwCntntFrm* pCnt;
1133 	if ( pOldAnch->IsCntntFrm() )
1134     {
1135 		pCnt = (const SwCntntFrm*)pOldAnch;
1136     }
1137 	else
1138     {
1139         Point aTmp( rNew );
1140 		SwLayoutFrm *pTmpLay = (SwLayoutFrm*)pOldAnch;
1141 		if( pTmpLay->IsRootFrm() )
1142 		{
1143 			SwRect aTmpRect( aTmp, Size(0,0) );
1144 			pTmpLay = (SwLayoutFrm*)::FindPage( aTmpRect, pTmpLay->Lower() );
1145 		}
1146 		pCnt = pTmpLay->GetCntntPos( aTmp, sal_False, bBodyOnly );
1147 	}
1148 
1149 	//Beim Suchen darauf achten, dass die Bereiche sinnvoll erhalten
1150 	//bleiben. D.h. in diesem Fall nicht in Header/Footer hinein und
1151 	//nicht aus Header/Footer hinaus.
1152 	const sal_Bool bBody = pCnt->IsInDocBody() || bBodyOnly;
1153 	const sal_Bool bFtn  = !bBodyOnly && pCnt->IsInFtn();
1154 
1155 	Point aNew( rNew );
1156 	if ( bBody )
1157 	{
1158 		//#38848 Vom Seitenrand in den Body ziehen.
1159 		const SwFrm *pPage = pCnt->FindPageFrm();
1160 		::lcl_PointToPrt( aNew, pPage->GetUpper() );
1161 		SwRect aTmp( aNew, Size( 0, 0 ) );
1162 		pPage = ::FindPage( aTmp, pPage );
1163 		::lcl_PointToPrt( aNew, pPage );
1164 	}
1165 
1166 	if ( pCnt->IsInDocBody() == bBody && pCnt->Frm().IsInside( aNew ) )
1167 		return pCnt;
1168 	else if ( pOldAnch->IsInDocBody() || pOldAnch->IsPageFrm() )
1169 	{
1170 		//Vielleicht befindet sich der gewuenschte Anker ja auf derselben
1171 		//Seite wie der aktuelle Anker.
1172 		//So gibt es kein Problem mit Spalten.
1173 		Point aTmp( aNew );
1174 		const SwCntntFrm *pTmp = pCnt->FindPageFrm()->
1175 										GetCntntPos( aTmp, sal_False, sal_True, sal_False );
1176 		if ( pTmp && pTmp->Frm().IsInside( aNew ) )
1177 			return pTmp;
1178 	}
1179 
1180 	//Ausgehend vom Anker suche ich jetzt in beide Richtungen bis ich
1181 	//den jeweils dichtesten gefunden habe.
1182 	//Nicht die direkte Entfernung ist relevant sondern die Strecke die
1183 	//im Textfluss zurueckgelegt werden muss.
1184 	const SwCntntFrm *pUpLst;
1185 	const SwCntntFrm *pUpFrm = pCnt;
1186 	SwDistance nUp, nUpLst;
1187 	::lcl_CalcDownDist( nUp, aNew, pUpFrm );
1188 	SwDistance nDown = nUp;
1189 	sal_Bool bNegAllowed = sal_True;//Einmal aus dem negativen Bereich heraus lassen.
1190 	do
1191 	{
1192 		pUpLst = pUpFrm; nUpLst = nUp;
1193 		pUpFrm = pUpLst->GetPrevCntntFrm();
1194 		while ( pUpFrm &&
1195 				(bBody != pUpFrm->IsInDocBody() || bFtn != pUpFrm->IsInFtn()))
1196 			pUpFrm = pUpFrm->GetPrevCntntFrm();
1197 		if ( pUpFrm )
1198 		{
1199 			::lcl_CalcDownDist( nUp, aNew, pUpFrm );
1200 			//Wenn die Distanz innnerhalb einer Tabelle waechst, so lohnt es
1201 			//sich weiter zu suchen.
1202 			if ( pUpLst->IsInTab() && pUpFrm->IsInTab() )
1203 			{
1204 				while ( pUpFrm && ((nUpLst < nUp && pUpFrm->IsInTab()) ||
1205 						bBody != pUpFrm->IsInDocBody()) )
1206 				{
1207 					pUpFrm = pUpFrm->GetPrevCntntFrm();
1208 					if ( pUpFrm )
1209 						::lcl_CalcDownDist( nUp, aNew, pUpFrm );
1210 				}
1211 			}
1212 		}
1213 		if ( !pUpFrm )
1214 			nUp.nMain = LONG_MAX;
1215         if ( nUp.nMain >= 0 && LONG_MAX != nUp.nMain )
1216 		{
1217 			bNegAllowed = sal_False;
1218 			if ( nUpLst.nMain < 0 ) //nicht den falschen erwischen, wenn der Wert
1219 									//gerade von negativ auf positiv gekippt ist.
1220 			{	pUpLst = pUpFrm;
1221 				nUpLst = nUp;
1222 			}
1223 		}
1224     } while ( pUpFrm && ( ( bNegAllowed && nUp.nMain < 0 ) || ( nUp <= nUpLst ) ) );
1225 
1226 	const SwCntntFrm *pDownLst;
1227 	const SwCntntFrm *pDownFrm = pCnt;
1228 	SwDistance nDownLst;
1229 	if ( nDown.nMain < 0 )
1230 		nDown.nMain = LONG_MAX;
1231 	do
1232 	{
1233 		pDownLst = pDownFrm; nDownLst = nDown;
1234 		pDownFrm = pDownLst->GetNextCntntFrm();
1235 		while ( pDownFrm &&
1236 				(bBody != pDownFrm->IsInDocBody() || bFtn != pDownFrm->IsInFtn()))
1237 			pDownFrm = pDownFrm->GetNextCntntFrm();
1238 		if ( pDownFrm )
1239 		{
1240 			::lcl_CalcDownDist( nDown, aNew, pDownFrm );
1241 			if ( nDown.nMain < 0 )
1242 				nDown.nMain = LONG_MAX;
1243 			//Wenn die Distanz innnerhalb einer Tabelle waechst, so lohnt es
1244 			//sich weiter zu suchen.
1245 			if ( pDownLst->IsInTab() && pDownFrm->IsInTab() )
1246 			{
1247 				while ( pDownFrm && ( ( nDown.nMain != LONG_MAX && nDownLst < nDownLst
1248 						&& pDownFrm->IsInTab()) || bBody != pDownFrm->IsInDocBody() ) )
1249 				{
1250 					pDownFrm = pDownFrm->GetNextCntntFrm();
1251 					if ( pDownFrm )
1252 						::lcl_CalcDownDist( nDown, aNew, pDownFrm );
1253 					if ( nDown.nMain < 0 )
1254 						nDown.nMain = LONG_MAX;
1255 				}
1256 			}
1257 		}
1258 		if ( !pDownFrm )
1259 			nDown.nMain = LONG_MAX;
1260 
1261 	} while ( pDownFrm && nDown <= nDownLst &&
1262 			  nDown.nMain != LONG_MAX && nDownLst.nMain != LONG_MAX );
1263 
1264 	//Wenn ich in beide Richtungen keinen gefunden habe, so suche ich mir
1265 	//denjenigen Cntnt dessen linke obere Ecke dem Point am naechsten liegt.
1266 	//Eine derartige Situation tritt z.b. auf, wenn der Point nicht im Text-
1267 	//fluss sondern in irgendwelchen Raendern steht.
1268 	if ( nDownLst.nMain == LONG_MAX && nUpLst.nMain == LONG_MAX )
1269     {
1270         // #102861# If an OLE objects, which is contained in a fly frame
1271         // is resized in inplace mode and the new Position is outside the
1272         // fly frame, we do not want to leave our fly frame.
1273         if ( pCnt->IsInFly() )
1274             return pCnt;
1275 
1276 		return ::lcl_FindCnt( aNew, pCnt, bBody, bFtn );
1277     }
1278 	else
1279 		return nDownLst < nUpLst ? pDownLst : pUpLst;
1280 }
1281 
1282 /*************************************************************************
1283 |*
1284 |*	SwFlyAtCntFrm::SetAbsPos()
1285 |*
1286 |*	Ersterstellung		MA 22. Jun. 93
1287 |*	Letzte Aenderung	MA 11. Sep. 98
1288 |*
1289 |*************************************************************************/
1290 
1291 void SwFlyAtCntFrm::SetAbsPos( const Point &rNew )
1292 {
1293 	SwPageFrm *pOldPage = FindPageFrm();
1294     const SwRect aOld( GetObjRectWithSpaces() );
1295 	Point aNew( rNew );
1296 	//Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1297       if( ( GetAnchorFrm()->IsVertical() && !GetAnchorFrm()->IsVertLR() ) || GetAnchorFrm()->IsRightToLeft() )
1298         aNew.X() += Frm().Width();
1299     SwCntntFrm *pCnt = (SwCntntFrm*)::FindAnchor( GetAnchorFrm(), aNew );
1300 	if( pCnt->IsProtected() )
1301         pCnt = (SwCntntFrm*)GetAnchorFrm();
1302 
1303     SwPageFrm *pTmpPage = 0;
1304     const bool bVert = pCnt->IsVertical();
1305     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1306     const bool bVertL2R = pCnt->IsVertLR();
1307     const sal_Bool bRTL = pCnt->IsRightToLeft();
1308 
1309     if( ( !bVert != !GetAnchorFrm()->IsVertical() ) ||
1310         ( !bRTL !=  !GetAnchorFrm()->IsRightToLeft() ) )
1311     {
1312         if( bVert || bRTL )
1313             aNew.X() += Frm().Width();
1314         else
1315             aNew.X() -= Frm().Width();
1316     }
1317 
1318 	if ( pCnt->IsInDocBody() )
1319 	{
1320 		//#38848 Vom Seitenrand in den Body ziehen.
1321         pTmpPage = pCnt->FindPageFrm();
1322         ::lcl_PointToPrt( aNew, pTmpPage->GetUpper() );
1323 		SwRect aTmp( aNew, Size( 0, 0 ) );
1324         pTmpPage = (SwPageFrm*)::FindPage( aTmp, pTmpPage );
1325         ::lcl_PointToPrt( aNew, pTmpPage );
1326 	}
1327 
1328 	//RelPos einstellen, nur auf Wunsch invalidieren.
1329 	//rNew ist eine Absolute Position. Um die RelPos korrekt einzustellen
1330 	//muessen wir uns die Entfernung von rNew zum Anker im Textfluss besorgen.
1331 //!!!!!Hier kann Optimiert werden: FindAnchor koennte die RelPos mitliefern!
1332 	const SwFrm *pFrm = 0;
1333 	SwTwips nY;
1334 	if ( pCnt->Frm().IsInside( aNew ) )
1335     {
1336         // --> OD 2009-01-12 #i70582#
1337         const SwTwips nTopForObjPos =
1338                 bVert
1339                 ? ( bVertL2R
1340                     ? ( pCnt->Frm().Left() +
1341                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
1342                     : ( pCnt->Frm().Left() +
1343                         pCnt->Frm().Width() -
1344                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
1345                 : ( pCnt->Frm().Top() +
1346                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
1347         if( bVert )
1348         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1349         {
1350 	    	if ( bVertL2R )
1351                 nY = rNew.X() - nTopForObjPos;
1352             else
1353                 nY = nTopForObjPos - rNew.X() - Frm().Width();
1354         }
1355         else
1356         {
1357             nY = rNew.Y() - nTopForObjPos;
1358         }
1359         // <--
1360     }
1361 	else
1362 	{
1363 		SwDistance aDist;
1364 		pFrm = ::lcl_CalcDownDist( aDist, aNew, pCnt );
1365 		nY = aDist.nMain + aDist.nSub;
1366 	}
1367 
1368 	SwTwips nX = 0;
1369 
1370 	if ( pCnt->IsFollow() )
1371 	{
1372 		//Flys haengen niemals an einem Follow sondern immer am
1373 		//Master, den suchen wir uns jetzt.
1374 		const SwCntntFrm *pOriginal = pCnt;
1375 		const SwCntntFrm *pFollow = pCnt;
1376 		while ( pCnt->IsFollow() )
1377 		{
1378 			do
1379 			{	pCnt = pCnt->GetPrevCntntFrm();
1380 			} while ( pCnt->GetFollow() != pFollow );
1381 			pFollow = pCnt;
1382 		}
1383 		SwTwips nDiff = 0;
1384 		do
1385 		{	const SwFrm *pUp = pFollow->GetUpper();
1386             if( pUp->IsVertical() )
1387             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1388             {
1389     		    if ( pUp->IsVertLR()  )
1390                 	nDiff += pUp->Prt().Width() - pFollow->GetRelPos().X();
1391                 else
1392                	    nDiff += pFollow->Frm().Left() + pFollow->Frm().Width()
1393                              - pUp->Frm().Left() - pUp->Prt().Left();
1394             }
1395             else
1396                 nDiff += pUp->Prt().Height() - pFollow->GetRelPos().Y();
1397 			pFollow = pFollow->GetFollow();
1398 		} while ( pFollow != pOriginal );
1399 		nY += nDiff;
1400         if( bVert )
1401             nX = pCnt->Frm().Top() - pOriginal->Frm().Top();
1402         else
1403             nX = pCnt->Frm().Left() - pOriginal->Frm().Left();
1404 	}
1405 
1406 	if ( nY == LONG_MAX )
1407     {
1408         // --> OD 2009-01-12 #i70582#
1409         const SwTwips nTopForObjPos =
1410                 bVert
1411                 ? ( bVertL2R
1412                     ? ( pCnt->Frm().Left() +
1413                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() )
1414                     : ( pCnt->Frm().Left() +
1415                         pCnt->Frm().Width() -
1416                         pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() ) )
1417                 : ( pCnt->Frm().Top() +
1418                     pCnt->GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() );
1419         if( bVert )
1420         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1421         {
1422 			if ( bVertL2R )
1423                 nY = rNew.X() - nTopForObjPos;
1424 			else
1425                 nY = nTopForObjPos - rNew.X();
1426     	}
1427         else
1428         {
1429             nY = rNew.Y() - nTopForObjPos;
1430         }
1431         // <--
1432     }
1433 
1434     SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
1435     const SwFmtSurround& rSurround = pFmt->GetSurround();
1436     const sal_Bool bWrapThrough =
1437         rSurround.GetSurround() == SURROUND_THROUGHT;
1438     SwTwips nBaseOfstForFly = 0;
1439     const SwFrm* pTmpFrm = pFrm ? pFrm : pCnt;
1440     if ( pTmpFrm->IsTxtFrm() )
1441         nBaseOfstForFly =
1442             ((SwTxtFrm*)pTmpFrm)->GetBaseOfstForFly( !bWrapThrough );
1443 
1444     if( bVert )
1445     {
1446         if( !pFrm )
1447             nX += rNew.Y() - pCnt->Frm().Top() - nBaseOfstForFly;
1448         else
1449             nX = rNew.Y() - pFrm->Frm().Top() - nBaseOfstForFly;
1450     }
1451     else
1452     {
1453         if( !pFrm )
1454         {
1455             if ( pCnt->IsRightToLeft() )
1456                 nX += pCnt->Frm().Right() - rNew.X() - Frm().Width() +
1457                       nBaseOfstForFly;
1458             else
1459                 nX += rNew.X() - pCnt->Frm().Left() - nBaseOfstForFly;
1460         }
1461         else
1462         {
1463             if ( pFrm->IsRightToLeft() )
1464                 nX += pFrm->Frm().Right() - rNew.X() - Frm().Width() +
1465                       nBaseOfstForFly;
1466             else
1467                 nX = rNew.X() - pFrm->Frm().Left() - nBaseOfstForFly;
1468         }
1469     }
1470     GetFmt()->GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
1471 
1472     if( pCnt != GetAnchorFrm() || ( IsAutoPos() && pCnt->IsTxtFrm() &&
1473                                   GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE)) )
1474 	{
1475 		//Das Ankerattribut auf den neuen Cnt setzen.
1476 		SwFmtAnchor aAnch( pFmt->GetAnchor() );
1477 		SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
1478 		if( IsAutoPos() && pCnt->IsTxtFrm() )
1479 		{
1480 			SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
1481 			Point aPt( rNew );
1482 			if( pCnt->GetCrsrOfst( pPos, aPt, &eTmpState )
1483 				&& pPos->nNode == *pCnt->GetNode() )
1484 			{
1485                 ResetLastCharRectHeight();
1486                 if( text::RelOrientation::CHAR == pFmt->GetVertOrient().GetRelationOrient() )
1487 					nY = LONG_MAX;
1488                 if( text::RelOrientation::CHAR == pFmt->GetHoriOrient().GetRelationOrient() )
1489 					nX = LONG_MAX;
1490 			}
1491 			else
1492 			{
1493 				pPos->nNode = *pCnt->GetNode();
1494 				pPos->nContent.Assign( pCnt->GetNode(), 0 );
1495 			}
1496 		}
1497 		else
1498 		{
1499 			pPos->nNode = *pCnt->GetNode();
1500 			pPos->nContent.Assign( pCnt->GetNode(), 0 );
1501 		}
1502 
1503         // --> OD 2006-02-27 #125892#
1504         // handle change of anchor node:
1505         // if count of the anchor frame also change, the fly frames have to be
1506         // re-created. Thus, delete all fly frames except the <this> before the
1507         // anchor attribute is change and re-create them afterwards.
1508         {
1509             SwHandleAnchorNodeChg aHandleAnchorNodeChg( *pFmt, aAnch, this );
1510             pFmt->GetDoc()->SetAttr( aAnch, *pFmt );
1511         }
1512         // <--
1513 	}
1514     // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
1515     else if ( pTmpPage && pTmpPage != GetPageFrm() )
1516         GetPageFrm()->MoveFly( this, pTmpPage );
1517 
1518     const Point aRelPos = bVert ? Point( -nY, nX ) : Point( nX, nY );
1519 
1520 	ChgRelPos( aRelPos );
1521 
1522     GetFmt()->GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
1523 
1524 	if ( pOldPage != FindPageFrm() )
1525 		::Notify_Background( GetVirtDrawObj(), pOldPage, aOld, PREP_FLY_LEAVE,
1526 							 sal_False );
1527 }
1528 
1529 // OD 2004-08-12 #i32795# - Note: method no longer used in <flyincnt.cxx>
1530 //void DeepCalc( const SwFrm *pFrm )
1531 //{
1532 //    if( pFrm->IsSctFrm() ||
1533 //        ( pFrm->IsFlyFrm() && ((SwFlyFrm*)pFrm)->IsFlyInCntFrm() ) )
1534 //      return;
1535 //    const SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );
1536 //    if( pFlow && pFlow->IsAnyJoinLocked() )
1537 //        return;
1538 
1539 //    sal_uInt16 nCnt = 0;
1540 
1541 //  sal_Bool bContinue = sal_False;
1542 //  do
1543 //    {
1544 //        if ( ++nCnt == 10 )
1545 //      {
1546 //          ASSERT( !nCnt, "DeepCalc: Loop detected1?" );
1547 //          break;
1548 //      }
1549 
1550 //      const sal_Bool bSetComplete = !pFrm->IsValid();
1551 //      const SwRect aOldFrm( pFrm->Frm() );
1552 //      const SwRect aOldPrt( pFrm->Prt() );
1553 
1554 //      const SwFrm *pUp = pFrm->GetUpper();
1555 //      if ( pUp )
1556 //      {
1557 //          //Nicht weiter wenn der Up ein Fly mit Spalten ist.
1558 //          if( ( !pUp->IsFlyFrm() || !((SwLayoutFrm*)pUp)->Lower() ||
1559 //               !((SwLayoutFrm*)pUp)->Lower()->IsColumnFrm() ) &&
1560 //               !pUp->IsSctFrm() )
1561 //          {
1562 //                SWRECTFN( pUp )
1563 //                const Point aPt( (pUp->Frm().*fnRect->fnGetPos)() );
1564 //              ::DeepCalc( pUp );
1565 //                bContinue = aPt != (pUp->Frm().*fnRect->fnGetPos)();
1566 //          }
1567 //      }
1568 //      else
1569 //          pUp = pFrm;
1570 
1571 //      pFrm->Calc();
1572 //      if ( bSetComplete && (aOldFrm != pFrm->Frm() || aOldPrt != pFrm->Prt()))
1573 //          pFrm->SetCompletePaint();
1574 
1575 //      if ( pUp->IsFlyFrm() )
1576 //      {
1577 //          if ( ((SwFlyFrm*)pUp)->IsLocked() ||
1578 //               (((SwFlyFrm*)pUp)->IsFlyAtCntFrm() &&
1579 //                SwOszControl::IsInProgress( (const SwFlyFrm*)pUp )) )
1580 //          {
1581 //              bContinue = sal_False;
1582 //          }
1583 //      }
1584 //  } while ( bContinue );
1585 //}
1586 
1587 /** method to assure that anchored object is registered at the correct
1588     page frame
1589 
1590     OD 2004-07-02 #i28701#
1591     takes over functionality of deleted method <SwFlyAtCntFrm::AssertPage()>
1592 
1593     @author OD
1594 */
1595 void SwFlyAtCntFrm::RegisterAtCorrectPage()
1596 {
1597     SwPageFrm* pPageFrm( 0L );
1598     if ( GetVertPosOrientFrm() )
1599     {
1600         pPageFrm = const_cast<SwPageFrm*>(GetVertPosOrientFrm()->FindPageFrm());
1601     }
1602     if ( pPageFrm && GetPageFrm() != pPageFrm )
1603     {
1604         if ( GetPageFrm() )
1605             GetPageFrm()->MoveFly( this, pPageFrm );
1606         else
1607             pPageFrm->AppendFlyToPage( this );
1608     }
1609 }
1610 
1611 // OD 2004-03-23 #i26791#
1612 //void SwFlyAtCntFrm::MakeFlyPos()
1613 void SwFlyAtCntFrm::MakeObjPos()
1614 {
1615     // OD 02.10.2002 #102646#
1616     // if fly frame position is valid, nothing is to do. Thus, return
1617     if ( bValidPos )
1618 	{
1619         return;
1620     }
1621 
1622     // OD 2004-03-24 #i26791# - validate position flag here.
1623     bValidPos = sal_True;
1624 
1625     // --> OD 2004-10-22 #i35911# - no calculation of new position, if
1626     // anchored object is marked that it clears its environment and its
1627     // environment is already cleared.
1628     // --> OD 2006-01-02 #125977# - before checking for cleared environment
1629     // check, if member <mpVertPosOrientFrm> is set.
1630     if ( GetVertPosOrientFrm() &&
1631          ClearedEnvironment() && HasClearedEnvironment() )
1632     {
1633         return;
1634     }
1635     // <--
1636 
1637     // OD 29.10.2003 #113049# - use new class to position object
1638     objectpositioning::SwToCntntAnchoredObjectPosition
1639             aObjPositioning( *GetVirtDrawObj() );
1640     aObjPositioning.CalcPosition();
1641 
1642     SetVertPosOrientFrm ( aObjPositioning.GetVertPosOrientFrm() );
1643 }
1644 
1645 // OD 2004-05-12 #i28701#
1646 bool SwFlyAtCntFrm::_InvalidationAllowed( const InvalidationType _nInvalid ) const
1647 {
1648     bool bAllowed( SwFlyFreeFrm::_InvalidationAllowed( _nInvalid ) );
1649 
1650     // forbiddance of base instance can't be over ruled.
1651     if ( bAllowed )
1652     {
1653         if ( _nInvalid == INVALID_POS ||
1654              _nInvalid == INVALID_ALL )
1655         {
1656             bAllowed = InvalidationOfPosAllowed();
1657         }
1658     }
1659 
1660     return bAllowed;
1661 }
1662