LCOV - code coverage report
Current view: top level - sw/source/core/layout - anchoreddrawobject.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 260 314 82.8 %
Date: 2015-06-13 12:38:46 Functions: 31 36 86.1 %
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 <dcontact.hxx>
      21             : #include <rootfrm.hxx>
      22             : #include <pagefrm.hxx>
      23             : #include <tocntntanchoredobjectposition.hxx>
      24             : #include <tolayoutanchoredobjectposition.hxx>
      25             : #include <frmtool.hxx>
      26             : #include <fmtornt.hxx>
      27             : #include <txtfrm.hxx>
      28             : #include <vector>
      29             : #include <svx/svdogrp.hxx>
      30             : #include <tools/fract.hxx>
      31             : #include <DocumentSettingManager.hxx>
      32             : #include <IDocumentState.hxx>
      33             : #include <txtfly.hxx>
      34             : 
      35             : using namespace ::com::sun::star;
      36             : 
      37             : /// helper class for correct notification due to the positioning of
      38             : /// the anchored drawing object
      39             : class SwPosNotify
      40             : {
      41             :     private:
      42             :         SwAnchoredDrawObject* mpAnchoredDrawObj;
      43             :         SwRect maOldObjRect;
      44             :         SwPageFrm* mpOldPageFrm;
      45             : 
      46             :     public:
      47             :         explicit SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj );
      48             :         ~SwPosNotify();
      49             :         // #i32795#
      50             :         Point LastObjPos() const;
      51             : };
      52             : 
      53        2186 : SwPosNotify::SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj ) :
      54        2186 :     mpAnchoredDrawObj( _pAnchoredDrawObj )
      55             : {
      56        2186 :     maOldObjRect = mpAnchoredDrawObj->GetObjRect();
      57             :     // --> #i35640# - determine correct page frame
      58        2186 :     mpOldPageFrm = mpAnchoredDrawObj->GetPageFrm();
      59        2186 : }
      60             : 
      61        2186 : SwPosNotify::~SwPosNotify()
      62             : {
      63        2186 :     if ( maOldObjRect != mpAnchoredDrawObj->GetObjRect() )
      64             :     {
      65        1540 :         if( maOldObjRect.HasArea() && mpOldPageFrm )
      66             :         {
      67             :             mpAnchoredDrawObj->NotifyBackground( mpOldPageFrm, maOldObjRect,
      68        1431 :                                                  PREP_FLY_LEAVE );
      69             :         }
      70        1540 :         SwRect aNewObjRect( mpAnchoredDrawObj->GetObjRect() );
      71        1540 :         if( aNewObjRect.HasArea() )
      72             :         {
      73             :             // --> #i35640# - determine correct page frame
      74        1431 :             SwPageFrm* pNewPageFrm = mpAnchoredDrawObj->GetPageFrm();
      75        1431 :             if( pNewPageFrm )
      76             :                 mpAnchoredDrawObj->NotifyBackground( pNewPageFrm, aNewObjRect,
      77        1431 :                                                      PREP_FLY_ARRIVE );
      78             :         }
      79             : 
      80        1540 :         ::ClrContourCache( mpAnchoredDrawObj->GetDrawObj() );
      81             : 
      82             :         // --> #i35640# - additional notify anchor text frame
      83             :         // Needed for negative positioned drawing objects
      84             :         // --> #i43255# - refine condition to avoid unneeded
      85             :         // invalidations: anchored object had to be on the page of its anchor
      86             :         // text frame.
      87        3042 :         if ( mpAnchoredDrawObj->GetAnchorFrm()->IsTextFrm() &&
      88        1502 :              mpOldPageFrm == mpAnchoredDrawObj->GetAnchorFrm()->FindPageFrm() )
      89             :         {
      90        1490 :             mpAnchoredDrawObj->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
      91             :         }
      92             : 
      93             :         // indicate a restart of the layout process
      94        1540 :         mpAnchoredDrawObj->SetRestartLayoutProcess( true );
      95             :     }
      96             :     else
      97             :     {
      98             :         // lock position
      99         646 :         mpAnchoredDrawObj->LockPosition();
     100             : 
     101         646 :         if ( !mpAnchoredDrawObj->ConsiderForTextWrap() )
     102             :         {
     103             :             // indicate that object has to be considered for text wrap
     104         213 :             mpAnchoredDrawObj->SetConsiderForTextWrap( true );
     105             :             // invalidate 'background' in order to allow its 'background'
     106             :             // to wrap around it.
     107             :             mpAnchoredDrawObj->NotifyBackground( mpAnchoredDrawObj->GetPageFrm(),
     108         213 :                                     mpAnchoredDrawObj->GetObjRectWithSpaces(),
     109         426 :                                     PREP_FLY_ARRIVE );
     110             :             // invalidate position of anchor frame in order to force
     111             :             // a re-format of the anchor frame, which also causes a
     112             :             // re-format of the invalid previous frames of the anchor frame.
     113         213 :             mpAnchoredDrawObj->AnchorFrm()->InvalidatePos();
     114             :         }
     115             :     }
     116        2186 : }
     117             : 
     118             : // --> #i32795#
     119        2129 : Point SwPosNotify::LastObjPos() const
     120             : {
     121        2129 :     return maOldObjRect.Pos();
     122             : }
     123             : 
     124             : // #i32795#
     125             : /// helper class for oscillation control on object positioning
     126             : class SwObjPosOscillationControl
     127             : {
     128             :     private:
     129             :         sal_uInt8 mnPosStackSize;
     130             : 
     131             :         const SwAnchoredDrawObject* mpAnchoredDrawObj;
     132             : 
     133             :         std::vector<Point*> maObjPositions;
     134             : 
     135             :     public:
     136             :         explicit SwObjPosOscillationControl( const SwAnchoredDrawObject& _rAnchoredDrawObj );
     137             :         ~SwObjPosOscillationControl();
     138             : 
     139             :         bool OscillationDetected();
     140             : };
     141             : 
     142        2077 : SwObjPosOscillationControl::SwObjPosOscillationControl(
     143             :                                 const SwAnchoredDrawObject& _rAnchoredDrawObj )
     144             :     : mnPosStackSize( 20 ),
     145        2077 :       mpAnchoredDrawObj( &_rAnchoredDrawObj )
     146             : {
     147        2077 : }
     148             : 
     149        4154 : SwObjPosOscillationControl::~SwObjPosOscillationControl()
     150             : {
     151        5656 :     while ( !maObjPositions.empty() )
     152             :     {
     153        1502 :         Point* pPos = maObjPositions.back();
     154        1502 :         delete pPos;
     155             : 
     156        1502 :         maObjPositions.pop_back();
     157             :     }
     158        2077 : }
     159             : 
     160        1502 : bool SwObjPosOscillationControl::OscillationDetected()
     161             : {
     162        1502 :     bool bOscillationDetected = false;
     163             : 
     164        1502 :     if ( maObjPositions.size() == mnPosStackSize )
     165             :     {
     166             :         // position stack is full -> oscillation
     167           0 :         bOscillationDetected = true;
     168             :     }
     169             :     else
     170             :     {
     171        1502 :         Point* pNewObjPos = new Point( mpAnchoredDrawObj->GetObjRect().Pos() );
     172        4506 :         for ( std::vector<Point*>::iterator aObjPosIter = maObjPositions.begin();
     173        3004 :               aObjPosIter != maObjPositions.end();
     174             :               ++aObjPosIter )
     175             :         {
     176           0 :             if ( *(pNewObjPos) == *(*aObjPosIter) )
     177             :             {
     178             :                 // position already occurred -> oscillation
     179           0 :                 bOscillationDetected = true;
     180           0 :                 delete pNewObjPos;
     181           0 :                 break;
     182             :             }
     183             :         }
     184        1502 :         if ( !bOscillationDetected )
     185             :         {
     186        1502 :             maObjPositions.push_back( pNewObjPos );
     187             :         }
     188             :     }
     189             : 
     190        1502 :     return bOscillationDetected;
     191             : }
     192             : 
     193     1253188 : TYPEINIT1(SwAnchoredDrawObject,SwAnchoredObject);
     194             : 
     195        2664 : SwAnchoredDrawObject::SwAnchoredDrawObject() :
     196             :     SwAnchoredObject(),
     197             :     mbValidPos( false ),
     198             :     // --> #i34748#
     199             :     mpLastObjRect( 0L ),
     200             :     mbNotYetAttachedToAnchorFrame( true ),
     201             :     // --> #i28749#
     202             :     mbNotYetPositioned( true ),
     203             :     // --> #i62875#
     204        2664 :     mbCaptureAfterLayoutDirChange( false )
     205             : {
     206        2664 : }
     207             : 
     208        5326 : SwAnchoredDrawObject::~SwAnchoredDrawObject()
     209             : {
     210             :     // #i34748#
     211        2663 :     delete mpLastObjRect;
     212        2663 : }
     213             : 
     214             : // --> #i62875#
     215        2180 : void SwAnchoredDrawObject::UpdateLayoutDir()
     216             : {
     217        2180 :     SwFrameFormat::tLayoutDir nOldLayoutDir( GetFrameFormat().GetLayoutDir() );
     218             : 
     219        2180 :     SwAnchoredObject::UpdateLayoutDir();
     220             : 
     221        4705 :     if ( !NotYetPositioned() &&
     222         345 :          GetFrameFormat().GetLayoutDir() != nOldLayoutDir &&
     223        2180 :          GetFrameFormat().GetDoc()->GetDocumentSettingManager().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
     224           0 :          !IsOutsidePage() )
     225             :     {
     226           0 :         mbCaptureAfterLayoutDirChange = true;
     227             :     }
     228        2180 : }
     229             : 
     230             : // --> #i62875#
     231           0 : bool SwAnchoredDrawObject::IsOutsidePage() const
     232             : {
     233           0 :     bool bOutsidePage( false );
     234             : 
     235           0 :     if ( !NotYetPositioned() && GetPageFrm() )
     236             :     {
     237           0 :         SwRect aTmpRect( GetObjRect() );
     238             :         bOutsidePage =
     239           0 :             ( aTmpRect.Intersection( GetPageFrm()->Frm() ) != GetObjRect() );
     240             :     }
     241             : 
     242           0 :     return bOutsidePage;
     243             : }
     244             : 
     245        9238 : void SwAnchoredDrawObject::MakeObjPos()
     246             : {
     247        9238 :     if ( IsPositioningInProgress() )
     248             :     {
     249             :         // nothind to do - positioning already in progress
     250           0 :         return;
     251             :     }
     252             : 
     253        9238 :     if ( mbValidPos )
     254             :     {
     255             :         // nothing to do - position is valid
     256        6499 :         return;
     257             :     }
     258             : 
     259             :     // --> #i28749# - anchored drawing object has to be attached
     260             :     // to anchor frame
     261        2739 :     if ( mbNotYetAttachedToAnchorFrame )
     262             :     {
     263             :         OSL_FAIL( "<SwAnchoredDrawObject::MakeObjPos() - drawing object not yet attached to anchor frame -> no positioning" );
     264           0 :         return;
     265             :     }
     266             : 
     267             :     SwDrawContact* pDrawContact =
     268        2739 :                         static_cast<SwDrawContact*>(::GetUserCall( GetDrawObj() ));
     269             : 
     270             :     // --> #i28749# - if anchored drawing object hasn't been yet
     271             :     // positioned, convert its positioning attributes, if its positioning
     272             :     // attributes are given in horizontal left-to-right layout.
     273             :     // --> #i36010# - Note: horizontal left-to-right layout is made
     274             :     // the default layout direction for <SwDrawFrameFormat> instances. Thus, it has
     275             :     // to be adjusted manually, if no adjustment of the positioning attributes
     276             :     // have to be performed here.
     277             :     // --> #i35635# - additionally move drawing object to the visible layer.
     278        2739 :     if ( mbNotYetPositioned )
     279             :     {
     280             :         // --> #i35635#
     281        1790 :         pDrawContact->MoveObjToVisibleLayer( DrawObj() );
     282             :         // --> perform conversion of positioning
     283             :         // attributes only for 'master' drawing objects
     284             :         // #i44334#, #i44681# - check, if positioning
     285             :         // attributes already have been set.
     286        3360 :         if ( !GetDrawObj()->ISA(SwDrawVirtObj) &&
     287        1570 :              !static_cast<SwDrawFrameFormat&>(GetFrameFormat()).IsPosAttrSet() )
     288             :         {
     289        1522 :             _SetPositioningAttr();
     290             :         }
     291             :         // -->
     292             :         // - reset internal flag after all needed actions are performed to
     293             :         //   avoid callbacks from drawing layer
     294        1790 :         mbNotYetPositioned = false;
     295             :     }
     296             : 
     297             :     // indicate that positioning is in progress
     298             :     {
     299        2739 :         SwObjPositioningInProgress aObjPosInProgress( *this );
     300             : 
     301             :         // determine relative position of drawing object and set it
     302        2739 :         switch ( pDrawContact->GetAnchorId() )
     303             :         {
     304             :             case FLY_AS_CHAR:
     305             :             {
     306             :                 // indicate that position will be valid after positioning is performed
     307         605 :                 mbValidPos = true;
     308             :                 // nothing to do, because as-character anchored objects are positioned
     309             :                 // during the format of its anchor frame - see <SwFlyCntPortion::SetBase(..)>
     310             :             }
     311         605 :             break;
     312             :             case FLY_AT_PARA:
     313             :             case FLY_AT_CHAR:
     314             :             {
     315             :                 // --> #i32795# - move intrinsic positioning to
     316             :                 // helper method <_MakeObjPosAnchoredAtPara()>
     317        2077 :                 _MakeObjPosAnchoredAtPara();
     318             :             }
     319        2077 :             break;
     320             :             case FLY_AT_PAGE:
     321             :             case FLY_AT_FLY:
     322             :             {
     323             :                 // --> #i32795# - move intrinsic positioning to
     324             :                 // helper method <_MakeObjPosAnchoredAtLayout()>
     325          57 :                 _MakeObjPosAnchoredAtLayout();
     326             :             }
     327          57 :             break;
     328             :             default:
     329             :             {
     330             :                 OSL_FAIL( "<SwAnchoredDrawObject::MakeObjPos()> - unknown anchor type - please inform OD." );
     331             :             }
     332             :         }
     333             : 
     334             :         // keep, current object rectangle
     335             :         // --> #i34748# - use new method <SetLastObjRect(..)>
     336        2739 :         SetLastObjRect( GetObjRect().SVRect() );
     337             : 
     338             :         // Assure for 'master' drawing object, that it's registered at the correct page.
     339             :         // Perform check not for as-character anchored drawing objects and only if
     340             :         // the anchor frame is valid.
     341        7536 :         if ( !GetDrawObj()->ISA(SwDrawVirtObj) &&
     342        4192 :              !pDrawContact->ObjAnchoredAsChar() &&
     343        1453 :              GetAnchorFrm()->IsValid() )
     344             :         {
     345        1116 :             pDrawContact->ChkPage();
     346        2739 :         }
     347             :     }
     348             : 
     349             :     // --> #i62875#
     350        2739 :     if ( mbCaptureAfterLayoutDirChange &&
     351           0 :          GetPageFrm() )
     352             :     {
     353           0 :         SwRect aPageRect( GetPageFrm()->Frm() );
     354           0 :         SwRect aObjRect( GetObjRect() );
     355           0 :         if ( aObjRect.Right() >= aPageRect.Right() + 10 )
     356             :         {
     357           0 :             Size aSize( aPageRect.Right() - aObjRect.Right(), 0 );
     358           0 :             DrawObj()->Move( aSize );
     359           0 :             aObjRect = GetObjRect();
     360             :         }
     361             : 
     362           0 :         if ( aObjRect.Left() + 10 <= aPageRect.Left() )
     363             :         {
     364           0 :             Size aSize( aPageRect.Left() - aObjRect.Left(), 0 );
     365           0 :             DrawObj()->Move( aSize );
     366             :         }
     367             : 
     368           0 :         mbCaptureAfterLayoutDirChange = false;
     369             :     }
     370             : }
     371             : 
     372             : /** method for the intrinsic positioning of a at-paragraph|at-character
     373             :     anchored drawing object
     374             : 
     375             :     #i32795# - helper method for method <MakeObjPos>
     376             : */
     377        2077 : void SwAnchoredDrawObject::_MakeObjPosAnchoredAtPara()
     378             : {
     379             :     // --> #i32795# - adopt positioning algorithm from Writer
     380             :     // fly frames, which are anchored at paragraph|at character
     381             : 
     382             :     // Determine, if anchor frame can/has to be formatted.
     383             :     // If yes, after each object positioning the anchor frame is formatted.
     384             :     // If after the anchor frame format the object position isn't valid, the
     385             :     // object is positioned again.
     386             :     // --> #i43255# - refine condition: anchor frame format not
     387             :     // allowed, if another anchored object, has to be consider its wrap influence
     388             :     // --> #i50356# - format anchor frame containing the anchor
     389             :     // position. E.g., for at-character anchored object this can be the follow
     390             :     // frame of the anchor frame, which contains the anchor character.
     391             :     const bool bFormatAnchor =
     392        4154 :             !static_cast<const SwTextFrm*>( GetAnchorFrmContainingAnchPos() )->IsAnyJoinLocked() &&
     393        3749 :             !ConsiderObjWrapInfluenceOnObjPos() &&
     394        3749 :             !ConsiderObjWrapInfluenceOfOtherObjs();
     395             : 
     396        2077 :     if ( bFormatAnchor )
     397             :     {
     398             :         // --> #i50356#
     399        1623 :         GetAnchorFrmContainingAnchPos()->Calc();
     400             :     }
     401             : 
     402        2077 :     bool bOscillationDetected = false;
     403        2077 :     SwObjPosOscillationControl aObjPosOscCtrl( *this );
     404             :     // --> #i3317# - boolean, to apply temporarly the
     405             :     // 'straightforward positioning process' for the frame due to its
     406             :     // overlapping with a previous column.
     407        2077 :     bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
     408        2129 :     do {
     409             :         // indicate that position will be valid after positioning is performed
     410        2129 :         mbValidPos = true;
     411             : 
     412             :         // --> #i35640# - correct scope for <SwPosNotify> instance
     413             :         {
     414             :             // create instance of <SwPosNotify> for correct notification
     415        2129 :             SwPosNotify aPosNotify( this );
     416             : 
     417             :             // determine and set position
     418             :             objectpositioning::SwToContentAnchoredObjectPosition
     419        4258 :                     aObjPositioning( *DrawObj() );
     420        2129 :             aObjPositioning.CalcPosition();
     421             : 
     422             :             // get further needed results of the positioning algorithm
     423        2129 :             SetVertPosOrientFrm ( aObjPositioning.GetVertPosOrientFrm() );
     424        2129 :             _SetDrawObjAnchor();
     425             : 
     426             :             // check for object position oscillation, if position has changed.
     427        2129 :             if ( GetObjRect().Pos() != aPosNotify.LastObjPos() )
     428             :             {
     429        1502 :                 bOscillationDetected = aObjPosOscCtrl.OscillationDetected();
     430        2129 :             }
     431             :         }
     432             :         // format anchor frame, if requested.
     433             :         // Note: the format of the anchor frame can cause the object position
     434             :         // to be invalid.
     435        2129 :         if ( bFormatAnchor )
     436             :         {
     437             :             // --> #i50356#
     438        1675 :             GetAnchorFrmContainingAnchPos()->Calc();
     439             :         }
     440             : 
     441             :         // --> #i3317#
     442        3853 :         if ( !ConsiderObjWrapInfluenceOnObjPos() &&
     443        1724 :              OverlapsPrevColumn() )
     444             :         {
     445           0 :             bConsiderWrapInfluenceDueToOverlapPrevCol = true;
     446             :         }
     447        2233 :     } while ( !mbValidPos && !bOscillationDetected &&
     448          52 :               !bConsiderWrapInfluenceDueToOverlapPrevCol );
     449             : 
     450             :     // --> #i3317# - consider a detected oscillation and overlapping
     451             :     // with previous column.
     452             :     // temporarly consider the anchored objects wrapping style influence
     453        2077 :     if ( bOscillationDetected || bConsiderWrapInfluenceDueToOverlapPrevCol )
     454             :     {
     455           0 :         SetTmpConsiderWrapInfluence( true );
     456           0 :         SetRestartLayoutProcess( true );
     457        2077 :     }
     458        2077 : }
     459             : 
     460             : /** method for the intrinsic positioning of a at-page|at-frame anchored
     461             :     drawing object
     462             : 
     463             :     #i32795# - helper method for method <MakeObjPos>
     464             : */
     465          57 : void SwAnchoredDrawObject::_MakeObjPosAnchoredAtLayout()
     466             : {
     467             :     // indicate that position will be valid after positioning is performed
     468          57 :     mbValidPos = true;
     469             : 
     470             :     // create instance of <SwPosNotify> for correct notification
     471          57 :     SwPosNotify aPosNotify( this );
     472             : 
     473             :     // determine position
     474             :     objectpositioning::SwToLayoutAnchoredObjectPosition
     475         114 :             aObjPositioning( *DrawObj() );
     476          57 :     aObjPositioning.CalcPosition();
     477             : 
     478             :     // set position
     479             : 
     480             :     // --> #i31698#
     481             :     // --> #i34995# - setting anchor position needed for filters,
     482             :     // especially for the xml-filter to the OpenOffice.org file format
     483             :     {
     484             :         const Point aNewAnchorPos =
     485          57 :                     GetAnchorFrm()->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
     486          57 :         DrawObj()->SetAnchorPos( aNewAnchorPos );
     487             :         // --> #i70122# - missing invalidation
     488          57 :         InvalidateObjRectWithSpaces();
     489             :     }
     490          57 :     SetCurrRelPos( aObjPositioning.GetRelPos() );
     491          57 :     const SwFrm* pAnchorFrm = GetAnchorFrm();
     492          57 :     SWRECTFN( pAnchorFrm );
     493          57 :     const Point aAnchPos( (pAnchorFrm->Frm().*fnRect->fnGetPos)() );
     494          57 :     SetObjLeft( aAnchPos.X() + GetCurrRelPos().X() );
     495         114 :     SetObjTop( aAnchPos.Y() + GetCurrRelPos().Y() );
     496          57 : }
     497             : 
     498        2129 : void SwAnchoredDrawObject::_SetDrawObjAnchor()
     499             : {
     500             :     // new anchor position
     501             :     // --> #i31698# -
     502             :     Point aNewAnchorPos =
     503        2129 :                 GetAnchorFrm()->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
     504        2129 :     Point aCurrAnchorPos = GetDrawObj()->GetAnchorPos();
     505        2129 :     if ( aNewAnchorPos != aCurrAnchorPos )
     506             :     {
     507             :         // determine movement to be applied after setting the new anchor position
     508        1507 :         Size aMove( aCurrAnchorPos.getX() - aNewAnchorPos.getX(),
     509        3014 :                     aCurrAnchorPos.getY() - aNewAnchorPos.getY() );
     510             :         // set new anchor position
     511        1507 :         DrawObj()->SetAnchorPos( aNewAnchorPos );
     512             :         // correct object position, caused by setting new anchor position
     513        1507 :         DrawObj()->Move( aMove );
     514             :         // --> #i70122# - missing invalidation
     515        1507 :         InvalidateObjRectWithSpaces();
     516             :     }
     517        2129 : }
     518             : 
     519             : /** method to invalidate the given page frame
     520             : 
     521             :     #i28701#
     522             : */
     523        1033 : void SwAnchoredDrawObject::_InvalidatePage( SwPageFrm* _pPageFrm )
     524             : {
     525        1033 :     if ( _pPageFrm && !_pPageFrm->GetFormat()->GetDoc()->IsInDtor() )
     526             :     {
     527        1033 :         if ( _pPageFrm->GetUpper() )
     528             :         {
     529             :             // --> #i35007# - correct invalidation for as-character
     530             :             // anchored objects.
     531        1033 :             if ( GetFrameFormat().GetAnchor().GetAnchorId() == FLY_AS_CHAR )
     532             :             {
     533         118 :                 _pPageFrm->InvalidateFlyInCnt();
     534             :             }
     535             :             else
     536             :             {
     537         915 :                 _pPageFrm->InvalidateFlyLayout();
     538             :             }
     539             : 
     540        1033 :             SwRootFrm* pRootFrm = static_cast<SwRootFrm*>(_pPageFrm->GetUpper());
     541        1033 :             pRootFrm->DisallowTurbo();
     542        1033 :             if ( pRootFrm->GetTurbo() )
     543             :             {
     544           1 :                 const SwContentFrm* pTmpFrm = pRootFrm->GetTurbo();
     545           1 :                 pRootFrm->ResetTurbo();
     546           1 :                 pTmpFrm->InvalidatePage();
     547             :             }
     548        1033 :             pRootFrm->SetIdleFlags();
     549             :         }
     550             :     }
     551        1033 : }
     552             : 
     553       11726 : void SwAnchoredDrawObject::InvalidateObjPos()
     554             : {
     555             :     // --> #i28701# - check, if invalidation is allowed
     556       12905 :     if ( mbValidPos &&
     557        1179 :          InvalidationOfPosAllowed() )
     558             :     {
     559        1022 :         mbValidPos = false;
     560             :         // --> #i68520#
     561        1022 :         InvalidateObjRectWithSpaces();
     562             : 
     563             :         // --> #i44339# - check, if anchor frame exists.
     564        1022 :         if ( GetAnchorFrm() )
     565             :         {
     566             :             // --> #118547# - notify anchor frame of as-character
     567             :             // anchored object, because its positioned by the format of its anchor frame.
     568             :             // --> #i44559# - assure, that text hint is already
     569             :             // existing in the text frame
     570        2035 :             if ( GetAnchorFrm()->ISA(SwTextFrm) &&
     571        1013 :                  (GetFrameFormat().GetAnchor().GetAnchorId() == FLY_AS_CHAR) )
     572             :             {
     573         118 :                 SwTextFrm* pAnchorTextFrm( static_cast<SwTextFrm*>(AnchorFrm()) );
     574         236 :                 if ( pAnchorTextFrm->GetTextNode()->GetpSwpHints() &&
     575         118 :                      pAnchorTextFrm->CalcFlyPos( &GetFrameFormat() ) != COMPLETE_STRING )
     576             :                 {
     577         118 :                     AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG, &GetFrameFormat() );
     578             :                 }
     579             :             }
     580             : 
     581        1022 :             SwPageFrm* pPageFrm = AnchorFrm()->FindPageFrm();
     582        1022 :             _InvalidatePage( pPageFrm );
     583             : 
     584             :             // --> #i32270# - also invalidate page frame, at which the
     585             :             // drawing object is registered at.
     586        1022 :             SwPageFrm* pPageFrmRegisteredAt = GetPageFrm();
     587        1022 :             if ( pPageFrmRegisteredAt &&
     588             :                  pPageFrmRegisteredAt != pPageFrm )
     589             :             {
     590          11 :                 _InvalidatePage( pPageFrmRegisteredAt );
     591             :             }
     592             :             // #i33751#, #i34060# - method <GetPageFrmOfAnchor()>
     593             :             // is replaced by method <FindPageFrmOfAnchor()>. It's return value
     594             :             // have to be checked.
     595        1022 :             SwPageFrm* pPageFrmOfAnchor = FindPageFrmOfAnchor();
     596        1022 :             if ( pPageFrmOfAnchor &&
     597           0 :                  pPageFrmOfAnchor != pPageFrm &&
     598             :                  pPageFrmOfAnchor != pPageFrmRegisteredAt )
     599             :             {
     600           0 :                 _InvalidatePage( pPageFrmOfAnchor );
     601             :             }
     602             :         }
     603             :     }
     604       11726 : }
     605             : 
     606      236669 : SwFrameFormat& SwAnchoredDrawObject::GetFrameFormat()
     607             : {
     608             :     OSL_ENSURE( static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat(),
     609             :             "<SwAnchoredDrawObject::GetFrameFormat()> - missing frame format -> crash." );
     610      236669 :     return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat());
     611             : }
     612      499564 : const SwFrameFormat& SwAnchoredDrawObject::GetFrameFormat() const
     613             : {
     614             :     OSL_ENSURE( static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat(),
     615             :             "<SwAnchoredDrawObject::GetFrameFormat()> - missing frame format -> crash." );
     616      499564 :     return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFormat());
     617             : }
     618             : 
     619     1243713 : const SwRect SwAnchoredDrawObject::GetObjRect() const
     620             : {
     621             :     // use geometry of drawing object
     622             :     //return GetDrawObj()->GetCurrentBoundRect();
     623     1243713 :     return GetDrawObj()->GetSnapRect();
     624             : }
     625             : 
     626             : // --> #i70122#
     627        5527 : const SwRect SwAnchoredDrawObject::GetObjBoundRect() const
     628             : {
     629        5527 :     bool bGroupShape = PTR_CAST(SdrObjGroup, GetDrawObj());
     630             :     // Resize objects with relative width or height
     631        5527 :     if ( !bGroupShape && GetPageFrm( ) && ( GetDrawObj( )->GetRelativeWidth( ) || GetDrawObj()->GetRelativeHeight( ) ) )
     632             :     {
     633         242 :         Rectangle aCurrObjRect = GetDrawObj()->GetCurrentBoundRect();
     634             : 
     635         242 :         long nTargetWidth = aCurrObjRect.GetWidth( );
     636         242 :         if ( GetDrawObj( )->GetRelativeWidth( ) )
     637             :         {
     638         203 :             Rectangle aPageRect;
     639         203 :             if (GetDrawObj()->GetRelativeWidthRelation() == text::RelOrientation::FRAME)
     640             :                 // Exclude margins.
     641         126 :                 aPageRect = GetPageFrm()->Prt().SVRect();
     642             :             else
     643          77 :                 aPageRect = GetPageFrm( )->GetBoundRect( ).SVRect();
     644         203 :             nTargetWidth = aPageRect.GetWidth( ) * (*GetDrawObj( )->GetRelativeWidth());
     645             :         }
     646             : 
     647         242 :         long nTargetHeight = aCurrObjRect.GetHeight( );
     648         242 :         if ( GetDrawObj( )->GetRelativeHeight( ) )
     649             :         {
     650         174 :             Rectangle aPageRect;
     651         174 :             if (GetDrawObj()->GetRelativeHeightRelation() == text::RelOrientation::FRAME)
     652             :                 // Exclude margins.
     653          63 :                 aPageRect = GetPageFrm()->Prt().SVRect();
     654             :             else
     655         111 :                 aPageRect = GetPageFrm( )->GetBoundRect( ).SVRect();
     656         174 :             nTargetHeight = aPageRect.GetHeight( ) * (*GetDrawObj( )->GetRelativeHeight());
     657             :         }
     658             : 
     659         242 :         if ( nTargetWidth != aCurrObjRect.GetWidth( ) || nTargetHeight != aCurrObjRect.GetHeight( ) )
     660             :         {
     661         129 :             SwDoc* pDoc = const_cast<SwDoc*>(GetPageFrm()->GetFormat()->GetDoc());
     662         129 :             bool bModified = pDoc->getIDocumentState().IsModified();
     663         129 :             const_cast< SdrObject* >( GetDrawObj() )->Resize( aCurrObjRect.TopLeft(),
     664             :                     Fraction( nTargetWidth, aCurrObjRect.GetWidth() ),
     665         129 :                     Fraction( nTargetHeight, aCurrObjRect.GetHeight() ), false );
     666         129 :             if (!bModified)
     667         105 :                 pDoc->getIDocumentState().ResetModified();
     668             :         }
     669             :     }
     670        5527 :     return GetDrawObj()->GetCurrentBoundRect();
     671             : }
     672             : 
     673             : // --> #i68520#
     674        6444 : bool SwAnchoredDrawObject::_SetObjTop( const SwTwips _nTop )
     675             : {
     676        6444 :     SwTwips nDiff = _nTop - GetObjRect().Top();
     677        6444 :     DrawObj()->Move( Size( 0, nDiff ) );
     678             : 
     679        6444 :     return nDiff != 0;
     680             : }
     681        2232 : bool SwAnchoredDrawObject::_SetObjLeft( const SwTwips _nLeft )
     682             : {
     683        2232 :     SwTwips nDiff = _nLeft - GetObjRect().Left();
     684        2232 :     DrawObj()->Move( Size( nDiff, 0 ) );
     685             : 
     686        2232 :     return nDiff != 0;
     687             : }
     688             : 
     689             : /** adjust positioning and alignment attributes for new anchor frame
     690             : 
     691             :     #i33313# - add second optional parameter <_pNewObjRect>
     692             : */
     693           0 : void SwAnchoredDrawObject::AdjustPositioningAttr( const SwFrm* _pNewAnchorFrm,
     694             :                                                   const SwRect* _pNewObjRect )
     695             : {
     696           0 :     SwTwips nHoriRelPos = 0;
     697           0 :     SwTwips nVertRelPos = 0;
     698           0 :     const Point aAnchorPos = _pNewAnchorFrm->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
     699             :     // --> #i33313#
     700           0 :     const SwRect aObjRect( _pNewObjRect ? *_pNewObjRect : GetObjRect() );
     701           0 :     const bool bVert = _pNewAnchorFrm->IsVertical();
     702           0 :     const bool bR2L = _pNewAnchorFrm->IsRightToLeft();
     703           0 :     if ( bVert )
     704             :     {
     705           0 :         nHoriRelPos = aObjRect.Top() - aAnchorPos.Y();
     706           0 :         nVertRelPos = aAnchorPos.X() - aObjRect.Right();
     707             :     }
     708           0 :     else if ( bR2L )
     709             :     {
     710           0 :         nHoriRelPos = aAnchorPos.X() - aObjRect.Right();
     711           0 :         nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
     712             :     }
     713             :     else
     714             :     {
     715           0 :         nHoriRelPos = aObjRect.Left() - aAnchorPos.X();
     716           0 :         nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
     717             :     }
     718             : 
     719           0 :     GetFrameFormat().SetFormatAttr( SwFormatHoriOrient( nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
     720           0 :     GetFrameFormat().SetFormatAttr( SwFormatVertOrient( nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
     721           0 : }
     722             : 
     723             : // --> #i34748# - change return type.
     724             : // If member <mpLastObjRect> is NULL, create one.
     725        5347 : void SwAnchoredDrawObject::SetLastObjRect( const Rectangle& _rNewLastRect )
     726             : {
     727        5347 :     if ( !mpLastObjRect )
     728             :     {
     729        1790 :         mpLastObjRect = new Rectangle;
     730             :     }
     731        5347 :     *(mpLastObjRect) = _rNewLastRect;
     732        5347 : }
     733             : 
     734        2180 : void SwAnchoredDrawObject::ObjectAttachedToAnchorFrame()
     735             : {
     736             :     // --> #i31698#
     737        2180 :     SwAnchoredObject::ObjectAttachedToAnchorFrame();
     738             : 
     739        2180 :     if ( mbNotYetAttachedToAnchorFrame )
     740             :     {
     741        1809 :         mbNotYetAttachedToAnchorFrame = false;
     742             :     }
     743        2180 : }
     744             : 
     745             : /** method to set positioning attributes
     746             : 
     747             :     #i35798#
     748             :     During load the positioning attributes aren't set.
     749             :     Thus, the positioning attributes are set by the current object geometry.
     750             :     This method is also used for the conversion for drawing objects
     751             :     (not anchored as-character) imported from OpenOffice.org file format
     752             :     once and directly before the first positioning.
     753             : */
     754        1522 : void SwAnchoredDrawObject::_SetPositioningAttr()
     755             : {
     756             :     SwDrawContact* pDrawContact =
     757        1522 :                         static_cast<SwDrawContact*>(GetUserCall( GetDrawObj() ));
     758             : 
     759        1522 :     if ( !pDrawContact->ObjAnchoredAsChar() )
     760             :     {
     761        1036 :         SwRect aObjRect( GetObjRect() );
     762             : 
     763        1036 :         SwTwips nHoriPos = aObjRect.Left();
     764        1036 :         SwTwips nVertPos = aObjRect.Top();
     765             :         // #i44334#, #i44681#
     766             :         // perform conversion only if position is in horizontal-left-to-right-layout.
     767        1036 :         if ( GetFrameFormat().GetPositionLayoutDir() ==
     768             :                 text::PositionLayoutDir::PositionInHoriL2R )
     769             :         {
     770           3 :             SwFrameFormat::tLayoutDir eLayoutDir = GetFrameFormat().GetLayoutDir();
     771           3 :             switch ( eLayoutDir )
     772             :             {
     773             :                 case SwFrameFormat::HORI_L2R:
     774             :                 {
     775             :                     // nothing to do
     776             :                 }
     777           3 :                 break;
     778             :                 case SwFrameFormat::HORI_R2L:
     779             :                 {
     780           0 :                     nHoriPos = -aObjRect.Left() - aObjRect.Width();
     781             :                 }
     782           0 :                 break;
     783             :                 case SwFrameFormat::VERT_R2L:
     784             :                 {
     785           0 :                     nHoriPos = aObjRect.Top();
     786           0 :                     nVertPos = -aObjRect.Left() - aObjRect.Width();
     787             :                 }
     788           0 :                 break;
     789             :                 default:
     790             :                 {
     791             :                     OSL_FAIL( "<SwAnchoredDrawObject::_SetPositioningAttr()> - unsupported layout direction" );
     792             :                 }
     793             :             }
     794             :         }
     795             : 
     796             :         // --> #i71182#
     797             :         // only change position - do not lose other attributes
     798             : 
     799        1036 :         SwFormatHoriOrient aHori( GetFrameFormat().GetHoriOrient() );
     800        1036 :         if (nHoriPos != aHori.GetPos()) {
     801         894 :             aHori.SetPos( nHoriPos );
     802         894 :             InvalidateObjRectWithSpaces();
     803         894 :             GetFrameFormat().SetFormatAttr( aHori );
     804             :         }
     805             : 
     806        2072 :         SwFormatVertOrient aVert( GetFrameFormat().GetVertOrient() );
     807        1036 :         if (nVertPos != aVert.GetPos()) {
     808         908 :             aVert.SetPos( nVertPos );
     809         908 :             InvalidateObjRectWithSpaces();
     810         908 :             GetFrameFormat().SetFormatAttr( aVert );
     811             :         }
     812             : 
     813             :         // --> #i36010# - set layout direction of the position
     814        1036 :         GetFrameFormat().SetPositionLayoutDir(
     815        2072 :             text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
     816             :     }
     817             :     // --> #i65798# - also for as-character anchored objects
     818             :     // --> #i45952# - indicate that position
     819             :     // attributes are set now.
     820        1522 :     static_cast<SwDrawFrameFormat&>(GetFrameFormat()).PosAttrSet();
     821        1522 : }
     822             : 
     823        3356 : void SwAnchoredDrawObject::NotifyBackground( SwPageFrm* _pPageFrm,
     824             :                                              const SwRect& _rRect,
     825             :                                              PrepareHint _eHint )
     826             : {
     827        3356 :     ::Notify_Background( GetDrawObj(), _pPageFrm, _rRect, _eHint, true );
     828        3356 : }
     829             : 
     830             : /** method to assure that anchored object is registered at the correct
     831             :     page frame
     832             : 
     833             :     #i28701#
     834             : */
     835        2129 : void SwAnchoredDrawObject::RegisterAtCorrectPage()
     836             : {
     837        2129 :     SwPageFrm* pPageFrm( 0L );
     838        2129 :     if ( GetVertPosOrientFrm() )
     839             :     {
     840        2129 :         pPageFrm = const_cast<SwPageFrm*>(GetVertPosOrientFrm()->FindPageFrm());
     841             :     }
     842        2129 :     if ( pPageFrm && GetPageFrm() != pPageFrm )
     843             :     {
     844          12 :         if ( GetPageFrm() )
     845          12 :             GetPageFrm()->RemoveDrawObjFromPage( *this );
     846          12 :         pPageFrm->AppendDrawObjToPage( *this );
     847             :     }
     848        2306 : }
     849             : 
     850             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11