LCOV - code coverage report
Current view: top level - sw/source/core/layout - flylay.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 369 570 64.7 %
Date: 2015-06-13 12:38:46 Functions: 24 30 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "pagefrm.hxx"
      21             : #include "rootfrm.hxx"
      22             : #include "cntfrm.hxx"
      23             : #include "dflyobj.hxx"
      24             : #include "dcontact.hxx"
      25             : #include "ftnfrm.hxx"
      26             : #include "frmtool.hxx"
      27             : #include "hints.hxx"
      28             : #include "sectfrm.hxx"
      29             : 
      30             : #include <svx/svdpage.hxx>
      31             : #include <editeng/ulspitem.hxx>
      32             : #include <fmtornt.hxx>
      33             : #include <fmtfsize.hxx>
      34             : #include "ndole.hxx"
      35             : #include "tabfrm.hxx"
      36             : #include "flyfrms.hxx"
      37             : #include <fmtfollowtextflow.hxx>
      38             : #include <environmentofanchoredobject.hxx>
      39             : #include <sortedobjs.hxx>
      40             : #include <viewimp.hxx>
      41             : #include <IDocumentSettingAccess.hxx>
      42             : #include <IDocumentDrawModelAccess.hxx>
      43             : 
      44             : using namespace ::com::sun::star;
      45             : 
      46        1333 : SwFlyFreeFrm::SwFlyFreeFrm( SwFlyFrameFormat *pFormat, SwFrm* pSib, SwFrm *pAnch ) :
      47             :     SwFlyFrm( pFormat, pSib, pAnch ),
      48             :     pPage( 0 ),
      49             :     // #i34753#
      50             :     mbNoMakePos( false ),
      51             :     // #i37068#
      52             :     mbNoMoveOnCheckClip( false ),
      53        1333 :     maUnclippedFrm( )
      54             : {
      55        1333 : }
      56             : 
      57        1333 : void SwFlyFreeFrm::DestroyImpl()
      58             : {
      59             :     // #i28701# - use new method <GetPageFrm()>
      60        1333 :     if( GetPageFrm() )
      61             :     {
      62         116 :         if( GetFormat()->GetDoc()->IsInDtor() )
      63             :         {
      64             :             // #i29879# - remove also to-frame anchored Writer
      65             :             // fly frame from page.
      66             :             const bool bRemoveFromPage =
      67           0 :                     GetPageFrm()->GetSortedObjs() &&
      68           0 :                     ( IsFlyAtCntFrm() ||
      69           0 :                       ( GetAnchorFrm() && GetAnchorFrm()->IsFlyFrm() ) );
      70           0 :             if ( bRemoveFromPage )
      71             :             {
      72           0 :                 GetPageFrm()->GetSortedObjs()->Remove( *this );
      73             :             }
      74             :         }
      75             :         else
      76             :         {
      77         116 :             SwRect aTmp( GetObjRectWithSpaces() );
      78         116 :             SwFlyFreeFrm::NotifyBackground( GetPageFrm(), aTmp, PREP_FLY_LEAVE );
      79             :         }
      80             :     }
      81             : 
      82        1333 :     SwFlyFrm::DestroyImpl();
      83        1333 : }
      84             : 
      85        1333 : SwFlyFreeFrm::~SwFlyFreeFrm()
      86             : {
      87        1333 : }
      88             : 
      89             : // #i28701#
      90      556277 : TYPEINIT1(SwFlyFreeFrm,SwFlyFrm);
      91             : /** Notifies the background (all ContentFrms that currently are overlapping).
      92             :  *
      93             :  * Additionally, the window is also directly invalidated (especially where
      94             :  * there are no overlapping ContentFrms).
      95             :  * This also takes ContentFrms within other Flys into account.
      96             :  */
      97        3387 : void SwFlyFreeFrm::NotifyBackground( SwPageFrm *pPageFrm,
      98             :                                      const SwRect& rRect, PrepareHint eHint )
      99             : {
     100        3387 :     ::Notify_Background( GetVirtDrawObj(), pPageFrm, rRect, eHint, true );
     101        3387 : }
     102             : 
     103        3596 : void SwFlyFreeFrm::MakeAll()
     104             : {
     105        3596 :     if ( !GetFormat()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
     106             :     {
     107           0 :         return;
     108             :     }
     109             : 
     110        3596 :     if ( !GetAnchorFrm() || IsLocked() || IsColLocked() )
     111           0 :         return;
     112             :     // #i28701# - use new method <GetPageFrm()>
     113        3596 :     if( !GetPageFrm() && GetAnchorFrm() && GetAnchorFrm()->IsInFly() )
     114             :     {
     115           0 :         SwFlyFrm* pFly = AnchorFrm()->FindFlyFrm();
     116           0 :         SwPageFrm *pPageFrm = pFly ? pFly->FindPageFrm() : NULL;
     117           0 :         if( pPageFrm )
     118           0 :             pPageFrm->AppendFlyToPage( this );
     119             :     }
     120        3596 :     if( !GetPageFrm() )
     121           0 :         return;
     122             : 
     123        3596 :     Lock(); // The curtain drops
     124             : 
     125             :     // takes care of the notification in the dtor
     126        3596 :     const SwFlyNotify aNotify( this );
     127             : 
     128        3596 :     if ( IsClipped() )
     129             :     {
     130         208 :         mbValidSize = bHeightClipped = bWidthClipped = false;
     131             :         // no invalidation of position,
     132             :         // if anchored object is anchored inside a Writer fly frame,
     133             :         // its position is already locked, and it follows the text flow.
     134             :         // #i34753# - add condition:
     135             :         // no invalidation of position, if no direct move is requested in <CheckClip(..)>
     136         308 :         if ( !IsNoMoveOnCheckClip() &&
     137          50 :              !( PositionLocked() &&
     138           0 :                 GetAnchorFrm()->IsInFly() &&
     139           0 :                 GetFrameFormat().GetFollowTextFlow().GetValue() ) )
     140             :         {
     141          50 :             mbValidPos = false;
     142             :         }
     143             :     }
     144             : 
     145             :     // #i81146# new loop control
     146        3596 :     int nLoopControlRuns = 0;
     147        3596 :     const int nLoopControlMax = 10;
     148             : 
     149       12326 :     while ( !mbValidPos || !mbValidSize || !mbValidPrtArea || bFormatHeightOnly || !m_bValidContentPos )
     150             :     {
     151        5134 :         SWRECTFN( this )
     152             :         const SwFormatFrmSize *pSz;
     153             :         {   // Additional scope, so aAccess will be destroyed before the check!
     154             : 
     155        5134 :             SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
     156        5134 :             const SwBorderAttrs &rAttrs = *aAccess.Get();
     157        5134 :             pSz = &rAttrs.GetAttrSet().GetFrmSize();
     158             : 
     159             :             // Only set when the flag is set!
     160        5134 :             if ( !mbValidSize )
     161             :             {
     162        3812 :                 mbValidPrtArea = false;
     163             :             }
     164             : 
     165        5134 :             if ( !mbValidPrtArea )
     166             :             {
     167        3812 :                 MakePrtArea( rAttrs );
     168        3812 :                 m_bValidContentPos = false;
     169             :             }
     170             : 
     171        5134 :             if ( !mbValidSize || bFormatHeightOnly )
     172             :             {
     173        3812 :                 mbValidSize = false;
     174        3812 :                 Format( &rAttrs );
     175        3812 :                 bFormatHeightOnly = false;
     176        5134 :             }
     177             :         }
     178             : 
     179        5134 :         if ( !mbValidPos )
     180             :         {
     181        2512 :             const Point aOldPos( (Frm().*fnRect->fnGetPos)() );
     182             :             // #i26791# - use new method <MakeObjPos()>
     183             :             // #i34753# - no positioning, if requested.
     184        2512 :             if ( IsNoMakePos() )
     185           0 :                 mbValidPos = true;
     186             :             else
     187             :                 // #i26791# - use new method <MakeObjPos()>
     188        2512 :                 MakeObjPos();
     189        2512 :             if( aOldPos == (Frm().*fnRect->fnGetPos)() )
     190             :             {
     191         995 :                 if( !mbValidPos && GetAnchorFrm()->IsInSct() &&
     192           0 :                     !GetAnchorFrm()->FindSctFrm()->IsValid() )
     193           0 :                     mbValidPos = true;
     194             :             }
     195             :             else
     196        1517 :                 mbValidSize = false;
     197             :         }
     198             : 
     199        5134 :         if ( !m_bValidContentPos )
     200             :         {
     201        4314 :             SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
     202        4314 :             const SwBorderAttrs &rAttrs = *aAccess.Get();
     203        4314 :             MakeContentPos( rAttrs );
     204             :         }
     205             : 
     206        5134 :         if ( mbValidPos && mbValidSize )
     207             :         {
     208        3610 :             ++nLoopControlRuns;
     209             : 
     210             :             OSL_ENSURE( nLoopControlRuns < nLoopControlMax, "LoopControl in SwFlyFreeFrm::MakeAll" );
     211             : 
     212        7220 :             if ( nLoopControlRuns < nLoopControlMax )
     213        3610 :                 CheckClip( *pSz );
     214             :         }
     215             :         else
     216        1524 :             nLoopControlRuns = 0;
     217             :     }
     218        3596 :     Unlock();
     219             : 
     220             : #if OSL_DEBUG_LEVEL > 0
     221             :     SWRECTFN( this )
     222             :     OSL_ENSURE( bHeightClipped || ( (Frm().*fnRect->fnGetHeight)() > 0 &&
     223             :             (Prt().*fnRect->fnGetHeight)() > 0),
     224             :             "SwFlyFreeFrm::Format(), flipping Fly." );
     225             : 
     226             : #endif
     227             : }
     228             : 
     229             : /** determines, if direct environment of fly frame has 'auto' size
     230             : 
     231             :     #i17297#
     232             :     start with anchor frame and search via <GetUpper()> for a header, footer,
     233             :     row or fly frame stopping at page frame.
     234             :     return <true>, if such a frame is found and it has 'auto' size.
     235             :     otherwise <false> is returned.
     236             : 
     237             :     @return boolean indicating, that direct environment has 'auto' size
     238             : */
     239           1 : bool SwFlyFreeFrm::HasEnvironmentAutoSize() const
     240             : {
     241           1 :     bool bRetVal = false;
     242             : 
     243           1 :     const SwFrm* pToBeCheckedFrm = GetAnchorFrm();
     244           5 :     while ( pToBeCheckedFrm &&
     245           2 :             !pToBeCheckedFrm->IsPageFrm() )
     246             :     {
     247           5 :         if ( pToBeCheckedFrm->IsHeaderFrm() ||
     248           2 :              pToBeCheckedFrm->IsFooterFrm() ||
     249           4 :              pToBeCheckedFrm->IsRowFrm() ||
     250           1 :              pToBeCheckedFrm->IsFlyFrm() )
     251             :         {
     252             :             bRetVal = ATT_FIX_SIZE !=
     253           1 :                       pToBeCheckedFrm->GetAttrSet()->GetFrmSize().GetHeightSizeType();
     254           1 :             break;
     255             :         }
     256             :         else
     257             :         {
     258           1 :             pToBeCheckedFrm = pToBeCheckedFrm->GetUpper();
     259             :         }
     260             :     }
     261             : 
     262           1 :     return bRetVal;
     263             : }
     264             : 
     265        3610 : void SwFlyFreeFrm::CheckClip( const SwFormatFrmSize &rSz )
     266             : {
     267             :     // It's probably time now to take appropriate measures, if the Fly
     268             :     // doesn't fit into its surrounding.
     269             :     // First, the Fly gives up its position, then it's formatted.
     270             :     // Only if it still doesn't fit after giving up its position, the
     271             :     // width or height are given up as well. The frame will be squeezed
     272             :     // as much as needed.
     273             : 
     274        3610 :     const SwVirtFlyDrawObj *pObj = GetVirtDrawObj();
     275        3610 :     SwRect aClip, aTmpStretch;
     276        3610 :     ::CalcClipRect( pObj, aClip, true );
     277        3610 :     ::CalcClipRect( pObj, aTmpStretch, false );
     278        3610 :     aClip._Intersection( aTmpStretch );
     279             : 
     280        3610 :     const long nBot = Frm().Top() + Frm().Height();
     281        3610 :     const long nRig = Frm().Left() + Frm().Width();
     282        3610 :     const long nClipBot = aClip.Top() + aClip.Height();
     283        3610 :     const long nClipRig = aClip.Left() + aClip.Width();
     284             : 
     285        3610 :     const bool bBot = nBot > nClipBot;
     286        3610 :     const bool bRig = nRig > nClipRig;
     287        3610 :     if ( bBot || bRig )
     288             :     {
     289         221 :         bool bAgain = false;
     290             :         // #i37068# - no move, if it's requested
     291         461 :         if ( bBot && !IsNoMoveOnCheckClip() &&
     292         279 :              !GetDrawObjs() && !GetAnchorFrm()->IsInTab() )
     293             :         {
     294          29 :             SwFrm* pHeader = FindFooterOrHeader();
     295             :             // In a header, correction of the position is no good idea.
     296             :             // If the fly moves, some paragraphs have to be formatted, this
     297             :             // could cause a change of the height of the headerframe,
     298             :             // now the flyframe can change its position and so on ...
     299          29 :             if ( !pHeader || !pHeader->IsHeaderFrm() )
     300             :             {
     301          20 :                 const long nOld = Frm().Top();
     302          20 :                 Frm().Pos().Y() = std::max( aClip.Top(), nClipBot - Frm().Height() );
     303          20 :                 if ( Frm().Top() != nOld )
     304          12 :                     bAgain = true;
     305          20 :                 bHeightClipped = true;
     306             :             }
     307             :         }
     308         221 :         if ( bRig )
     309             :         {
     310          20 :             const long nOld = Frm().Left();
     311          20 :             Frm().Pos().X() = std::max( aClip.Left(), nClipRig - Frm().Width() );
     312          20 :             if ( Frm().Left() != nOld )
     313             :             {
     314           2 :                 const SwFormatHoriOrient &rH = GetFormat()->GetHoriOrient();
     315             :                 // Left-aligned ones may not be moved to the left when they
     316             :                 // are avoiding another one.
     317           2 :                 if( rH.GetHoriOrient() == text::HoriOrientation::LEFT )
     318           0 :                     Frm().Pos().X() = nOld;
     319             :                 else
     320           2 :                     bAgain = true;
     321             :             }
     322          20 :             bWidthClipped = true;
     323             :         }
     324         221 :         if ( bAgain )
     325          14 :             mbValidSize = false;
     326             :         else
     327             :         {
     328             :             // If we reach this branch, the Frm protrudes into forbidden
     329             :             // areas, and correcting the position is not allowed or not
     330             :             // possible or not required.
     331             : 
     332             :             // For Flys with OLE objects as lower, we make sure that
     333             :             // we always resize proportionally
     334         207 :             Size aOldSize( Frm().SSize() );
     335             : 
     336             :             // First, setup the FrmRect, then transfer it to the Frm.
     337         207 :             SwRect aFrmRect( Frm() );
     338             : 
     339         207 :             if ( bBot )
     340             :             {
     341         199 :                 long nDiff = nClipBot;
     342         199 :                 nDiff -= aFrmRect.Top(); // nDiff represents the available distance
     343         199 :                 nDiff = aFrmRect.Height() - nDiff;
     344         199 :                 aFrmRect.Height( aFrmRect.Height() - nDiff );
     345         199 :                 bHeightClipped = true;
     346             :             }
     347         207 :             if ( bRig )
     348             :             {
     349          18 :                 long nDiff = nClipRig;
     350          18 :                 nDiff -= aFrmRect.Left();// nDiff represents the available distance
     351          18 :                 nDiff = aFrmRect.Width() - nDiff;
     352          18 :                 aFrmRect.Width( aFrmRect.Width() - nDiff );
     353          18 :                 bWidthClipped = true;
     354             :             }
     355             : 
     356             :             // #i17297# - no proportional
     357             :             // scaling of graphics in environments, which determines its size
     358             :             // by its content ('auto' size). Otherwise layout loops can occur and
     359             :             // layout sizes of the environment can be incorrect.
     360             :             // Such environment are:
     361             :             // (1) header and footer frames with 'auto' size
     362             :             // (2) table row frames with 'auto' size
     363             :             // (3) fly frames with 'auto' size
     364             :             // Note: section frames seems to be not critical - didn't found
     365             :             //       any critical layout situation so far.
     366         208 :             if ( Lower() && Lower()->IsNoTextFrm() &&
     367           2 :                  ( static_cast<SwContentFrm*>(Lower())->GetNode()->GetOLENode() ||
     368           1 :                    !HasEnvironmentAutoSize() ) )
     369             :             {
     370             :                 // If width and height got adjusted, then the bigger
     371             :                 // change is relevant.
     372           0 :                 if ( aFrmRect.Width() != aOldSize.Width() &&
     373           0 :                      aFrmRect.Height()!= aOldSize.Height() )
     374             :                 {
     375           0 :                     if ( (aOldSize.Width() - aFrmRect.Width()) >
     376           0 :                          (aOldSize.Height()- aFrmRect.Height()) )
     377           0 :                         aFrmRect.Height( aOldSize.Height() );
     378             :                     else
     379           0 :                         aFrmRect.Width( aOldSize.Width() );
     380             :                 }
     381             : 
     382             :                 // Adjusted the width? change height proportionally
     383           0 :                 if( aFrmRect.Width() != aOldSize.Width() )
     384             :                 {
     385           0 :                     aFrmRect.Height( aFrmRect.Width() * aOldSize.Height() /
     386           0 :                                      aOldSize.Width() );
     387           0 :                     bHeightClipped = true;
     388             :                 }
     389             :                 // Adjusted the height? change width proportionally
     390           0 :                 else if( aFrmRect.Height() != aOldSize.Height() )
     391             :                 {
     392           0 :                     aFrmRect.Width( aFrmRect.Height() * aOldSize.Width() /
     393           0 :                                     aOldSize.Height() );
     394           0 :                     bWidthClipped = true;
     395             :                 }
     396             : 
     397             :                 // #i17297# - reactivate change
     398             :                 // of size attribute for fly frames containing an ole object.
     399             : 
     400             :                 // Added the aFrmRect.HasArea() hack, because
     401             :                 // the environment of the ole object does not have to be valid
     402             :                 // at this moment, or even worse, it does not have to have a
     403             :                 // reasonable size. In this case we do not want to change to
     404             :                 // attributes permanentely. Maybe one day somebody dares to remove
     405             :                 // this code.
     406           0 :                 if ( aFrmRect.HasArea() &&
     407           0 :                      static_cast<SwContentFrm*>(Lower())->GetNode()->GetOLENode() &&
     408           0 :                      ( bWidthClipped || bHeightClipped ) )
     409             :                 {
     410           0 :                     SwFlyFrameFormat *pFormat = GetFormat();
     411           0 :                     pFormat->LockModify();
     412           0 :                     SwFormatFrmSize aFrmSize( rSz );
     413           0 :                     aFrmSize.SetWidth( aFrmRect.Width() );
     414           0 :                     aFrmSize.SetHeight( aFrmRect.Height() );
     415           0 :                     pFormat->SetFormatAttr( aFrmSize );
     416           0 :                     pFormat->UnlockModify();
     417             :                 }
     418             :             }
     419             : 
     420             :             // Now change the Frm; for columns, we put the new values into the attributes,
     421             :             // otherwise we'll end up with unwanted side-effects/oscillations
     422         207 :             const long nPrtHeightDiff = Frm().Height() - Prt().Height();
     423         207 :             const long nPrtWidthDiff  = Frm().Width()  - Prt().Width();
     424         207 :             maUnclippedFrm = SwRect( Frm() );
     425         207 :             Frm().Height( aFrmRect.Height() );
     426         207 :             Frm().Width ( std::max( long(MINLAY), aFrmRect.Width() ) );
     427         207 :             if ( Lower() && Lower()->IsColumnFrm() )
     428             :             {
     429           0 :                 ColLock();  //lock grow/shrink
     430           0 :                 const Size aTmpOldSize( Prt().SSize() );
     431           0 :                 Prt().Height( Frm().Height() - nPrtHeightDiff );
     432           0 :                 Prt().Width ( Frm().Width()  - nPrtWidthDiff );
     433           0 :                 ChgLowersProp( aTmpOldSize );
     434           0 :                 SwFrm *pLow = Lower();
     435           0 :                 do
     436             :                 {
     437           0 :                     pLow->Calc();
     438             :                     // also calculate the (Column)BodyFrm
     439           0 :                     static_cast<SwLayoutFrm*>(pLow)->Lower()->Calc();
     440           0 :                     pLow = pLow->GetNext();
     441             :                 } while ( pLow );
     442           0 :                 ::CalcContent( this );
     443           0 :                 ColUnlock();
     444           0 :                 if ( !mbValidSize && !bWidthClipped )
     445           0 :                     bFormatHeightOnly = mbValidSize = true;
     446             :             }
     447             :             else
     448             :             {
     449         207 :                 Prt().Height( Frm().Height() - nPrtHeightDiff );
     450         207 :                 Prt().Width ( Frm().Width()  - nPrtWidthDiff );
     451             :             }
     452             :         }
     453             :     }
     454             : 
     455             :     // #i26945#
     456             :     OSL_ENSURE( Frm().Height() >= 0,
     457             :             "<SwFlyFreeFrm::CheckClip(..)> - fly frame has negative height now." );
     458        3610 : }
     459             : 
     460             : /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
     461             :     #i43771#
     462             : */
     463        8969 : bool SwFlyFreeFrm::IsFormatPossible() const
     464             : {
     465       26907 :     return SwFlyFrm::IsFormatPossible() &&
     466        8969 :            ( GetPageFrm() ||
     467        8969 :              ( GetAnchorFrm() && GetAnchorFrm()->IsInFly() ) );
     468             : }
     469             : 
     470         102 : SwFlyLayFrm::SwFlyLayFrm( SwFlyFrameFormat *pFormat, SwFrm* pSib, SwFrm *pAnch ) :
     471         102 :     SwFlyFreeFrm( pFormat, pSib, pAnch )
     472             : {
     473         102 :     bLayout = true;
     474         102 : }
     475             : 
     476             : // #i28701#
     477        9600 : TYPEINIT1(SwFlyLayFrm,SwFlyFreeFrm);
     478             : 
     479          47 : void SwFlyLayFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
     480             : {
     481          47 :     const sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
     482             : 
     483          47 :     const SwFormatAnchor *pAnch = 0;
     484          77 :     if( RES_ATTRSET_CHG == nWhich && SfxItemState::SET ==
     485          30 :         static_cast<const SwAttrSetChg*>(pNew)->GetChgSet()->GetItemState( RES_ANCHOR, false,
     486          30 :             reinterpret_cast<const SfxPoolItem**>(&pAnch) ))
     487             :         ; // GetItemState sets the anchor pointer!
     488             : 
     489          43 :     else if( RES_ANCHOR == nWhich )
     490             :     {
     491             :         // Change of anchor. I'm attaching myself to the new place.
     492             :         // It's not allowed to change the anchor type. This is only
     493             :         // possible via SwFEShell.
     494           0 :         pAnch = static_cast<const SwFormatAnchor*>(pNew);
     495             :     }
     496             : 
     497          47 :     if( pAnch )
     498             :     {
     499             :         OSL_ENSURE( pAnch->GetAnchorId() ==
     500             :                 GetFormat()->GetAnchor().GetAnchorId(),
     501             :                 "8-) Invalid change of anchor type." );
     502             : 
     503             :         // Unregister, get hold of the page, attach to the corresponding LayoutFrm.
     504           4 :         SwRect aOld( GetObjRectWithSpaces() );
     505             :         // #i28701# - use new method <GetPageFrm()>
     506           4 :         SwPageFrm *pOldPage = GetPageFrm();
     507           4 :         AnchorFrm()->RemoveFly( this );
     508             : 
     509           4 :         if ( FLY_AT_PAGE == pAnch->GetAnchorId() )
     510             :         {
     511           4 :             sal_uInt16 nPgNum = pAnch->GetPageNum();
     512           4 :             SwRootFrm *pRoot = getRootFrm();
     513           4 :             SwPageFrm *pTmpPage = static_cast<SwPageFrm*>(pRoot->Lower());
     514          12 :             for ( sal_uInt16 i = 1; (i <= nPgNum) && pTmpPage; ++i,
     515           4 :                                 pTmpPage = static_cast<SwPageFrm*>(pTmpPage->GetNext()) )
     516             :             {
     517           4 :                 if ( i == nPgNum )
     518             :                 {
     519             :                     // #i50432# - adjust synopsis of <PlaceFly(..)>
     520           4 :                     pTmpPage->PlaceFly( this, 0 );
     521             :                 }
     522             :             }
     523           4 :             if( !pTmpPage )
     524             :             {
     525           4 :                 pRoot->SetAssertFlyPages();
     526           4 :                 pRoot->AssertFlyPages();
     527             :             }
     528             :         }
     529             :         else
     530             :         {
     531           0 :             SwNodeIndex aIdx( pAnch->GetContentAnchor()->nNode );
     532           0 :             SwContentFrm *pContent = GetFormat()->GetDoc()->GetNodes().GoNext( &aIdx )->
     533           0 :                          GetContentNode()->getLayoutFrm( getRootFrm(), 0, 0, false );
     534           0 :             if( pContent )
     535             :             {
     536           0 :                 SwFlyFrm *pTmp = pContent->FindFlyFrm();
     537           0 :                 if( pTmp )
     538           0 :                     pTmp->AppendFly( this );
     539           0 :             }
     540             :         }
     541             :         // #i28701# - use new method <GetPageFrm()>
     542           4 :         if ( pOldPage && pOldPage != GetPageFrm() )
     543           0 :             NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE );
     544           4 :         SetCompletePaint();
     545           4 :         InvalidateAll();
     546           4 :         SetNotifyBack();
     547             :     }
     548             :     else
     549          43 :         SwFlyFrm::Modify( pOld, pNew );
     550          47 : }
     551             : 
     552        2214 : void SwPageFrm::AppendFlyToPage( SwFlyFrm *pNew )
     553             : {
     554        2214 :     if ( !pNew->GetVirtDrawObj()->IsInserted() )
     555          66 :         getRootFrm()->GetDrawPage()->InsertObject(
     556          66 :                 static_cast<SdrObject*>(pNew->GetVirtDrawObj()),
     557         132 :                 pNew->GetVirtDrawObj()->GetReferencedObj().GetOrdNumDirect() );
     558             : 
     559        2214 :     InvalidateSpelling();
     560        2214 :     InvalidateSmartTags();
     561        2214 :     InvalidateAutoCompleteWords();
     562        2214 :     InvalidateWordCount();
     563             : 
     564        2214 :     if ( GetUpper() )
     565             :     {
     566        2214 :         static_cast<SwRootFrm*>(GetUpper())->SetIdleFlags();
     567        2214 :         static_cast<SwRootFrm*>(GetUpper())->InvalidateBrowseWidth();
     568             :     }
     569             : 
     570        2214 :     SdrObject* pObj = pNew->GetVirtDrawObj();
     571             :     OSL_ENSURE( pNew->GetAnchorFrm(), "Fly without Anchor" );
     572        2214 :     SwFlyFrm* pFly = const_cast<SwFlyFrm*>(pNew->GetAnchorFrm()->FindFlyFrm());
     573        2214 :     if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() )
     574             :     {
     575             :         //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
     576           3 :         sal_uInt32 nNewNum = pObj->GetOrdNumDirect();
     577           3 :         if ( pObj->GetPage() )
     578           3 :             pObj->GetPage()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum );
     579             :         else
     580           0 :             pFly->GetVirtDrawObj()->SetOrdNum( nNewNum );
     581             :     }
     582             : 
     583             :     // Don't look further at Flys that sit inside the Content.
     584        2214 :     if ( pNew->IsFlyInCntFrm() )
     585         815 :         InvalidateFlyInCnt();
     586             :     else
     587             :     {
     588        1399 :         InvalidateFlyContent();
     589             : 
     590        1399 :         if ( !pSortedObjs )
     591         469 :             pSortedObjs = new SwSortedObjs();
     592             : 
     593        1399 :         const bool bSucessInserted = pSortedObjs->Insert( *pNew );
     594             :         OSL_ENSURE( bSucessInserted, "Fly not inserted in Sorted." );
     595             :         (void) bSucessInserted;
     596             : 
     597             :         // #i87493#
     598             :         OSL_ENSURE( pNew->GetPageFrm() == 0 || pNew->GetPageFrm() == this,
     599             :                 "<SwPageFrm::AppendFlyToPage(..)> - anchored fly frame seems to be registered at another page frame. Serious defect -> please inform OD." );
     600             :         // #i28701# - use new method <SetPageFrm(..)>
     601        1399 :         pNew->SetPageFrm( this );
     602        1399 :         pNew->InvalidatePage( this );
     603             :         // #i28701#
     604        1399 :         pNew->UnlockPosition();
     605             : 
     606             :         // Notify accessible layout. That's required at this place for
     607             :         // frames only where the anchor is moved. Creation of new frames
     608             :         // is additionally handled by the SwFrmNotify class.
     609        4197 :         if( GetUpper() &&
     610        1399 :             static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
     611           0 :              static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
     612             :         {
     613           0 :             static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
     614           0 :                                       ->AddAccessibleFrm( pNew );
     615             :         }
     616             :     }
     617             : 
     618             :     // #i28701# - correction: consider also drawing objects
     619        2214 :     if ( pNew->GetDrawObjs() )
     620             :     {
     621           1 :         SwSortedObjs &rObjs = *pNew->GetDrawObjs();
     622           9 :         for ( size_t i = 0; i < rObjs.size(); ++i )
     623             :         {
     624           8 :             SwAnchoredObject* pTmpObj = rObjs[i];
     625           8 :             if ( pTmpObj->ISA(SwFlyFrm) )
     626             :             {
     627           0 :                 SwFlyFrm* pTmpFly = static_cast<SwFlyFrm*>(pTmpObj);
     628             :                 // #i28701# - use new method <GetPageFrm()>
     629           0 :                 if ( pTmpFly->IsFlyFreeFrm() && !pTmpFly->GetPageFrm() )
     630           0 :                     AppendFlyToPage( pTmpFly );
     631             :             }
     632           8 :             else if ( pTmpObj->ISA(SwAnchoredDrawObject) )
     633             :             {
     634             :                 // #i87493#
     635           8 :                 if ( pTmpObj->GetPageFrm() != this )
     636             :                 {
     637           8 :                     if ( pTmpObj->GetPageFrm() != 0 )
     638             :                     {
     639           0 :                         pTmpObj->GetPageFrm()->RemoveDrawObjFromPage( *pTmpObj );
     640             :                     }
     641           8 :                     AppendDrawObjToPage( *pTmpObj );
     642             :                 }
     643             :             }
     644             :         }
     645             :     }
     646        2214 : }
     647             : 
     648         183 : void SwPageFrm::RemoveFlyFromPage( SwFlyFrm *pToRemove )
     649             : {
     650         183 :     const sal_uInt32 nOrdNum = pToRemove->GetVirtDrawObj()->GetOrdNum();
     651         183 :     getRootFrm()->GetDrawPage()->RemoveObject( nOrdNum );
     652         183 :     pToRemove->GetVirtDrawObj()->ReferencedObj().SetOrdNum( nOrdNum );
     653             : 
     654         183 :     if ( GetUpper() )
     655             :     {
     656         183 :         if ( !pToRemove->IsFlyInCntFrm() )
     657         182 :             static_cast<SwRootFrm*>(GetUpper())->SetSuperfluous();
     658         183 :         static_cast<SwRootFrm*>(GetUpper())->InvalidateBrowseWidth();
     659             :     }
     660             : 
     661             :     // Don't look further at Flys that sit inside the Content.
     662         183 :     if ( pToRemove->IsFlyInCntFrm() )
     663         184 :         return;
     664             : 
     665             :     // Don't delete collections just yet. This will happen at the end of the
     666             :     // action in the RemoveSuperfluous of the page, kicked off by a method of
     667             :     // the same name in the root.
     668             :     // The FlyColl might be gone already, because the page's dtor is being
     669             :     // executed.
     670             :     // Remove it _before_ disposing accessible frames to avoid accesses to
     671             :     // the Frm from event handlers.
     672         182 :     if (pSortedObjs)
     673             :     {
     674         182 :         pSortedObjs->Remove(*pToRemove);
     675         182 :         if (!pSortedObjs->size())
     676             :         {
     677          36 :             delete pSortedObjs;
     678          36 :             pSortedObjs = 0;
     679             :         }
     680             :     }
     681             : 
     682             :     // Notify accessible layout. That's required at this place for
     683             :     // frames only where the anchor is moved. Creation of new frames
     684             :     // is additionally handled by the SwFrmNotify class.
     685         546 :     if( GetUpper() &&
     686         182 :         static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
     687           0 :         static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
     688             :     {
     689           0 :         static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
     690           0 :                                   ->DisposeAccessibleFrm( pToRemove, true );
     691             :     }
     692             : 
     693             :     // #i28701# - use new method <SetPageFrm(..)>
     694         182 :     pToRemove->SetPageFrm( 0L );
     695             : }
     696             : 
     697          16 : void SwPageFrm::MoveFly( SwFlyFrm *pToMove, SwPageFrm *pDest )
     698             : {
     699             :     // Invalidations
     700          16 :     if ( GetUpper() )
     701             :     {
     702          16 :         static_cast<SwRootFrm*>(GetUpper())->SetIdleFlags();
     703          16 :         if ( !pToMove->IsFlyInCntFrm() && pDest->GetPhyPageNum() < GetPhyPageNum() )
     704          11 :             static_cast<SwRootFrm*>(GetUpper())->SetSuperfluous();
     705             :     }
     706             : 
     707          16 :     pDest->InvalidateSpelling();
     708          16 :     pDest->InvalidateSmartTags();
     709          16 :     pDest->InvalidateAutoCompleteWords();
     710          16 :     pDest->InvalidateWordCount();
     711             : 
     712          16 :     if ( pToMove->IsFlyInCntFrm() )
     713             :     {
     714           0 :         pDest->InvalidateFlyInCnt();
     715          16 :         return;
     716             :     }
     717             : 
     718             :     // Notify accessible layout. That's required at this place for
     719             :     // frames only where the anchor is moved. Creation of new frames
     720             :     // is additionally handled by the SwFrmNotify class.
     721          48 :     if( GetUpper() &&
     722          16 :         static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
     723           0 :         static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
     724             :     {
     725           0 :         static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
     726           0 :                                   ->DisposeAccessibleFrm( pToMove, true );
     727             :     }
     728             : 
     729             :     // The FlyColl might be gone already, because the page's dtor is being executed.
     730          16 :     if ( pSortedObjs )
     731             :     {
     732          16 :         pSortedObjs->Remove( *pToMove );
     733          16 :         if ( !pSortedObjs->size() )
     734             :         {
     735           8 :             DELETEZ( pSortedObjs );
     736             :         }
     737             :     }
     738             : 
     739             :     // Register
     740          16 :     if ( !pDest->GetSortedObjs() )
     741           7 :         pDest->pSortedObjs = new SwSortedObjs();
     742             : 
     743          16 :     const bool bSucessInserted = pDest->GetSortedObjs()->Insert( *pToMove );
     744             :     OSL_ENSURE( bSucessInserted, "Fly not inserted in Sorted." );
     745             :     (void) bSucessInserted;
     746             : 
     747             :     // #i28701# - use new method <SetPageFrm(..)>
     748          16 :     pToMove->SetPageFrm( pDest );
     749          16 :     pToMove->InvalidatePage( pDest );
     750          16 :     pToMove->SetNotifyBack();
     751          16 :     pDest->InvalidateFlyContent();
     752             :     // #i28701#
     753          16 :     pToMove->UnlockPosition();
     754             : 
     755             :     // Notify accessible layout. That's required at this place for
     756             :     // frames only where the anchor is moved. Creation of new frames
     757             :     // is additionally handled by the SwFrmNotify class.
     758          48 :     if( GetUpper() &&
     759          16 :         static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
     760           0 :         static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
     761             :     {
     762           0 :         static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
     763           0 :                                   ->AddAccessibleFrm( pToMove );
     764             :     }
     765             : 
     766             :     // #i28701# - correction: move lowers of Writer fly frame
     767          16 :     if ( pToMove->GetDrawObjs() )
     768             :     {
     769           0 :         SwSortedObjs &rObjs = *pToMove->GetDrawObjs();
     770           0 :         for ( size_t i = 0; i < rObjs.size(); ++i )
     771             :         {
     772           0 :             SwAnchoredObject* pObj = rObjs[i];
     773           0 :             if ( pObj->ISA(SwFlyFrm) )
     774             :             {
     775           0 :                 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
     776           0 :                 if ( pFly->IsFlyFreeFrm() )
     777             :                 {
     778             :                     // #i28701# - use new method <GetPageFrm()>
     779           0 :                     SwPageFrm* pPageFrm = pFly->GetPageFrm();
     780           0 :                     if ( pPageFrm )
     781           0 :                         pPageFrm->MoveFly( pFly, pDest );
     782             :                     else
     783           0 :                         pDest->AppendFlyToPage( pFly );
     784             :                 }
     785             :             }
     786           0 :             else if ( pObj->ISA(SwAnchoredDrawObject) )
     787             :             {
     788           0 :                 RemoveDrawObjFromPage( *pObj );
     789           0 :                 pDest->AppendDrawObjToPage( *pObj );
     790             :             }
     791             :         }
     792             :     }
     793             : }
     794             : 
     795        2203 : void SwPageFrm::AppendDrawObjToPage( SwAnchoredObject& _rNewObj )
     796             : {
     797        2203 :     if ( !_rNewObj.ISA(SwAnchoredDrawObject) )
     798             :     {
     799             :         OSL_FAIL( "SwPageFrm::AppendDrawObjToPage(..) - anchored object of unexpected type -> object not appended" );
     800           0 :         return;
     801             :     }
     802             : 
     803        2203 :     if ( GetUpper() )
     804             :     {
     805        2203 :         static_cast<SwRootFrm*>(GetUpper())->InvalidateBrowseWidth();
     806             :     }
     807             : 
     808             :     OSL_ENSURE( _rNewObj.GetAnchorFrm(), "anchored draw object without anchor" );
     809        2203 :     SwFlyFrm* pFlyFrm = const_cast<SwFlyFrm*>(_rNewObj.GetAnchorFrm()->FindFlyFrm());
     810        2245 :     if ( pFlyFrm &&
     811          42 :          _rNewObj.GetDrawObj()->GetOrdNum() < pFlyFrm->GetVirtDrawObj()->GetOrdNum() )
     812             :     {
     813             :         //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
     814          12 :         sal_uInt32 nNewNum = _rNewObj.GetDrawObj()->GetOrdNumDirect();
     815          12 :         if ( _rNewObj.GetDrawObj()->GetPage() )
     816          12 :             _rNewObj.DrawObj()->GetPage()->SetObjectOrdNum( pFlyFrm->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum );
     817             :         else
     818           0 :             pFlyFrm->GetVirtDrawObj()->SetOrdNum( nNewNum );
     819             :     }
     820             : 
     821        2203 :     if ( FLY_AS_CHAR == _rNewObj.GetFrameFormat().GetAnchor().GetAnchorId() )
     822             :     {
     823         515 :         return;
     824             :     }
     825             : 
     826        1688 :     if ( !pSortedObjs )
     827             :     {
     828         518 :         pSortedObjs = new SwSortedObjs();
     829             :     }
     830        1688 :     if ( !pSortedObjs->Insert( _rNewObj ) )
     831             :     {
     832             :         OSL_ENSURE( pSortedObjs->Contains( _rNewObj ),
     833             :                 "Drawing object not appended into list <pSortedObjs>." );
     834             :     }
     835             :     // #i87493#
     836             :     OSL_ENSURE( _rNewObj.GetPageFrm() == 0 || _rNewObj.GetPageFrm() == this,
     837             :             "<SwPageFrm::AppendDrawObjToPage(..)> - anchored draw object seems to be registered at another page frame. Serious defect -> please inform OD." );
     838        1688 :     _rNewObj.SetPageFrm( this );
     839             : 
     840             :     // invalidate page in order to force a reformat of object layout of the page.
     841        1688 :     InvalidateFlyLayout();
     842             : }
     843             : 
     844         406 : void SwPageFrm::RemoveDrawObjFromPage( SwAnchoredObject& _rToRemoveObj )
     845             : {
     846         406 :     if ( !_rToRemoveObj.ISA(SwAnchoredDrawObject) )
     847             :     {
     848             :         OSL_FAIL( "SwPageFrm::RemoveDrawObjFromPage(..) - anchored object of unexpected type -> object not removed" );
     849         406 :         return;
     850             :     }
     851             : 
     852         406 :     if ( pSortedObjs )
     853             :     {
     854         406 :         pSortedObjs->Remove( _rToRemoveObj );
     855         406 :         if ( !pSortedObjs->size() )
     856             :         {
     857          49 :             DELETEZ( pSortedObjs );
     858             :         }
     859         406 :         if ( GetUpper() )
     860             :         {
     861         406 :             if (FLY_AS_CHAR !=
     862         406 :                     _rToRemoveObj.GetFrameFormat().GetAnchor().GetAnchorId())
     863             :             {
     864         406 :                 static_cast<SwRootFrm*>(GetUpper())->SetSuperfluous();
     865         406 :                 InvalidatePage();
     866             :             }
     867         406 :             static_cast<SwRootFrm*>(GetUpper())->InvalidateBrowseWidth();
     868             :         }
     869             :     }
     870         406 :     _rToRemoveObj.SetPageFrm( 0 );
     871             : }
     872             : 
     873             : // #i50432# - adjust method description and synopsis.
     874          27 : void SwPageFrm::PlaceFly( SwFlyFrm* pFly, SwFlyFrameFormat* pFormat )
     875             : {
     876             :     // #i50432# - consider the case that page is an empty page:
     877             :     // In this case append the fly frame at the next page
     878             :     OSL_ENSURE( !IsEmptyPage() || GetNext(),
     879             :             "<SwPageFrm::PlaceFly(..)> - empty page with no next page! -> fly frame appended at empty page" );
     880          27 :     if ( IsEmptyPage() && GetNext() )
     881             :     {
     882           0 :         static_cast<SwPageFrm*>(GetNext())->PlaceFly( pFly, pFormat );
     883             :     }
     884             :     else
     885             :     {
     886             :         // If we received a Fly, we use that one. Otherwise, create a new
     887             :         // one using the Format.
     888          27 :         if ( pFly )
     889           4 :             AppendFly( pFly );
     890             :         else
     891             :         {
     892             :             OSL_ENSURE( pFormat, ":-( No Format given for Fly." );
     893          23 :             pFly = new SwFlyLayFrm( pFormat, this, this );
     894          23 :             AppendFly( pFly );
     895          23 :             ::RegistFlys( this, pFly );
     896             :         }
     897             :     }
     898          27 : }
     899             : 
     900             : // #i18732# - adjustments for following text flow or not
     901             : // AND alignment at 'page areas' for to paragraph/to character anchored objects
     902             : // #i22305# - adjustment for following text flow for to frame anchored objects
     903             : // #i29778# - Because calculating the floating screen object's position
     904             : // (Writer fly frame or drawing object) doesn't perform a calculation on its
     905             : // upper frames and its anchor frame, a calculation of the upper frames in this
     906             : // method is no longer sensible.
     907             : // #i28701# - if document compatibility option 'Consider wrapping style influence
     908             : // on object positioning' is ON, the clip area corresponds to the one as the
     909             : // object doesn't follow the text flow.
     910        7222 : bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, bool bMove )
     911             : {
     912        7222 :     bool bRet = true;
     913        7222 :     if ( pSdrObj->ISA(SwVirtFlyDrawObj) )
     914             :     {
     915        7221 :         const SwFlyFrm* pFly = static_cast<const SwVirtFlyDrawObj*>(pSdrObj)->GetFlyFrm();
     916        7221 :         const bool bFollowTextFlow = pFly->GetFormat()->GetFollowTextFlow().GetValue();
     917             :         // #i28701#
     918             :         const bool bConsiderWrapOnObjPos =
     919        7221 :                                 pFly->GetFormat()->getIDocumentSettingAccess()->get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION);
     920        7221 :         const SwFormatVertOrient &rV = pFly->GetFormat()->GetVertOrient();
     921        7221 :         if( pFly->IsFlyLayFrm() )
     922             :         {
     923             :             const SwFrm* pClip;
     924             :             // #i22305#
     925             :             // #i28701#
     926         130 :             if ( !bFollowTextFlow || bConsiderWrapOnObjPos )
     927             :             {
     928         124 :                 pClip = pFly->GetAnchorFrm()->FindPageFrm();
     929             :             }
     930             :             else
     931             :             {
     932           6 :                 pClip = pFly->GetAnchorFrm();
     933             :             }
     934             : 
     935         130 :             rRect = pClip->Frm();
     936         130 :             SWRECTFN( pClip )
     937             : 
     938             :             // vertical clipping: Top and Bottom, also to PrtArea if necessary
     939         154 :             if( rV.GetVertOrient() != text::VertOrientation::NONE &&
     940          24 :                 rV.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
     941             :             {
     942           8 :                 (rRect.*fnRect->fnSetTop)( (pClip->*fnRect->fnGetPrtTop)() );
     943           8 :                 (rRect.*fnRect->fnSetBottom)( (pClip->*fnRect->fnGetPrtBottom)() );
     944             :             }
     945             :             // horizontal clipping: Top and Bottom, also to PrtArea if necessary
     946         130 :             const SwFormatHoriOrient &rH = pFly->GetFormat()->GetHoriOrient();
     947         146 :             if( rH.GetHoriOrient() != text::HoriOrientation::NONE &&
     948          16 :                 rH.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
     949             :             {
     950          12 :                 (rRect.*fnRect->fnSetLeft)( (pClip->*fnRect->fnGetPrtLeft)() );
     951          12 :                 (rRect.*fnRect->fnSetRight)((pClip->*fnRect->fnGetPrtRight)());
     952             :             }
     953             :         }
     954        7091 :         else if( pFly->IsFlyAtCntFrm() )
     955             :         {
     956             :             // #i18732# - consider following text flow or not
     957             :             // AND alignment at 'page areas'
     958        7091 :             const SwFrm* pVertPosOrientFrm = pFly->GetVertPosOrientFrm();
     959        7091 :             if ( !pVertPosOrientFrm )
     960             :             {
     961             :                 OSL_FAIL( "::CalcClipRect(..) - frame, vertical position is oriented at, is missing .");
     962           0 :                 pVertPosOrientFrm = pFly->GetAnchorFrm();
     963             :             }
     964             : 
     965        7091 :             if ( !bFollowTextFlow || bConsiderWrapOnObjPos )
     966             :             {
     967        7081 :                 const SwLayoutFrm* pClipFrm = pVertPosOrientFrm->FindPageFrm();
     968        7081 :                 if (!pClipFrm)
     969             :                 {
     970             :                     OSL_FAIL("!pClipFrm: "
     971             :                             "if you can reproduce this please file a bug");
     972           0 :                     return false;
     973             :                 }
     974       10622 :                 rRect = bMove ? pClipFrm->GetUpper()->Frm()
     975       10622 :                               : pClipFrm->Frm();
     976             :                 // #i26945# - consider that a table, during
     977             :                 // its format, can exceed its upper printing area bottom.
     978             :                 // Thus, enlarge the clip rectangle, if such a case occurred
     979        7081 :                 if ( pFly->GetAnchorFrm()->IsInTab() )
     980             :                 {
     981             :                     const SwTabFrm* pTabFrm = const_cast<SwFlyFrm*>(pFly)
     982          72 :                                 ->GetAnchorFrmContainingAnchPos()->FindTabFrm();
     983          72 :                     SwRect aTmp( pTabFrm->Prt() );
     984          72 :                     aTmp += pTabFrm->Frm().Pos();
     985          72 :                     rRect.Union( aTmp );
     986             :                     // #i43913# - consider also the cell frame
     987             :                     const SwFrm* pCellFrm = const_cast<SwFlyFrm*>(pFly)
     988          72 :                                 ->GetAnchorFrmContainingAnchPos()->GetUpper();
     989         144 :                     while ( pCellFrm && !pCellFrm->IsCellFrm() )
     990             :                     {
     991           0 :                         pCellFrm = pCellFrm->GetUpper();
     992             :                     }
     993          72 :                     if ( pCellFrm )
     994             :                     {
     995          72 :                         aTmp = pCellFrm->Prt();
     996          72 :                         aTmp += pCellFrm->Frm().Pos();
     997          72 :                         rRect.Union( aTmp );
     998             :                     }
     999        7081 :                 }
    1000             :             }
    1001          20 :             else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME ||
    1002          10 :                       rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
    1003             :             {
    1004             :                 // new class <SwEnvironmentOfAnchoredObject>
    1005             :                 objectpositioning::SwEnvironmentOfAnchoredObject
    1006           0 :                                                 aEnvOfObj( bFollowTextFlow );
    1007             :                 const SwLayoutFrm& rVertClipFrm =
    1008           0 :                     aEnvOfObj.GetVertEnvironmentLayoutFrm( *pVertPosOrientFrm );
    1009           0 :                 if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME )
    1010             :                 {
    1011           0 :                     rRect = rVertClipFrm.Frm();
    1012             :                 }
    1013           0 :                 else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
    1014             :                 {
    1015           0 :                     if ( rVertClipFrm.IsPageFrm() )
    1016             :                     {
    1017           0 :                         rRect = static_cast<const SwPageFrm&>(rVertClipFrm).PrtWithoutHeaderAndFooter();
    1018             :                     }
    1019             :                     else
    1020             :                     {
    1021           0 :                         rRect = rVertClipFrm.Frm();
    1022             :                     }
    1023             :                 }
    1024             :                 const SwLayoutFrm* pHoriClipFrm =
    1025           0 :                         pFly->GetAnchorFrm()->FindPageFrm()->GetUpper();
    1026           0 :                 SWRECTFN( pFly->GetAnchorFrm() )
    1027           0 :                 (rRect.*fnRect->fnSetLeft)( (pHoriClipFrm->Frm().*fnRect->fnGetLeft)() );
    1028           0 :                 (rRect.*fnRect->fnSetRight)((pHoriClipFrm->Frm().*fnRect->fnGetRight)());
    1029             :             }
    1030             :             else
    1031             :             {
    1032             :                 // #i26945#
    1033             :                 const SwFrm *pClip =
    1034          10 :                         const_cast<SwFlyFrm*>(pFly)->GetAnchorFrmContainingAnchPos();
    1035          10 :                 SWRECTFN( pClip )
    1036          10 :                 const SwLayoutFrm *pUp = pClip->GetUpper();
    1037          10 :                 const SwFrm *pCell = pUp->IsCellFrm() ? pUp : 0;
    1038             :                 const sal_uInt16 nType = bMove ? FRM_ROOT   | FRM_FLY | FRM_HEADER |
    1039             :                                        FRM_FOOTER | FRM_FTN
    1040             :                                      : FRM_BODY   | FRM_FLY | FRM_HEADER |
    1041          10 :                                        FRM_FOOTER | FRM_CELL| FRM_FTN;
    1042             : 
    1043          30 :                 while ( !(pUp->GetType() & nType) || pUp->IsColBodyFrm() )
    1044             :                 {
    1045          10 :                     pUp = pUp->GetUpper();
    1046          10 :                     if ( !pCell && pUp->IsCellFrm() )
    1047           0 :                         pCell = pUp;
    1048             :                 }
    1049          10 :                 if ( bMove )
    1050             :                 {
    1051           5 :                     if ( pUp->IsRootFrm() )
    1052             :                     {
    1053           5 :                         rRect  = pUp->Prt();
    1054           5 :                         rRect += pUp->Frm().Pos();
    1055           5 :                         pUp = 0;
    1056             :                     }
    1057             :                 }
    1058          10 :                 if ( pUp )
    1059             :                 {
    1060           5 :                     if ( pUp->GetType() & FRM_BODY )
    1061             :                     {
    1062             :                         const SwPageFrm *pPg;
    1063           5 :                         if ( pUp->GetUpper() != (pPg = pFly->FindPageFrm()) )
    1064           0 :                             pUp = pPg->FindBodyCont();
    1065           5 :                         if (pUp)
    1066             :                         {
    1067           5 :                             rRect = pUp->GetUpper()->Frm();
    1068           5 :                             (rRect.*fnRect->fnSetTop)( (pUp->*fnRect->fnGetPrtTop)() );
    1069           5 :                             (rRect.*fnRect->fnSetBottom)((pUp->*fnRect->fnGetPrtBottom)());
    1070             :                         }
    1071             :                     }
    1072             :                     else
    1073             :                     {
    1074           0 :                         if( ( pUp->GetType() & (FRM_FLY | FRM_FTN ) ) &&
    1075           0 :                             !pUp->Frm().IsInside( pFly->Frm().Pos() ) )
    1076             :                         {
    1077           0 :                             if( pUp->IsFlyFrm() )
    1078             :                             {
    1079           0 :                                 const SwFlyFrm *pTmpFly = static_cast<const SwFlyFrm*>(pUp);
    1080           0 :                                 while( pTmpFly->GetNextLink() )
    1081             :                                 {
    1082           0 :                                     pTmpFly = pTmpFly->GetNextLink();
    1083           0 :                                     if( pTmpFly->Frm().IsInside( pFly->Frm().Pos() ) )
    1084           0 :                                         break;
    1085             :                                 }
    1086           0 :                                 pUp = pTmpFly;
    1087             :                             }
    1088           0 :                             else if( pUp->IsInFootnote() )
    1089             :                             {
    1090           0 :                                 const SwFootnoteFrm *pTmp = pUp->FindFootnoteFrm();
    1091           0 :                                 while( pTmp->GetFollow() )
    1092             :                                 {
    1093           0 :                                     pTmp = pTmp->GetFollow();
    1094           0 :                                     if( pTmp->Frm().IsInside( pFly->Frm().Pos() ) )
    1095           0 :                                         break;
    1096             :                                 }
    1097           0 :                                 pUp = pTmp;
    1098             :                             }
    1099             :                         }
    1100           0 :                         rRect = pUp->Prt();
    1101           0 :                         rRect.Pos() += pUp->Frm().Pos();
    1102           0 :                         if ( pUp->GetType() & (FRM_HEADER | FRM_FOOTER) )
    1103             :                         {
    1104           0 :                             rRect.Left ( pUp->GetUpper()->Frm().Left() );
    1105           0 :                             rRect.Width( pUp->GetUpper()->Frm().Width());
    1106             :                         }
    1107           0 :                         else if ( pUp->IsCellFrm() )                //MA_FLY_HEIGHT
    1108             :                         {
    1109           0 :                             const SwFrm *pTab = pUp->FindTabFrm();
    1110             :                             (rRect.*fnRect->fnSetBottom)(
    1111           0 :                                         (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() );
    1112             :                             // expand to left and right cell border
    1113           0 :                             rRect.Left ( pUp->Frm().Left() );
    1114           0 :                             rRect.Width( pUp->Frm().Width() );
    1115             :                         }
    1116             :                     }
    1117             :                 }
    1118          10 :                 if ( pCell )
    1119             :                 {
    1120             :                     // CellFrms might also sit in unallowed areas. In this case,
    1121             :                     // the Fly is allowed to do so as well
    1122           0 :                     SwRect aTmp( pCell->Prt() );
    1123           0 :                     aTmp += pCell->Frm().Pos();
    1124           0 :                     rRect.Union( aTmp );
    1125             :                 }
    1126             :             }
    1127             :         }
    1128             :         else
    1129             :         {
    1130           0 :             const SwFrm *pUp = pFly->GetAnchorFrm()->GetUpper();
    1131           0 :             SWRECTFN( pFly->GetAnchorFrm() )
    1132           0 :             while( pUp->IsColumnFrm() || pUp->IsSctFrm() || pUp->IsColBodyFrm())
    1133           0 :                 pUp = pUp->GetUpper();
    1134           0 :             rRect = pUp->Frm();
    1135           0 :             if( !pUp->IsBodyFrm() )
    1136             :             {
    1137           0 :                 rRect += pUp->Prt().Pos();
    1138           0 :                 rRect.SSize( pUp->Prt().SSize() );
    1139           0 :                 if ( pUp->IsCellFrm() )
    1140             :                 {
    1141           0 :                     const SwFrm *pTab = pUp->FindTabFrm();
    1142             :                     (rRect.*fnRect->fnSetBottom)(
    1143           0 :                                     (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() );
    1144             :                 }
    1145             :             }
    1146           0 :             else if ( pUp->GetUpper()->IsPageFrm() )
    1147             :             {
    1148             :                 // Objects anchored as character may exceed right margin
    1149             :                 // of body frame:
    1150           0 :                 (rRect.*fnRect->fnSetRight)( (pUp->GetUpper()->Frm().*fnRect->fnGetRight)() );
    1151             :             }
    1152           0 :             long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10;
    1153             :             long nTop;
    1154           0 :             const SwFormat *pFormat = static_cast<SwContact*>(GetUserCall(pSdrObj))->GetFormat();
    1155           0 :             const SvxULSpaceItem &rUL = pFormat->GetULSpace();
    1156           0 :             if( bMove )
    1157             :             {
    1158           0 :                 nTop = bVert ? static_cast<const SwFlyInCntFrm*>(pFly)->GetRefPoint().X() :
    1159           0 :                                static_cast<const SwFlyInCntFrm*>(pFly)->GetRefPoint().Y();
    1160           0 :                 nTop = (*fnRect->fnYInc)( nTop, -nHeight );
    1161           0 :                 long nWidth = (pFly->Frm().*fnRect->fnGetWidth)();
    1162             :                 (rRect.*fnRect->fnSetLeftAndWidth)( bVert ?
    1163           0 :                             static_cast<const SwFlyInCntFrm*>(pFly)->GetRefPoint().Y() :
    1164           0 :                             static_cast<const SwFlyInCntFrm*>(pFly)->GetRefPoint().X(), nWidth );
    1165           0 :                 nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper();
    1166             :             }
    1167             :             else
    1168             :             {
    1169           0 :                 nTop = (*fnRect->fnYInc)( (pFly->Frm().*fnRect->fnGetBottom)(),
    1170           0 :                                            rUL.GetLower() - nHeight );
    1171           0 :                 nHeight = 2*nHeight - (pFly->Frm().*fnRect->fnGetHeight)()
    1172           0 :                           - rUL.GetLower() - rUL.GetUpper();
    1173             :             }
    1174           0 :             (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight );
    1175             :         }
    1176             :     }
    1177             :     else
    1178             :     {
    1179           1 :         const SwDrawContact *pC = static_cast<const SwDrawContact*>(GetUserCall(pSdrObj));
    1180           1 :         const SwFrameFormat  *pFormat = pC->GetFormat();
    1181           1 :         const SwFormatAnchor &rAnch = pFormat->GetAnchor();
    1182           1 :         if ( FLY_AS_CHAR == rAnch.GetAnchorId() )
    1183             :         {
    1184           0 :             const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj );
    1185           0 :             if( !pAnchorFrm )
    1186             :             {
    1187             :                 OSL_FAIL( "<::CalcClipRect(..)> - missing anchor frame." );
    1188           0 :                 const_cast<SwDrawContact*>(pC)->ConnectToLayout();
    1189           0 :                 pAnchorFrm = pC->GetAnchorFrm();
    1190             :             }
    1191           0 :             const SwFrm* pUp = pAnchorFrm->GetUpper();
    1192           0 :             rRect = pUp->Prt();
    1193           0 :             rRect += pUp->Frm().Pos();
    1194           0 :             SWRECTFN( pAnchorFrm )
    1195           0 :             long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10;
    1196             :             long nTop;
    1197           0 :             const SvxULSpaceItem &rUL = pFormat->GetULSpace();
    1198           0 :             SwRect aSnapRect( pSdrObj->GetSnapRect() );
    1199           0 :             long nTmpH = 0;
    1200           0 :             if( bMove )
    1201             :             {
    1202           0 :                 nTop = (*fnRect->fnYInc)( bVert ? pSdrObj->GetAnchorPos().X() :
    1203           0 :                                        pSdrObj->GetAnchorPos().Y(), -nHeight );
    1204           0 :                 long nWidth = (aSnapRect.*fnRect->fnGetWidth)();
    1205             :                 (rRect.*fnRect->fnSetLeftAndWidth)( bVert ?
    1206           0 :                             pSdrObj->GetAnchorPos().Y() :
    1207           0 :                             pSdrObj->GetAnchorPos().X(), nWidth );
    1208             :             }
    1209             :             else
    1210             :             {
    1211             :                 // #i26791# - value of <nTmpH> is needed to
    1212             :                 // calculate value of <nTop>.
    1213           0 :                 nTmpH = bVert ? pSdrObj->GetCurrentBoundRect().GetWidth() :
    1214           0 :                                 pSdrObj->GetCurrentBoundRect().GetHeight();
    1215           0 :                 nTop = (*fnRect->fnYInc)( (aSnapRect.*fnRect->fnGetTop)(),
    1216           0 :                                           rUL.GetLower() + nTmpH - nHeight );
    1217             :             }
    1218           0 :             nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper();
    1219           0 :             (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight );
    1220             :         }
    1221             :         else
    1222             :         {
    1223             :             // restrict clip rectangle for drawing
    1224             :             // objects in header/footer to the page frame.
    1225             :             // #i26791#
    1226           1 :             const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj );
    1227           1 :             if ( pAnchorFrm && pAnchorFrm->FindFooterOrHeader() )
    1228             :             {
    1229             :                 // clip frame is the page frame the header/footer is on.
    1230           0 :                 const SwFrm* pClipFrm = pAnchorFrm->FindPageFrm();
    1231           0 :                 rRect = pClipFrm->Frm();
    1232             :             }
    1233             :             else
    1234             :             {
    1235           1 :                 bRet = false;
    1236             :             }
    1237             :         }
    1238             :     }
    1239        7222 :     return bRet;
    1240         177 : }
    1241             : 
    1242             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11