xref: /AOO41X/main/sw/source/core/layout/anchoredobject.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 #include <anchoredobject.hxx>
31 #include <pam.hxx>
32 #include <frame.hxx>
33 #include <txtfrm.hxx>
34 #include <frmfmt.hxx>
35 #include <fmtanchr.hxx>
36 #include <fmtornt.hxx>
37 // --> OD 2004-06-29 #i28701#
38 #include <doc.hxx>
39 #include <fmtsrnd.hxx>
40 #include <svx/svdobj.hxx>
41 #include <dcontact.hxx>
42 #include <editeng/ulspitem.hxx>
43 #include <editeng/lrspitem.hxx>
44 #include <sortedobjs.hxx>
45 #include <pagefrm.hxx>
46 // <--
47 #include <frmatr.hxx>
48 // --> OD 2004-08-25 #i3317#
49 #include <colfrm.hxx>
50 // <--
51 // --> OD 2004-10-22 #i35911#
52 #include <layouter.hxx>
53 
54 
55 using namespace ::com::sun::star;
56 
57 
58 // <--
59 // ============================================================================
60 // --> OD 2004-06-30 #i28701# -
61 // implementation of helper class <SwObjPositioningInProgress>
62 // ============================================================================
63 SwObjPositioningInProgress::SwObjPositioningInProgress( SdrObject& _rSdrObj ) :
64     mpAnchoredObj( 0L ),
65     // --> OD 2005-08-09 #i52904#
66     mbOldObjPositioningInProgress( false )
67     // <--
68 {
69     mpAnchoredObj = ::GetUserCall( &_rSdrObj )->GetAnchoredObj( &_rSdrObj );
70     // --> OD 2005-08-09 #i52904#
71     mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress();
72     // <--
73     mpAnchoredObj->SetPositioningInProgress( true );
74 }
75 SwObjPositioningInProgress::SwObjPositioningInProgress( SwAnchoredObject& _rAnchoredObj ) :
76     mpAnchoredObj( &_rAnchoredObj ),
77     // --> OD 2005-08-09 #i52904#
78     mbOldObjPositioningInProgress( false )
79     // <--
80 {
81     // --> OD 2005-08-09 #i52904#
82     mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress();
83     // <--
84     mpAnchoredObj->SetPositioningInProgress( true );
85 }
86 
87 SwObjPositioningInProgress::~SwObjPositioningInProgress()
88 {
89     if ( mpAnchoredObj )
90     {
91         // --> OD 2005-08-09 #i52904#
92         mpAnchoredObj->SetPositioningInProgress( mbOldObjPositioningInProgress );
93         // <--
94     }
95 }
96 
97 // ============================================================================
98 
99 TYPEINIT0(SwAnchoredObject);
100 
101 SwAnchoredObject::SwAnchoredObject() :
102     mpDrawObj( 0L ),
103     mpAnchorFrm( 0L ),
104     // --> OD 2004-06-30 #i28701#
105     mpPageFrm( 0L ),
106     // <--
107     maRelPos(),
108     maLastCharRect(),
109     mnLastTopOfLine( 0L ),
110     mpVertPosOrientFrm( 0L ),
111     // --> OD 2004-06-29 #i28701#
112     mbPositioningInProgress( false ),
113     mbConsiderForTextWrap( false ),
114     mbPositionLocked( false ),
115     // --> OD 2005-01-10 #i40147#
116     mbKeepPositionLockedForSection( false ),
117     // <--
118     mbRestartLayoutProcess( false ),
119     // <--
120     // --> OD 2004-10-22 #i35911#
121     mbClearedEnvironment( false ),
122     // <--
123     // --> OD 2004-08-25 #i3317#
124     mbTmpConsiderWrapInfluence( false ),
125     // <--
126     // --> OD 2006-08-10 #i68520#
127     maObjRectWithSpaces(),
128     mbObjRectWithSpacesValid( false ),
129     maLastObjRect()
130     // <--
131 {
132 }
133 
134 SwAnchoredObject::~SwAnchoredObject()
135 {
136 }
137 
138 // =============================================================================
139 // accessors for member <mpDrawObj>
140 // =============================================================================
141 void SwAnchoredObject::SetDrawObj( SdrObject& _rDrawObj )
142 {
143     mpDrawObj = &_rDrawObj;
144 }
145 
146 const SdrObject* SwAnchoredObject::GetDrawObj() const
147 {
148     return mpDrawObj;
149 }
150 
151 SdrObject* SwAnchoredObject::DrawObj()
152 {
153     return mpDrawObj;
154 }
155 
156 // =============================================================================
157 // accessors for member <mpAnchorFrm>
158 // =============================================================================
159 const SwFrm* SwAnchoredObject::GetAnchorFrm() const
160 {
161     return mpAnchorFrm;
162 }
163 
164 SwFrm* SwAnchoredObject::AnchorFrm()
165 {
166     return mpAnchorFrm;
167 }
168 
169 void SwAnchoredObject::ChgAnchorFrm( SwFrm* _pNewAnchorFrm )
170 {
171     mpAnchorFrm = _pNewAnchorFrm;
172 
173     if ( mpAnchorFrm )
174     {
175         ObjectAttachedToAnchorFrame();
176     }
177 }
178 
179 /** determine anchor frame containing the anchor position
180 
181     OD 2004-10-08 #i26945#
182     the anchor frame, which is determined, is <mpAnchorFrm>
183     for an at-page, at-frame or at-paragraph anchored object
184     and the anchor character frame for an at-character and as-character
185     anchored object.
186 
187     @author OD
188 */
189 SwFrm* SwAnchoredObject::GetAnchorFrmContainingAnchPos()
190 {
191     SwFrm* pAnchorFrmContainingAnchPos = FindAnchorCharFrm();
192     if ( !pAnchorFrmContainingAnchPos )
193     {
194         pAnchorFrmContainingAnchPos = AnchorFrm();
195     }
196 
197     return pAnchorFrmContainingAnchPos;
198 }
199 
200 // =============================================================================
201 // OD 2004-06-30 #i28701# accessors for member <mpPageFrm>
202 // =============================================================================
203 SwPageFrm* SwAnchoredObject::GetPageFrm()
204 {
205     return mpPageFrm;
206 }
207 
208 const SwPageFrm* SwAnchoredObject::GetPageFrm() const
209 {
210     return mpPageFrm;
211 }
212 
213 void SwAnchoredObject::SetPageFrm( SwPageFrm* _pNewPageFrm )
214 {
215     // --> OD 2006-01-02 #125977#
216     if ( mpPageFrm != _pNewPageFrm )
217     {
218         // clear member, which denotes the layout frame at which the vertical
219         // position is oriented at, if it doesn't fit to the new page frame.
220         if ( GetVertPosOrientFrm() &&
221              ( !_pNewPageFrm ||
222                _pNewPageFrm != GetVertPosOrientFrm()->FindPageFrm() ) )
223         {
224             ClearVertPosOrientFrm();
225         }
226 
227         // assign new page frame
228         mpPageFrm = _pNewPageFrm;
229     }
230     // <--
231 }
232 
233 // =============================================================================
234 // accessors for member <maLastCharRect>
235 // =============================================================================
236 const SwRect& SwAnchoredObject::GetLastCharRect() const
237 {
238     return maLastCharRect;
239 }
240 
241 SwTwips SwAnchoredObject::GetRelCharX( const SwFrm* pFrm ) const
242 {
243     return maLastCharRect.Left() - pFrm->Frm().Left();
244 }
245 
246 SwTwips SwAnchoredObject::GetRelCharY( const SwFrm* pFrm ) const
247 {
248     return maLastCharRect.Bottom() - pFrm->Frm().Top();
249 }
250 
251 void SwAnchoredObject::AddLastCharY( long nDiff )
252 {
253     maLastCharRect.Pos().Y() += nDiff;
254 }
255 
256 void SwAnchoredObject::ResetLastCharRectHeight()
257 {
258     maLastCharRect.Height( 0 );
259 }
260 // =============================================================================
261 // accessors for member <mpVertPosOrientFrm>
262 // =============================================================================
263 void SwAnchoredObject::SetVertPosOrientFrm( const SwLayoutFrm& _rVertPosOrientFrm )
264 {
265     mpVertPosOrientFrm = &_rVertPosOrientFrm;
266 
267     // --> OD 2004-07-02 #i28701# - take over functionality of deleted method
268     // <SwFlyAtCntFrm::AssertPage()>: assure for at-paragraph and at-character
269     // an anchored object, that it is registered at the correct page frame
270     RegisterAtCorrectPage();
271 }
272 
273 // =============================================================================
274 // accessors for member <mnLastTopOfLine>
275 // =============================================================================
276 SwTwips SwAnchoredObject::GetLastTopOfLine() const
277 {
278     return mnLastTopOfLine;
279 }
280 
281 // OD 2004-05-18 #i28701# - follow-up of #i22341#
282 void SwAnchoredObject::AddLastTopOfLineY( SwTwips _nDiff )
283 {
284     mnLastTopOfLine += _nDiff;
285 }
286 
287 /** check anchor character rectangle and top of line
288 
289     OD 2004-03-24 #i26791
290     For to-character anchored Writer fly frames the members <maLastCharRect>
291     and <maLastTopOfLine> are updated. These are checked for change and
292     depending on the applied positioning, it's decided, if the Writer fly
293     frame has to be invalidated.
294     OD 2004-07-15 #117380#
295     add parameter <_bCheckForParaPorInf>, default value <true>
296 
297     @author OD
298 */
299 void SwAnchoredObject::CheckCharRectAndTopOfLine(
300                                         const bool _bCheckForParaPorInf )
301 {
302     if ( GetAnchorFrm() &&
303          GetAnchorFrm()->IsTxtFrm() )
304     {
305         const SwFmtAnchor& rAnch = GetFrmFmt().GetAnchor();
306         if ( (rAnch.GetAnchorId() == FLY_AT_CHAR) &&
307              rAnch.GetCntntAnchor() )
308         {
309             // --> OD 2004-07-14 #117380# - if requested, assure that anchor frame,
310             // which contains the anchor character, has a paragraph portion information.
311             // The paragraph portion information is needed to determine the
312             // anchor character rectangle respectively the top of the line.
313             // Thus, a format of this frame is avoided to determine the
314             // paragraph portion information.
315             // --> OD 2004-10-04 #i26945# - use new method <FindAnchorCharFrm()>
316             const SwTxtFrm& aAnchorCharFrm = *(FindAnchorCharFrm());
317             // <--
318             if ( !_bCheckForParaPorInf || aAnchorCharFrm.HasPara() )
319             {
320                 _CheckCharRect( rAnch, aAnchorCharFrm );
321                 _CheckTopOfLine( rAnch, aAnchorCharFrm );
322             }
323             // <--
324         }
325     }
326 }
327 
328 /** check anchor character rectangle
329 
330     OD 11.11.2003 #i22341#
331     helper method for method <CheckCharRectAndTopOfLine()>
332     For to-character anchored Writer fly frames the member <maLastCharRect>
333     is updated. This is checked for change and depending on the applied
334     positioning, it's decided, if the Writer fly frame has to be invalidated.
335     OD 2004-07-14 #117380#
336     improvement - add second parameter <_rAnchorCharFrm>
337 
338     @author OD
339 */
340 void SwAnchoredObject::_CheckCharRect( const SwFmtAnchor& _rAnch,
341                                        const SwTxtFrm& _rAnchorCharFrm )
342 {
343     // determine rectangle of anchor character. If not exist, abort operation
344     SwRect aCharRect;
345     if ( !_rAnchorCharFrm.GetAutoPos( aCharRect, *_rAnch.GetCntntAnchor() ) )
346     {
347         return;
348     }
349     // check, if anchor character rectangle has changed
350     if ( aCharRect != maLastCharRect )
351     {
352         // check positioning and alignment for invalidation of position
353         {
354             SWRECTFN( (&_rAnchorCharFrm) );
355             // determine positioning and alignment
356             SwFmtVertOrient aVert( GetFrmFmt().GetVertOrient() );
357             SwFmtHoriOrient aHori( GetFrmFmt().GetHoriOrient() );
358             // check for anchor character rectangle changes for certain
359             // positionings and alignments
360             // OD 07.10.2003 #110978# - add condition to invalidate position,
361             // if vertical aligned at frame/page area and vertical position
362             // of anchor character has changed.
363             const sal_Int16 eVertRelOrient = aVert.GetRelationOrient();
364             if ( ( aHori.GetRelationOrient() == text::RelOrientation::CHAR &&
365                    (aCharRect.*fnRect->fnGetLeft)() !=
366                         (maLastCharRect.*fnRect->fnGetLeft)() ) ||
367                  ( eVertRelOrient == text::RelOrientation::CHAR &&
368                    ( (aCharRect.*fnRect->fnGetTop)() !=
369                         (maLastCharRect.*fnRect->fnGetTop)() ||
370                      (aCharRect.*fnRect->fnGetHeight)() !=
371                         (maLastCharRect.*fnRect->fnGetHeight)() ) ) ||
372                  ( ( ( eVertRelOrient == text::RelOrientation::FRAME ) ||
373                      ( eVertRelOrient == text::RelOrientation::PRINT_AREA ) ||
374                      ( eVertRelOrient == text::RelOrientation::PAGE_FRAME ) ||
375                      ( eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA ) ) &&
376                    ( (aCharRect.*fnRect->fnGetTop)() !=
377                         (maLastCharRect.*fnRect->fnGetTop)() ) ) )
378             {
379                 // --> OD 2004-10-08 #i26945#, #i35911# - unlock position of
380                 // anchored object, if it isn't registered at the page,
381                 // where its anchor character frame is on.
382                 if ( GetPageFrm() != _rAnchorCharFrm.FindPageFrm() )
383                 {
384                     UnlockPosition();
385                 }
386                 // <--
387                 InvalidateObjPos();
388             }
389         }
390         // keep new anchor character rectangle
391         maLastCharRect = aCharRect;
392     }
393 }
394 
395 /** check top of line
396 
397     OD 11.11.2003 #i22341#
398     helper method for method <CheckCharRectAndTopOfLine()>
399     For to-character anchored Writer fly frames the member <mnLastTopOfLine>
400     is updated. This is checked for change and depending on the applied
401     positioning, it's decided, if the Writer fly frame has to be invalidated.
402     OD 2004-07-14 #117380#
403     improvement - add second parameter <_rAnchorCharFrm>
404 
405     @author OD
406 */
407 void SwAnchoredObject::_CheckTopOfLine( const SwFmtAnchor& _rAnch,
408                                         const SwTxtFrm& _rAnchorCharFrm )
409 {
410     SwTwips nTopOfLine = 0L;
411     if ( _rAnchorCharFrm.GetTopOfLine( nTopOfLine, *_rAnch.GetCntntAnchor() ) )
412     {
413         if ( nTopOfLine != mnLastTopOfLine )
414         {
415             // check alignment for invalidation of position
416             if ( GetFrmFmt().GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE )
417             {
418                 // --> OD 2004-10-08 #i26945#, #i35911# - unlock position of
419                 // anchored object, if it isn't registered at the page,
420                 // where its anchor character frame is on.
421                 if ( GetPageFrm() != _rAnchorCharFrm.FindPageFrm() )
422                 {
423                     UnlockPosition();
424                 }
425                 // <--
426                 InvalidateObjPos();
427             }
428             // keep new top of line value
429             mnLastTopOfLine = nTopOfLine;
430         }
431     }
432 }
433 
434 void SwAnchoredObject::ClearCharRectAndTopOfLine()
435 {
436     maLastCharRect.Clear();
437     mnLastTopOfLine = 0;
438 }
439 
440 const Point SwAnchoredObject::GetCurrRelPos() const
441 {
442     return maRelPos;
443 }
444 void SwAnchoredObject::SetCurrRelPos( Point _aRelPos )
445 {
446     maRelPos = _aRelPos;
447 }
448 
449 void SwAnchoredObject::ObjectAttachedToAnchorFrame()
450 {
451     // default behaviour:
452     // update layout direction, the anchored object is assigned to
453     UpdateLayoutDir();
454 }
455 
456 /** method update layout direction the layout direction, the anchored
457     object is in
458 
459     OD 2004-07-27 #i31698#
460     method has typically to be called, if the anchored object gets its
461     anchor frame assigned.
462 
463     @author OD
464 */
465 void SwAnchoredObject::UpdateLayoutDir()
466 {
467     SwFrmFmt::tLayoutDir nLayoutDir = SwFrmFmt::HORI_L2R;
468     const SwFrm* pAnchorFrm = GetAnchorFrm();
469     if ( pAnchorFrm )
470     {
471         const bool bVert = pAnchorFrm->IsVertical();
472         const bool bR2L = pAnchorFrm->IsRightToLeft();
473         if ( bVert )
474         {
475             nLayoutDir = SwFrmFmt::VERT_R2L;
476         }
477         else if ( bR2L )
478         {
479             nLayoutDir = SwFrmFmt::HORI_R2L;
480         }
481     }
482     GetFrmFmt().SetLayoutDir( nLayoutDir );
483 }
484 
485 /** method to perform necessary invalidations for the positioning of
486     objects, for whose the wrapping style influence has to be considered
487     on the object positioning.
488 
489     OD 2004-06-30 #i28701#
490 
491     @author OD
492 */
493 void SwAnchoredObject::InvalidateObjPosForConsiderWrapInfluence(
494                                                     const bool _bNotifyBackgrd )
495 {
496     if ( ConsiderObjWrapInfluenceOnObjPos() )
497     {
498         // indicate that object has not to be considered for text wrap
499         SetConsiderForTextWrap( false );
500         // unlock position
501         UnlockPosition();
502         // invalidate position
503         InvalidateObjPos();
504         // invalidate 'background', if requested
505         if ( _bNotifyBackgrd )
506         {
507             NotifyBackground( GetPageFrm(), GetObjRectWithSpaces(), PREP_FLY_LEAVE );
508         }
509     }
510 }
511 
512 /** method to determine, if wrapping style influence of the anchored
513     object has to be considered on the object positioning
514 
515     OD 2004-06-30 #i28701#
516     Note: result of this method also decides, if the booleans for the
517     layout process are of relevance.
518 
519     @author OD
520 */
521 bool SwAnchoredObject::ConsiderObjWrapInfluenceOnObjPos() const
522 {
523     bool bRet( false );
524 
525     const SwFrmFmt& rObjFmt = GetFrmFmt();
526 
527     // --> OD 2004-08-25 #i3317# - add condition <IsTmpConsiderWrapInfluence()>
528     // --> OD 2005-09-29 #i55204#
529     // - correction: wrapping style influence has been considered, if condition
530     //   <IsTmpConsiderWrapInfluence()> is hold, regardless of its anchor type
531     //   or its wrapping style.
532     if ( IsTmpConsiderWrapInfluence() )
533     {
534         bRet = true;
535     }
536     else if ( rObjFmt.getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
537     // <--
538     {
539         const SwFmtAnchor& rAnchor = rObjFmt.GetAnchor();
540         if ( ((rAnchor.GetAnchorId() == FLY_AT_CHAR) ||
541               (rAnchor.GetAnchorId() == FLY_AT_PARA)) &&
542              rObjFmt.GetSurround().GetSurround() != SURROUND_THROUGHT )
543         {
544             // --> OD 2004-09-23 #i34520# - text also wraps around anchored
545             // objects in the layer Hell - see the text formatting.
546             // Thus, it hasn't to be checked here.
547             bRet = true;
548             // <--
549         }
550     }
551 
552     return bRet;
553 }
554 
555 /** method to determine, if other anchored objects, also attached at
556     to the anchor frame, have to consider its wrap influence.
557 
558     // --> OD 2005-02-22 #i43255#
559 
560     @author OD
561 */
562 bool SwAnchoredObject::ConsiderObjWrapInfluenceOfOtherObjs() const
563 {
564     bool bRet( false );
565 
566     const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs();
567     if ( pObjs->Count() > 1 )
568     {
569         sal_uInt32 i = 0;
570         for ( ; i < pObjs->Count(); ++i )
571         {
572             SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
573             if ( pAnchoredObj != this &&
574                  pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
575             {
576                 bRet = true;
577                 break;
578             }
579         }
580     }
581 
582     return bRet;
583 }
584 
585 // =============================================================================
586 // --> OD 2004-06-29 #i28701# - accessors to booleans for layout process
587 // =============================================================================
588 bool SwAnchoredObject::ConsiderForTextWrap() const
589 {
590     if ( ConsiderObjWrapInfluenceOnObjPos() )
591         return mbConsiderForTextWrap;
592     else
593         return true;
594 }
595 
596 void SwAnchoredObject::SetConsiderForTextWrap( const bool _bConsiderForTextWrap )
597 {
598     mbConsiderForTextWrap = _bConsiderForTextWrap;
599 }
600 
601 bool SwAnchoredObject::PositionLocked() const
602 {
603     if ( ConsiderObjWrapInfluenceOnObjPos() )
604         return mbPositionLocked;
605     else
606         return false;
607 }
608 
609 bool SwAnchoredObject::RestartLayoutProcess() const
610 {
611     if ( ConsiderObjWrapInfluenceOnObjPos() )
612         return mbRestartLayoutProcess;
613     else
614         return false;
615 }
616 
617 void SwAnchoredObject::SetRestartLayoutProcess( const bool _bRestartLayoutProcess )
618 {
619     mbRestartLayoutProcess = _bRestartLayoutProcess;
620 }
621 
622 // --> OD 2004-10-22 #i35911#
623 bool SwAnchoredObject::ClearedEnvironment() const
624 {
625     if ( ConsiderObjWrapInfluenceOnObjPos() )
626         return mbClearedEnvironment;
627     else
628         return false;
629 }
630 void SwAnchoredObject::SetClearedEnvironment( const bool _bClearedEnvironment )
631 {
632     mbClearedEnvironment = _bClearedEnvironment;
633 }
634 // <--
635 
636 /** method to determine, if due to anchored object size and wrapping
637     style, its layout environment is cleared.
638 
639     OD 2004-10-22 #i35911#
640 
641     @author OD
642 */
643 bool SwAnchoredObject::HasClearedEnvironment() const
644 {
645     bool bHasClearedEnvironment( false );
646 
647     // --> OD 2005-03-03 #i43913# - layout frame, vertical position is orient at, has to be set.
648     ASSERT( GetVertPosOrientFrm(),
649             "<SwAnchoredObject::HasClearedEnvironment()> - layout frame missing, at which the vertical position is oriented at." );
650     if ( GetVertPosOrientFrm() &&
651          GetAnchorFrm()->IsTxtFrm() &&
652          !static_cast<const SwTxtFrm*>(GetAnchorFrm())->IsFollow() &&
653          static_cast<const SwTxtFrm*>(GetAnchorFrm())->FindPageFrm()->GetPhyPageNum() >=
654                 GetPageFrm()->GetPhyPageNum() )
655     // <--
656     {
657         const SwFrm* pTmpFrm = GetVertPosOrientFrm()->Lower();
658         while ( pTmpFrm && pTmpFrm->IsLayoutFrm() && !pTmpFrm->IsTabFrm() )
659         {
660             pTmpFrm = static_cast<const SwLayoutFrm*>(pTmpFrm)->Lower();
661         }
662         if ( !pTmpFrm )
663         {
664             bHasClearedEnvironment = true;
665         }
666         else if ( pTmpFrm->IsTxtFrm() && !pTmpFrm->GetNext() )
667         {
668             const SwTxtFrm* pTmpTxtFrm = static_cast<const SwTxtFrm*>(pTmpFrm);
669             if ( pTmpTxtFrm->IsUndersized() ||
670                  ( pTmpTxtFrm->GetFollow() &&
671                    pTmpTxtFrm->GetFollow()->GetOfst() == 0 ) )
672             {
673                 bHasClearedEnvironment = true;
674             }
675         }
676     }
677 
678     return bHasClearedEnvironment;
679 }
680 
681 /** method to add spacing to object area
682 
683     OD 2004-06-30 #i28701#
684     OD 2006-08-10 #i68520# - return constant reference and use cache
685 
686     @author OD
687 */
688 const SwRect& SwAnchoredObject::GetObjRectWithSpaces() const
689 {
690     if ( mbObjRectWithSpacesValid &&
691          maLastObjRect != GetObjRect() )
692     {
693         ASSERT( false,
694                 "<SwAnchoredObject::GetObjRectWithSpaces> - cache for object rectangle inclusive spaces marked as valid, but it couldn't be. Missing invalidation of cache. Please inform OD." );
695         InvalidateObjRectWithSpaces();
696     }
697     if ( !mbObjRectWithSpacesValid )
698     {
699         // --> OD 2006-10-05 #i70122# - correction:
700         // use bounding rectangle of anchored objects.
701 //        maObjRectWithSpaces = GetObjRect();
702         maObjRectWithSpaces = GetObjBoundRect();
703         // <--
704         const SwFrmFmt& rFmt = GetFrmFmt();
705         const SvxULSpaceItem& rUL = rFmt.GetULSpace();
706         const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
707         {
708             maObjRectWithSpaces.Top ( Max( maObjRectWithSpaces.Top() - long(rUL.GetUpper()), 0L ));
709             maObjRectWithSpaces.Left( Max( maObjRectWithSpaces.Left()- long(rLR.GetLeft()),  0L ));
710             maObjRectWithSpaces.SSize().Height() += rUL.GetLower();
711             maObjRectWithSpaces.SSize().Width()  += rLR.GetRight();
712         }
713 
714         mbObjRectWithSpacesValid = true;
715         maLastObjRect = GetObjRect();
716     }
717 
718     return maObjRectWithSpaces;
719 }
720 
721 // --> OD 2006-08-10 #i68520#
722 void SwAnchoredObject::SetObjTop( const SwTwips _nTop)
723 {
724     const bool bTopChanged( _SetObjTop( _nTop ) );
725     if ( bTopChanged )
726     {
727         mbObjRectWithSpacesValid = false;
728     }
729 }
730 
731 void SwAnchoredObject::SetObjLeft( const SwTwips _nLeft)
732 {
733     const bool bLeftChanged( _SetObjLeft( _nLeft ) );
734     if ( bLeftChanged )
735     {
736         mbObjRectWithSpacesValid = false;
737     }
738 }
739 // <--
740 
741 /** method to update anchored object in the <SwSortedObjs> lists
742 
743     OD 2004-07-01 #i28701#
744     If document compatibility option 'Consider wrapping style influence
745     on object positioning' is ON, additionally all anchored objects
746     at the anchor frame and all following anchored objects on the page
747     frame are invalidated.
748 
749     @author OD
750 */
751 void SwAnchoredObject::UpdateObjInSortedList()
752 {
753     if ( GetAnchorFrm() )
754     {
755         if ( GetFrmFmt().getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
756         {
757             // invalidate position of all anchored objects at anchor frame
758             if ( GetAnchorFrm()->GetDrawObjs() )
759             {
760                 const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs();
761                 // determine start index
762                 sal_uInt32 i = 0;
763                 for ( ; i < pObjs->Count(); ++i )
764                 {
765                     SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
766                     if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
767                         pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
768                     else
769                         pAnchoredObj->InvalidateObjPos();
770                 }
771             }
772             // invalidate all following anchored objects on the page frame
773             if ( GetPageFrm() && GetPageFrm()->GetSortedObjs() )
774             {
775                 const SwSortedObjs* pObjs = GetPageFrm()->GetSortedObjs();
776                 // determine start index
777                 sal_uInt32 i = pObjs->ListPosOf( *this ) + 1;
778                 for ( ; i < pObjs->Count(); ++i )
779                 {
780                     SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
781                     if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
782                         pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
783                     else
784                         pAnchoredObj->InvalidateObjPos();
785                 }
786             }
787         }
788         // update its position in the sorted object list of its anchor frame
789         AnchorFrm()->GetDrawObjs()->Update( *this );
790         // update its position in the sorted object list of its page frame
791         // note: as-character anchored object aren't registered at a page frame
792         if ( GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR )
793         {
794             GetPageFrm()->GetSortedObjs()->Update( *this );
795         }
796     }
797 }
798 
799 /** method to determine, if invalidation of position is allowed
800 
801     OD 2004-07-01 #i28701#
802 
803     @author OD
804 */
805 bool SwAnchoredObject::InvalidationOfPosAllowed() const
806 {
807     // --> OD 2004-11-03 #114798# - Check, if page frame layout is in progress,
808     // isn't needed, because of anchored object, whose are moved forward.
809     return !PositionLocked();
810     // <--
811 }
812 
813 /** method to determine the page frame, on which the 'anchor' of
814     the given anchored object is.
815 
816     OD 2004-07-02 #i28701#
817     OD 2004-09-23 #i33751#, #i34060#
818     Adjust meaning of method and thus its name: If the anchored object
819     or its anchor isn't correctly inserted in the layout, no page frame
820     can be found. Thus, the return type changed to be a pointer and can
821     be NULL.
822 
823     @author OD
824 */
825 SwPageFrm* SwAnchoredObject::FindPageFrmOfAnchor()
826 {
827     SwPageFrm* pRetPageFrm = 0L;
828 
829     // --> OD 2005-03-08 #i44339# - check, if anchor frame exists.
830     if ( mpAnchorFrm )
831     {
832         // --> OD 2004-10-08 #i26945# - use new method <GetAnchorFrmContainingAnchPos()>
833         pRetPageFrm = GetAnchorFrmContainingAnchPos()->FindPageFrm();
834         // <--
835     }
836 
837     return pRetPageFrm;
838 }
839 
840 /** get frame, which contains the anchor character, if the object
841     is anchored at-character or as-character.
842 
843     OD 2004-10-04 #i26945#
844 
845     @author OD
846 
847     @return SwTxtFrm*
848     text frame containing the anchor character. It's NULL, if the object
849     isn't anchored at-character resp. as-character.
850 */
851 SwTxtFrm* SwAnchoredObject::FindAnchorCharFrm()
852 {
853     SwTxtFrm* pAnchorCharFrm( 0L );
854 
855     // --> OD 2005-03-08 #i44339# - check, if anchor frame exists.
856     if ( mpAnchorFrm )
857     {
858         const SwFmtAnchor& rAnch = GetFrmFmt().GetAnchor();
859         if ((rAnch.GetAnchorId() == FLY_AT_CHAR) ||
860             (rAnch.GetAnchorId() == FLY_AS_CHAR))
861         {
862             pAnchorCharFrm = &(static_cast<SwTxtFrm*>(AnchorFrm())->
863                         GetFrmAtOfst( rAnch.GetCntntAnchor()->nContent.GetIndex() ));
864         }
865     }
866     // <--
867 
868     return pAnchorCharFrm;
869 }
870 
871 /** method to determine, if a format on the anchored object is possible
872 
873     OD 2004-07-23 #i28701#
874     A format is possible, if anchored object is in an invisible layer.
875     Note: method is virtual to refine the conditions for the sub-classes.
876 
877     @author OD
878 */
879 bool SwAnchoredObject::IsFormatPossible() const
880 {
881     return GetFrmFmt().GetDoc()->IsVisibleLayerId( GetDrawObj()->GetLayer() );
882 }
883 
884 // --> OD 2004-08-25 #i3317#
885 void SwAnchoredObject::SetTmpConsiderWrapInfluence( const bool _bTmpConsiderWrapInfluence )
886 {
887     mbTmpConsiderWrapInfluence = _bTmpConsiderWrapInfluence;
888     // --> OD 2004-10-22 #i35911#
889     if ( mbTmpConsiderWrapInfluence )
890     {
891         SwLayouter::InsertObjForTmpConsiderWrapInfluence( *(GetFrmFmt().GetDoc()),
892                                                           *this );
893     }
894     // <--
895 }
896 
897 bool SwAnchoredObject::IsTmpConsiderWrapInfluence() const
898 {
899     return mbTmpConsiderWrapInfluence;
900 }
901 // <--
902 
903 // --> OD 2006-07-24 #b6449874#
904 void SwAnchoredObject::SetTmpConsiderWrapInfluenceOfOtherObjs( const bool bTmpConsiderWrapInfluence )
905 {
906     const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs();
907     if ( pObjs->Count() > 1 )
908     {
909         sal_uInt32 i = 0;
910         for ( ; i < pObjs->Count(); ++i )
911         {
912             SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
913             if ( pAnchoredObj != this )
914             {
915                 pAnchoredObj->SetTmpConsiderWrapInfluence( bTmpConsiderWrapInfluence );
916             }
917         }
918     }
919 }
920 // <--
921 
922 /** method to determine, if the anchored object is overlapping with a
923     previous column
924 
925     OD 2004-08-25 #i3317#
926     overlapping with a previous column means, that the object overlaps
927     with a column, which is a previous one of the column its anchor
928     frame is in.
929     Only applied for at-paragraph and at-character anchored objects.
930 
931     @author OD
932 */
933 bool SwAnchoredObject::OverlapsPrevColumn() const
934 {
935     bool bOverlapsPrevColumn( false );
936 
937     if ( mpAnchorFrm && mpAnchorFrm->IsTxtFrm() )
938     {
939         const SwFrm* pColFrm = mpAnchorFrm->FindColFrm();
940         if ( pColFrm && pColFrm->GetPrev() )
941         {
942             const SwFrm* pTmpColFrm = pColFrm->GetPrev();
943             SwRect aChkRect;
944             while ( pTmpColFrm )
945             {
946                 aChkRect.Union( pTmpColFrm->Frm() );
947                 pTmpColFrm = pTmpColFrm->GetPrev();
948             }
949             bOverlapsPrevColumn = GetObjRect().IsOver( aChkRect );
950         }
951     }
952 
953     return bOverlapsPrevColumn;
954 }
955 
956 /** method to determine position of anchored object relative to
957     anchor frame
958 
959     OD 2005-01-06 #i30669#
960     Usage: Needed layout information for WW8 export
961 
962     @author OD
963 */
964 Point SwAnchoredObject::GetRelPosToAnchorFrm() const
965 {
966     Point aRelPos;
967 
968     ASSERT( GetAnchorFrm(),
969             "<SwAnchoredObject::GetRelPosToAnchorFrm()> - missing anchor frame." );
970     aRelPos = GetObjRect().Pos();
971     aRelPos -= GetAnchorFrm()->Frm().Pos();
972 
973     return aRelPos;
974 }
975 
976 /** method to determine position of anchored object relative to
977     page frame
978 
979     OD 2005-01-06 #i30669#
980     Usage: Needed layout information for WW8 export
981     OD 2005-01-27 #i33818# - add parameters <_bFollowTextFlow> and
982     <_obRelToTableCell>
983     If <_bFollowTextFlow> is set and object is anchored inside table,
984     the position relative to the table cell is determined. Output
985     parameter <_obRelToTableCell> reflects this situation
986 
987     @author OD
988 */
989 Point SwAnchoredObject::GetRelPosToPageFrm( const bool _bFollowTextFlow,
990                                             bool& _obRelToTableCell ) const
991 {
992     Point aRelPos;
993     _obRelToTableCell = false;
994 
995     ASSERT( GetAnchorFrm(),
996             "<SwAnchoredObject::GetRelPosToPageFrm()> - missing anchor frame." );
997     ASSERT( GetAnchorFrm()->FindPageFrm(),
998             "<SwAnchoredObject::GetRelPosToPageFrm()> - missing page frame." );
999 
1000     aRelPos = GetObjRect().Pos();
1001     // --> OD 2005-01-27 #i33818# - search for cell frame, if object has to
1002     // follow the text flow.
1003     const SwFrm* pFrm( 0L );
1004     if ( _bFollowTextFlow && !GetAnchorFrm()->IsPageFrm() )
1005     {
1006         pFrm = GetAnchorFrm()->GetUpper();
1007         while ( !pFrm->IsCellFrm() && !pFrm->IsPageFrm() )
1008         {
1009             pFrm = pFrm->GetUpper();
1010         }
1011     }
1012     else
1013     {
1014         pFrm = GetAnchorFrm()->FindPageFrm();
1015     }
1016     if ( pFrm->IsCellFrm() )
1017     {
1018         aRelPos -= ( pFrm->Frm().Pos() + pFrm->Prt().Pos() );
1019         _obRelToTableCell = true;
1020     }
1021     else
1022     {
1023         aRelPos -= pFrm->Frm().Pos();
1024     }
1025     // <--
1026 
1027     return aRelPos;
1028 }
1029 
1030 /** method to determine position of anchored object relative to
1031     anchor character
1032 
1033     OD 2005-01-06 #i30669#
1034     Usage: Needed layout information for WW8 export
1035 
1036     @author OD
1037 */
1038 Point SwAnchoredObject::GetRelPosToChar() const
1039 {
1040     Point aRelPos;
1041 
1042     aRelPos = GetObjRect().Pos();
1043     aRelPos -= GetLastCharRect().Pos();
1044 
1045     return aRelPos;
1046 }
1047 
1048 /** method to determine position of anchored object relative to
1049     top of line
1050 
1051     OD 2005-01-06 #i30669#
1052     Usage: Needed layout information for WW8 export
1053 
1054     @author OD
1055 */
1056 Point SwAnchoredObject::GetRelPosToLine() const
1057 {
1058     Point aRelPos;
1059 
1060     aRelPos = GetObjRect().Pos();
1061     aRelPos.Y() -= GetLastTopOfLine();
1062 
1063     return aRelPos;
1064 }
1065