LCOV - code coverage report
Current view: top level - sw/source/core/text - txtfrm.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 994 1299 76.5 %
Date: 2015-06-13 12:38:46 Functions: 61 70 87.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 <hintids.hxx>
      21             : #include <hints.hxx>
      22             : #include <svl/ctloptions.hxx>
      23             : #include <sfx2/printer.hxx>
      24             : #include <sfx2/sfxuno.hxx>
      25             : #include <editeng/langitem.hxx>
      26             : #include <editeng/lspcitem.hxx>
      27             : #include <editeng/lrspitem.hxx>
      28             : #include <editeng/ulspitem.hxx>
      29             : #include <editeng/brushitem.hxx>
      30             : #include <editeng/pgrditem.hxx>
      31             : #include <swmodule.hxx>
      32             : #include <SwSmartTagMgr.hxx>
      33             : #include <doc.hxx>
      34             : #include <IDocumentSettingAccess.hxx>
      35             : #include <IDocumentDeviceAccess.hxx>
      36             : #include <IDocumentFieldsAccess.hxx>
      37             : #include "rootfrm.hxx"
      38             : #include <pagefrm.hxx>
      39             : #include <viewsh.hxx>
      40             : #include <pam.hxx>
      41             : #include <ndtxt.hxx>
      42             : #include <txtatr.hxx>
      43             : #include <paratr.hxx>
      44             : #include <viewopt.hxx>
      45             : #include <dflyobj.hxx>
      46             : #include <flyfrm.hxx>
      47             : #include <tabfrm.hxx>
      48             : #include <frmtool.hxx>
      49             : #include <pagedesc.hxx>
      50             : #include <tgrditem.hxx>
      51             : #include <dbg_lay.hxx>
      52             : #include <fmtfld.hxx>
      53             : #include <fmtftn.hxx>
      54             : #include <txtfld.hxx>
      55             : #include <txtftn.hxx>
      56             : #include <charatr.hxx>
      57             : #include <ftninfo.hxx>
      58             : #include <fmtline.hxx>
      59             : #include <txtfrm.hxx>
      60             : #include <sectfrm.hxx>
      61             : #include <itrform2.hxx>
      62             : #include <widorp.hxx>
      63             : #include <txtcache.hxx>
      64             : #include <fntcache.hxx>
      65             : #include <SwGrammarMarkUp.hxx>
      66             : #include <lineinfo.hxx>
      67             : #include <SwPortionHandler.hxx>
      68             : #include <dcontact.hxx>
      69             : #include <sortedobjs.hxx>
      70             : #include <txtflcnt.hxx>
      71             : #include <fmtflcnt.hxx>
      72             : #include <fmtcntnt.hxx>
      73             : #include <numrule.hxx>
      74             : #include <swtable.hxx>
      75             : #include <fldupde.hxx>
      76             : #include <IGrammarContact.hxx>
      77             : #include <calbck.hxx>
      78             : #include <ftnidx.hxx>
      79             : 
      80     2271551 : TYPEINIT1( SwTextFrm, SwContentFrm );
      81             : 
      82             : /// Switches width and height of the text frame
      83          92 : void SwTextFrm::SwapWidthAndHeight()
      84             : {
      85          92 :     if ( ! bIsSwapped )
      86             :     {
      87          46 :         const long nPrtOfstX = Prt().Pos().X();
      88          46 :         Prt().Pos().X() = Prt().Pos().Y();
      89          46 :         if( IsVertLR() )
      90           0 :             Prt().Pos().Y() = nPrtOfstX;
      91             :         else
      92          46 :             Prt().Pos().Y() = Frm().Width() - ( nPrtOfstX + Prt().Width() );
      93             : 
      94             :     }
      95             :     else
      96             :     {
      97          46 :         const long nPrtOfstY = Prt().Pos().Y();
      98          46 :         Prt().Pos().Y() = Prt().Pos().X();
      99          46 :         if( IsVertLR() )
     100           0 :             Prt().Pos().X() = nPrtOfstY;
     101             :         else
     102          46 :             Prt().Pos().X() = Frm().Height() - ( nPrtOfstY + Prt().Height() );
     103             :     }
     104             : 
     105          92 :     const long nFrmWidth = Frm().Width();
     106          92 :     Frm().Width( Frm().Height() );
     107          92 :     Frm().Height( nFrmWidth );
     108          92 :     const long nPrtWidth = Prt().Width();
     109          92 :     Prt().Width( Prt().Height() );
     110          92 :     Prt().Height( nPrtWidth );
     111             : 
     112          92 :     bIsSwapped = ! bIsSwapped;
     113          92 : }
     114             : 
     115             : /**
     116             :  * Calculates the coordinates of a rectangle when switching from
     117             :  * horizontal to vertical layout.
     118             :  */
     119           0 : void SwTextFrm::SwitchHorizontalToVertical( SwRect& rRect ) const
     120             : {
     121             :     // calc offset inside frame
     122             :     long nOfstX, nOfstY;
     123           0 :     if ( IsVertLR() )
     124             :     {
     125           0 :         nOfstX = rRect.Left() - Frm().Left();
     126           0 :         nOfstY = rRect.Top() - Frm().Top();
     127             :     }
     128             :     else
     129             :     {
     130           0 :         nOfstX = rRect.Left() - Frm().Left();
     131           0 :         nOfstY = rRect.Top() + rRect.Height() - Frm().Top();
     132             :     }
     133             : 
     134           0 :     const long nWidth = rRect.Width();
     135           0 :     const long nHeight = rRect.Height();
     136             : 
     137           0 :     if ( IsVertLR() )
     138           0 :         rRect.Left(Frm().Left() + nOfstY);
     139             :     else
     140             :     {
     141           0 :         if ( bIsSwapped )
     142           0 :             rRect.Left( Frm().Left() + Frm().Height() - nOfstY );
     143             :         else
     144             :             // frame is rotated
     145           0 :             rRect.Left( Frm().Left() + Frm().Width() - nOfstY );
     146             :     }
     147             : 
     148           0 :     rRect.Top( Frm().Top() + nOfstX );
     149           0 :     rRect.Width( nHeight );
     150           0 :     rRect.Height( nWidth );
     151           0 : }
     152             : 
     153             : /**
     154             :  * Calculates the coordinates of a point when switching from
     155             :  * horizontal to vertical layout.
     156             :  */
     157          27 : void SwTextFrm::SwitchHorizontalToVertical( Point& rPoint ) const
     158             : {
     159             :     // calc offset inside frame
     160          27 :     const long nOfstX = rPoint.X() - Frm().Left();
     161          27 :     const long nOfstY = rPoint.Y() - Frm().Top();
     162          27 :     if ( IsVertLR() )
     163           0 :         rPoint.X() = Frm().Left() + nOfstY;
     164             :     else
     165             :     {
     166          27 :         if ( bIsSwapped )
     167          27 :             rPoint.X() = Frm().Left() + Frm().Height() - nOfstY;
     168             :         else
     169             :             // calc rotated coords
     170           0 :             rPoint.X() = Frm().Left() + Frm().Width() - nOfstY;
     171             :     }
     172             : 
     173          27 :     rPoint.Y() = Frm().Top() + nOfstX;
     174          27 : }
     175             : 
     176             : /**
     177             :  * Calculates the a limit value when switching from
     178             :  * horizontal to vertical layout.
     179             :  */
     180           0 : long SwTextFrm::SwitchHorizontalToVertical( long nLimit ) const
     181             : {
     182           0 :     Point aTmp( 0, nLimit );
     183           0 :     SwitchHorizontalToVertical( aTmp );
     184           0 :     return aTmp.X();
     185             : }
     186             : 
     187             : /**
     188             :  * Calculates the coordinates of a rectangle when switching from
     189             :  * vertical to horizontal layout.
     190             :  */
     191           0 : void SwTextFrm::SwitchVerticalToHorizontal( SwRect& rRect ) const
     192             : {
     193             :     long nOfstX;
     194             : 
     195             :     // calc offset inside frame
     196           0 :     if ( IsVertLR() )
     197           0 :         nOfstX = rRect.Left() - Frm().Left();
     198             :     else
     199             :     {
     200           0 :         if ( bIsSwapped )
     201           0 :             nOfstX = Frm().Left() + Frm().Height() - ( rRect.Left() + rRect.Width() );
     202             :         else
     203           0 :             nOfstX = Frm().Left() + Frm().Width() - ( rRect.Left() + rRect.Width() );
     204             :     }
     205             : 
     206           0 :     const long nOfstY = rRect.Top() - Frm().Top();
     207           0 :     const long nWidth = rRect.Height();
     208           0 :     const long nHeight = rRect.Width();
     209             : 
     210             :     // calc rotated coords
     211           0 :     rRect.Left( Frm().Left() + nOfstY );
     212           0 :     rRect.Top( Frm().Top() + nOfstX );
     213           0 :     rRect.Width( nWidth );
     214           0 :     rRect.Height( nHeight );
     215           0 : }
     216             : 
     217             : /**
     218             :  * Calculates the coordinates of a point when switching from
     219             :  * vertical to horizontal layout.
     220             :  */
     221           0 : void SwTextFrm::SwitchVerticalToHorizontal( Point& rPoint ) const
     222             : {
     223             :     long nOfstX;
     224             : 
     225             :     // calc offset inside frame
     226           0 :     if ( IsVertLR() )
     227           0 :         nOfstX = rPoint.X() - Frm().Left();
     228             :     else
     229             :     {
     230           0 :         if ( bIsSwapped )
     231           0 :             nOfstX = Frm().Left() + Frm().Height() - rPoint.X();
     232             :         else
     233           0 :             nOfstX = Frm().Left() + Frm().Width() - rPoint.X();
     234             :     }
     235             : 
     236           0 :     const long nOfstY = rPoint.Y() - Frm().Top();
     237             : 
     238             :     // calc rotated coords
     239           0 :     rPoint.X() = Frm().Left() + nOfstY;
     240           0 :     rPoint.Y() = Frm().Top() + nOfstX;
     241           0 : }
     242             : 
     243             : /**
     244             :  * Calculates the a limit value when switching from
     245             :  * vertical to horizontal layout.
     246             :  */
     247           0 : long SwTextFrm::SwitchVerticalToHorizontal( long nLimit ) const
     248             : {
     249           0 :     Point aTmp( nLimit, 0 );
     250           0 :     SwitchVerticalToHorizontal( aTmp );
     251           0 :     return aTmp.Y();
     252             : }
     253             : 
     254      848071 : SwFrmSwapper::SwFrmSwapper( const SwTextFrm* pTextFrm, bool bSwapIfNotSwapped )
     255      848071 :     : pFrm( pTextFrm ), bUndo( false )
     256             : {
     257      848086 :     if ( pFrm->IsVertical() &&
     258          34 :         ( (   bSwapIfNotSwapped && ! pFrm->IsSwapped() ) ||
     259          38 :           ( ! bSwapIfNotSwapped && pFrm->IsSwapped() ) ) )
     260             :     {
     261          15 :         bUndo = true;
     262          15 :         const_cast<SwTextFrm*>(pFrm)->SwapWidthAndHeight();
     263             :     }
     264      848071 : }
     265             : 
     266      848071 : SwFrmSwapper::~SwFrmSwapper()
     267             : {
     268      848071 :     if ( bUndo )
     269          15 :         const_cast<SwTextFrm*>(pFrm)->SwapWidthAndHeight();
     270      848071 : }
     271             : 
     272         352 : void SwTextFrm::SwitchLTRtoRTL( SwRect& rRect ) const
     273             : {
     274         352 :     SWAP_IF_NOT_SWAPPED swap(const_cast<SwTextFrm *>(this));
     275             : 
     276         352 :     long nWidth = rRect.Width();
     277         704 :     rRect.Left( 2 * ( Frm().Left() + Prt().Left() ) +
     278         704 :                 Prt().Width() - rRect.Right() - 1 );
     279             : 
     280         352 :     rRect.Width( nWidth );
     281         352 : }
     282             : 
     283          78 : void SwTextFrm::SwitchLTRtoRTL( Point& rPoint ) const
     284             : {
     285          78 :     SWAP_IF_NOT_SWAPPED swap(const_cast<SwTextFrm *>(this));
     286             : 
     287          78 :     rPoint.X() = 2 * ( Frm().Left() + Prt().Left() ) + Prt().Width() - rPoint.X() - 1;
     288          78 : }
     289             : 
     290       24914 : SwLayoutModeModifier::SwLayoutModeModifier( const OutputDevice& rOutp ) :
     291       24914 :         rOut( rOutp ), nOldLayoutMode( rOutp.GetLayoutMode() )
     292             : {
     293       24914 : }
     294             : 
     295       24914 : SwLayoutModeModifier::~SwLayoutModeModifier()
     296             : {
     297       24914 :     const_cast<OutputDevice&>(rOut).SetLayoutMode( nOldLayoutMode );
     298       24914 : }
     299             : 
     300        2629 : void SwLayoutModeModifier::Modify( bool bChgToRTL )
     301             : {
     302             :     const_cast<OutputDevice&>(rOut).SetLayoutMode( bChgToRTL ?
     303             :                                          TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL :
     304        2629 :                                          TEXT_LAYOUT_BIDI_STRONG );
     305        2629 : }
     306             : 
     307       22804 : void SwLayoutModeModifier::SetAuto()
     308             : {
     309       22804 :     const ComplexTextLayoutMode nNewLayoutMode = nOldLayoutMode & ~TEXT_LAYOUT_BIDI_STRONG;
     310       22804 :     const_cast<OutputDevice&>(rOut).SetLayoutMode( nNewLayoutMode );
     311       22804 : }
     312             : 
     313      180058 : SwDigitModeModifier::SwDigitModeModifier( const OutputDevice& rOutp, LanguageType eCurLang ) :
     314      180058 :         rOut( rOutp ), nOldLanguageType( rOutp.GetDigitLanguage() )
     315             : {
     316      180058 :     LanguageType eLang = eCurLang;
     317      180058 :     const SvtCTLOptions::TextNumerals nTextNumerals = SW_MOD()->GetCTLOptions().GetCTLTextNumerals();
     318             : 
     319      180058 :     if ( SvtCTLOptions::NUMERALS_HINDI == nTextNumerals )
     320           0 :         eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
     321      180058 :     else if ( SvtCTLOptions::NUMERALS_ARABIC == nTextNumerals )
     322      180058 :         eLang = LANGUAGE_ENGLISH;
     323           0 :     else if ( SvtCTLOptions::NUMERALS_SYSTEM == nTextNumerals )
     324           0 :         eLang = ::GetAppLanguage();
     325             : 
     326      180058 :     const_cast<OutputDevice&>(rOut).SetDigitLanguage( eLang );
     327      180058 : }
     328             : 
     329      180058 : SwDigitModeModifier::~SwDigitModeModifier()
     330             : {
     331      180058 :     const_cast<OutputDevice&>(rOut).SetDigitLanguage( nOldLanguageType );
     332      180058 : }
     333             : 
     334       15371 : void SwTextFrm::Init()
     335             : {
     336             :     OSL_ENSURE( !IsLocked(), "+SwTextFrm::Init: this is locked." );
     337       15371 :     if( !IsLocked() )
     338             :     {
     339       15371 :         ClearPara();
     340       15371 :         ResetBlinkPor();
     341             :         // set flags directly to save a ResetPreps call,
     342             :         // and thereby an unnecessary GetPara call
     343             :         // don't set bOrphan, bLocked or bWait to false!
     344             :         // bOrphan = bFlag7 = bFlag8 = false;
     345             :     }
     346       15371 : }
     347             : 
     348       36977 : SwTextFrm::SwTextFrm(SwTextNode * const pNode, SwFrm* pSib )
     349             :     : SwContentFrm( pNode, pSib )
     350             :     , nAllLines( 0 )
     351             :     , nThisLines( 0 )
     352             :     , mnFlyAnchorOfst( 0 )
     353             :     , mnFlyAnchorOfstNoWrap( 0 )
     354             :     , mnFootnoteLine( 0 )
     355             :     , mnHeightOfLastLine( 0 ) // OD 2004-03-17 #i11860#
     356             :     , mnAdditionalFirstLineOffset( 0 )
     357             :     , nOfst( 0 )
     358             :     , nCacheIdx( USHRT_MAX )
     359             :     , bLocked( false )
     360             :     , bWidow( false )
     361             :     , bJustWidow( false )
     362             :     , bEmpty( false )
     363             :     , bInFootnoteConnect( false )
     364             :     , bFootnote( false )
     365             :     , bRepaint( false )
     366             :     , bBlinkPor( false )
     367             :     , bFieldFollow( false )
     368             :     , bHasAnimation( false )
     369             :     , bIsSwapped( false )
     370       36977 :     , mbFollowFormatAllowed( true ) // OD 14.03.2003 #i11760#
     371             : {
     372       36977 :     mnFrmType = FRM_TXT;
     373       36977 : }
     374             : 
     375       36151 : void SwTextFrm::DestroyImpl()
     376             : {
     377             :     // Remove associated SwParaPortion from pTextCache
     378       36151 :     ClearPara();
     379             : 
     380             :     const SwContentNode* pCNd;
     381      144604 :     if( 0 != ( pCNd = PTR_CAST( SwContentNode, GetRegisteredIn() )) &&
     382      144604 :         !pCNd->GetDoc()->IsInDtor() && HasFootnote() )
     383             :     {
     384          67 :         SwTextNode *pTextNd = static_cast<SwTextFrm*>(this)->GetTextNode();
     385          67 :         const SwFootnoteIdxs &rFootnoteIdxs = pCNd->GetDoc()->GetFootnoteIdxs();
     386          67 :         size_t nPos = 0;
     387          67 :         sal_uLong nIndex = pCNd->GetIndex();
     388          67 :         rFootnoteIdxs.SeekEntry( *pTextNd, &nPos );
     389          67 :         if( nPos < rFootnoteIdxs.size() )
     390             :         {
     391         148 :             while( nPos && pTextNd == &(rFootnoteIdxs[ nPos ]->GetTextNode()) )
     392          14 :                 --nPos;
     393          67 :             if( nPos || pTextNd != &(rFootnoteIdxs[ nPos ]->GetTextNode()) )
     394          13 :                 ++nPos;
     395             :         }
     396         209 :         while( nPos < rFootnoteIdxs.size() )
     397             :         {
     398          88 :             SwTextFootnote* pTextFootnote = rFootnoteIdxs[ nPos ];
     399          88 :             if( pTextFootnote->GetTextNode().GetIndex() > nIndex )
     400          13 :                 break;
     401          75 :             pTextFootnote->DelFrms( this );
     402          75 :             ++nPos;
     403             :         }
     404             :     }
     405             : 
     406       36151 :     SwContentFrm::DestroyImpl();
     407       36151 : }
     408             : 
     409       72302 : SwTextFrm::~SwTextFrm()
     410             : {
     411       72302 : }
     412             : 
     413      198023 : const OUString& SwTextFrm::GetText() const
     414             : {
     415      198023 :     return GetTextNode()->GetText();
     416             : }
     417             : 
     418       17180 : void SwTextFrm::ResetPreps()
     419             : {
     420       17180 :     if ( GetCacheIdx() != USHRT_MAX )
     421             :     {
     422             :         SwParaPortion *pPara;
     423       17180 :         if( 0 != (pPara = GetPara()) )
     424       17178 :             pPara->ResetPreps();
     425             :     }
     426       17180 : }
     427             : 
     428      578337 : bool SwTextFrm::IsHiddenNow() const
     429             : {
     430      578337 :     SwFrmSwapper aSwapper( this, true );
     431             : 
     432      578337 :     if( !Frm().Width() && IsValid() && GetUpper()->IsValid() ) // invalid when stack overflows (StackHack)!
     433             :     {
     434             : //        OSL_FAIL( "SwTextFrm::IsHiddenNow: thin frame" );
     435           2 :         return true;
     436             :     }
     437             : 
     438      578335 :     const bool bHiddenCharsHidePara = GetTextNode()->HasHiddenCharAttribute( true );
     439      578335 :     const bool bHiddenParaField = GetTextNode()->HasHiddenParaField();
     440      578335 :     const SwViewShell* pVsh = getRootFrm()->GetCurrShell();
     441             : 
     442      578335 :     if ( pVsh && ( bHiddenCharsHidePara || bHiddenParaField ) )
     443             :     {
     444        1004 :         if (
     445           0 :              ( bHiddenParaField &&
     446           0 :                ( !pVsh->GetViewOptions()->IsShowHiddenPara() &&
     447        3012 :                  !pVsh->GetViewOptions()->IsFieldName() ) ) ||
     448        1004 :              ( bHiddenCharsHidePara &&
     449        1004 :                !pVsh->GetViewOptions()->IsShowHiddenChar() ) )
     450             :         {
     451        1004 :             return true;
     452             :         }
     453             :     }
     454             : 
     455      577331 :     return false;
     456             : }
     457             : 
     458             : /// Removes Textfrm's attachments, when it's hidden
     459          22 : void SwTextFrm::HideHidden()
     460             : {
     461             :     OSL_ENSURE( !GetFollow() && IsHiddenNow(),
     462             :             "HideHidden on visible frame of hidden frame has follow" );
     463             : 
     464          22 :     const sal_Int32 nEnd = COMPLETE_STRING;
     465          22 :     HideFootnotes( GetOfst(), nEnd );
     466             :     // OD 2004-01-15 #110582#
     467          22 :     HideAndShowObjects();
     468             : 
     469             :     // format information is obsolete
     470          22 :     ClearPara();
     471          22 : }
     472             : 
     473          26 : void SwTextFrm::HideFootnotes( sal_Int32 nStart, sal_Int32 nEnd )
     474             : {
     475          26 :     const SwpHints *pHints = GetTextNode()->GetpSwpHints();
     476          26 :     if( pHints )
     477             :     {
     478          26 :         const size_t nSize = pHints->Count();
     479          26 :         SwPageFrm *pPage = 0;
     480          75 :         for ( size_t i = 0; i < nSize; ++i )
     481             :         {
     482          49 :             const SwTextAttr *pHt = (*pHints)[i];
     483          49 :             if ( pHt->Which() == RES_TXTATR_FTN )
     484             :             {
     485           0 :                 const sal_Int32 nIdx = pHt->GetStart();
     486           0 :                 if ( nEnd < nIdx )
     487           0 :                     break;
     488           0 :                 if( nStart <= nIdx )
     489             :                 {
     490           0 :                     if( !pPage )
     491           0 :                         pPage = FindPageFrm();
     492           0 :                     pPage->RemoveFootnote( this, static_cast<const SwTextFootnote*>(pHt) );
     493             :                 }
     494             :             }
     495             :         }
     496             :     }
     497          26 : }
     498             : 
     499             : /**
     500             :  * #120729# - hotfix
     501             :  * as-character anchored graphics, which are used for a graphic bullet list.
     502             :  * As long as these graphic bullet list aren't imported, do not hide a
     503             :  * at-character anchored object, if
     504             :  * (a) the document is an imported WW8 document -
     505             :  *     checked by checking certain compatibility options -
     506             :  * (b) the paragraph is the last content in the document and
     507             :  * (c) the anchor character is an as-character anchored graphic.
     508             :  */
     509           0 : bool sw_HideObj( const SwTextFrm& _rFrm,
     510             :                   const RndStdIds _eAnchorType,
     511             :                   const sal_Int32 _nObjAnchorPos,
     512             :                   SwAnchoredObject* _pAnchoredObj )
     513             : {
     514           0 :     bool bRet( true );
     515             : 
     516           0 :     if (_eAnchorType == FLY_AT_CHAR)
     517             :     {
     518           0 :         const IDocumentSettingAccess* pIDSA = _rFrm.GetTextNode()->getIDocumentSettingAccess();
     519           0 :         if ( !pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) &&
     520           0 :              !pIDSA->get(DocumentSettingId::OLD_LINE_SPACING) &&
     521           0 :              !pIDSA->get(DocumentSettingId::USE_FORMER_OBJECT_POS) &&
     522           0 :               pIDSA->get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) &&
     523           0 :              _rFrm.IsInDocBody() && !_rFrm.FindNextCnt() )
     524             :         {
     525           0 :             const OUString &rStr = _rFrm.GetTextNode()->GetText();
     526           0 :             const sal_Unicode cAnchorChar = _nObjAnchorPos < rStr.getLength() ? rStr[_nObjAnchorPos] : 0;
     527           0 :             if (cAnchorChar == CH_TXTATR_BREAKWORD)
     528             :             {
     529             :                 const SwTextAttr* const pHint(
     530             :                     _rFrm.GetTextNode()->GetTextAttrForCharAt(_nObjAnchorPos,
     531           0 :                         RES_TXTATR_FLYCNT) );
     532           0 :                 if ( pHint )
     533             :                 {
     534             :                     const SwFrameFormat* pFrameFormat =
     535           0 :                         static_cast<const SwTextFlyCnt*>(pHint)->GetFlyCnt().GetFrameFormat();
     536           0 :                     if ( pFrameFormat->Which() == RES_FLYFRMFMT )
     537             :                     {
     538           0 :                         SwNodeIndex nContentIndex = *(pFrameFormat->GetContent().GetContentIdx());
     539           0 :                         ++nContentIndex;
     540           0 :                         if ( nContentIndex.GetNode().IsNoTextNode() )
     541             :                         {
     542           0 :                             bRet = false;
     543             :                             // set needed data structure values for object positioning
     544           0 :                             SWRECTFN( (&_rFrm) );
     545           0 :                             SwRect aLastCharRect( _rFrm.Frm() );
     546           0 :                             (aLastCharRect.*fnRect->fnSetWidth)( 1 );
     547           0 :                             _pAnchoredObj->maLastCharRect = aLastCharRect;
     548           0 :                             _pAnchoredObj->mnLastTopOfLine = (aLastCharRect.*fnRect->fnGetTop)();
     549           0 :                         }
     550             :                     }
     551             :                 }
     552             :             }
     553             :         }
     554             :     }
     555             : 
     556           0 :     return bRet;
     557             : }
     558             : 
     559             : /**
     560             :  * Hide/show objects
     561             :  * OD 2004-01-15 #110582#
     562             :  *
     563             :  * Method hides respectively shows objects, which are anchored at paragraph,
     564             :  * at/as a character of the paragraph, corresponding to the paragraph and
     565             :  * paragraph portion visibility.
     566             :  *
     567             :  * - is called from HideHidden() - should hide objects in hidden paragraphs and
     568             :  * - from _Format() - should hide/show objects in partly visible paragraphs
     569             :  */
     570       67440 : void SwTextFrm::HideAndShowObjects()
     571             : {
     572       67440 :     if ( GetDrawObjs() )
     573             :     {
     574        6703 :         if ( IsHiddenNow() )
     575             :         {
     576             :             // complete paragraph is hidden. Thus, hide all objects
     577           0 :             for ( size_t i = 0; i < GetDrawObjs()->size(); ++i )
     578             :             {
     579           0 :                 SdrObject* pObj = (*GetDrawObjs())[i]->DrawObj();
     580           0 :                 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
     581             :                 // #120729# - hotfix
     582             :                 // under certain conditions
     583           0 :                 const RndStdIds eAnchorType( pContact->GetAnchorId() );
     584           0 :                 const sal_Int32 nObjAnchorPos = pContact->GetContentAnchorIndex().GetIndex();
     585           0 :                 if ((eAnchorType != FLY_AT_CHAR) ||
     586             :                     sw_HideObj( *this, eAnchorType, nObjAnchorPos,
     587           0 :                                  (*GetDrawObjs())[i] ))
     588             :                 {
     589           0 :                     pContact->MoveObjToInvisibleLayer( pObj );
     590             :                 }
     591             :             }
     592             :         }
     593             :         else
     594             :         {
     595             :             // paragraph is visible, but can contain hidden text portion.
     596             :             // first we check if objects are allowed to be hidden:
     597        6703 :             const SwTextNode& rNode = *GetTextNode();
     598        6703 :             const SwViewShell* pVsh = getRootFrm()->GetCurrShell();
     599       13406 :             const bool bShouldBeHidden = !pVsh || !pVsh->GetWin() ||
     600       13406 :                                          !pVsh->GetViewOptions()->IsShowHiddenChar();
     601             : 
     602             :             // Thus, show all objects, which are anchored at paragraph and
     603             :             // hide/show objects, which are anchored at/as character, according
     604             :             // to the visibility of the anchor character.
     605       65395 :             for ( size_t i = 0; i < GetDrawObjs()->size(); ++i )
     606             :             {
     607       58692 :                 SdrObject* pObj = (*GetDrawObjs())[i]->DrawObj();
     608       58692 :                 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
     609             :                 // #120729# - determine anchor type only once
     610       58692 :                 const RndStdIds eAnchorType( pContact->GetAnchorId() );
     611             : 
     612       58692 :                 if (eAnchorType == FLY_AT_PARA)
     613             :                 {
     614       55522 :                     pContact->MoveObjToVisibleLayer( pObj );
     615             :                 }
     616        3170 :                 else if ((eAnchorType == FLY_AT_CHAR) ||
     617             :                          (eAnchorType == FLY_AS_CHAR))
     618             :                 {
     619             :                     sal_Int32 nHiddenStart;
     620             :                     sal_Int32 nHiddenEnd;
     621        3170 :                     const sal_Int32 nObjAnchorPos = pContact->GetContentAnchorIndex().GetIndex();
     622        3170 :                     SwScriptInfo::GetBoundsOfHiddenRange( rNode, nObjAnchorPos, nHiddenStart, nHiddenEnd, 0 );
     623             :                     // #120729# - hotfix
     624             :                     // under certain conditions
     625        3170 :                     if ( nHiddenStart != COMPLETE_STRING && bShouldBeHidden &&
     626           0 :                          sw_HideObj( *this, eAnchorType, nObjAnchorPos, (*GetDrawObjs())[i] ) )
     627           0 :                         pContact->MoveObjToInvisibleLayer( pObj );
     628             :                     else
     629        3170 :                         pContact->MoveObjToVisibleLayer( pObj );
     630             :                 }
     631             :                 else
     632             :                 {
     633             :                     OSL_FAIL( "<SwTextFrm::HideAndShowObjects()> - object not anchored at/inside paragraph!?" );
     634             :                 }
     635             :             }
     636             :         }
     637             :     }
     638             : 
     639       67440 :     if (IsFollow())
     640             :     {
     641        3966 :         SwTextFrm *pMaster = FindMaster();
     642             :         OSL_ENSURE(pMaster, "SwTextFrm without master");
     643        3966 :         if (pMaster)
     644        3966 :             pMaster->HideAndShowObjects();
     645             :     }
     646       67440 : }
     647             : 
     648             : /**
     649             :  * Returns the first possible break point in the current line.
     650             :  * This method is used in SwTextFrm::Format() to decide whether the previous
     651             :  * line has to be formatted as well.
     652             :  * nFound is <= nEndLine.
     653             :  */
     654        1506 : sal_Int32 SwTextFrm::FindBrk( const OUString &rText,
     655             :                               const sal_Int32 nStart,
     656             :                               const sal_Int32 nEnd )
     657             : {
     658        1506 :     sal_Int32 nFound = nStart;
     659        1506 :     const sal_Int32 nEndLine = std::min( nEnd, rText.getLength() - 1 );
     660             : 
     661             :     // skip all leading blanks (see bug #2235).
     662        3015 :     while( nFound <= nEndLine && ' ' == rText[nFound] )
     663             :     {
     664           3 :          nFound++;
     665             :     }
     666             : 
     667             :     // A tricky situation with the TextAttr-Dummy-character (in this case "$"):
     668             :     // "Dr.$Meyer" at the beginning of the second line. Typing a blank after that
     669             :     // doesn't result in the word moving into first line, even though that would work.
     670             :     // For this reason we don't skip the dummy char.
     671       37677 :     while( nFound <= nEndLine && ' ' != rText[nFound] )
     672             :     {
     673       34665 :         nFound++;
     674             :     }
     675             : 
     676        1506 :     return nFound;
     677             : }
     678             : 
     679       21149 : bool SwTextFrm::IsIdxInside( const sal_Int32 nPos, const sal_Int32 nLen ) const
     680             : {
     681       21149 :     if( nLen != COMPLETE_STRING && GetOfst() > nPos + nLen ) // the range preceded us
     682         205 :         return false;
     683             : 
     684       20944 :     if( !GetFollow() ) // the range doesn't precede us,
     685       19938 :         return true; // nobody follows us.
     686             : 
     687        1006 :     const sal_Int32 nMax = GetFollow()->GetOfst();
     688             : 
     689             :     // either the range overlap or our text has been deleted
     690        1006 :     if( nMax > nPos || nMax > GetText().getLength() )
     691         285 :         return true;
     692             : 
     693             :     // changes made in the first line of a follow can modify the master
     694         721 :     const SwParaPortion* pPara = GetFollow()->GetPara();
     695         721 :     return pPara && ( nPos <= nMax + pPara->GetLen() );
     696             : }
     697             : 
     698        6668 : inline void SwTextFrm::InvalidateRange(const SwCharRange &aRange, const long nD)
     699             : {
     700        6668 :     if ( IsIdxInside( aRange.Start(), aRange.Len() ) )
     701        6644 :         _InvalidateRange( aRange, nD );
     702        6668 : }
     703             : 
     704       19600 : void SwTextFrm::_InvalidateRange( const SwCharRange &aRange, const long nD)
     705             : {
     706       19600 :     if ( !HasPara() )
     707        7893 :     {   InvalidateSize();
     708       27493 :         return;
     709             :     }
     710             : 
     711       11707 :     SetWidow( false );
     712       11707 :     SwParaPortion *pPara = GetPara();
     713             : 
     714       11707 :     bool bInv = false;
     715       11707 :     if( 0 != nD )
     716             :     {
     717             :         // In nDelta the differences between old and new
     718             :         // linelengths are being added, that's why it's negative
     719             :         // if chars have been added and positive, if chars have
     720             :         // deleted
     721        6758 :         pPara->GetDelta() += nD;
     722        6758 :         bInv = true;
     723             :     }
     724       11707 :     SwCharRange &rReformat = pPara->GetReformat();
     725       11707 :     if(aRange != rReformat) {
     726        9678 :         if( COMPLETE_STRING == rReformat.Len() )
     727           0 :             rReformat = aRange;
     728             :         else
     729        9678 :             rReformat += aRange;
     730        9678 :         bInv = true;
     731             :     }
     732       11707 :     if(bInv)
     733             :     {
     734        9800 :         InvalidateSize();
     735             :     }
     736             : }
     737             : 
     738          69 : void SwTextFrm::CalcLineSpace()
     739             : {
     740             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
     741             :             "SwTextFrm::CalcLineSpace with swapped frame!" );
     742             : 
     743          69 :     if( IsLocked() || !HasPara() )
     744         134 :         return;
     745             : 
     746             :     SwParaPortion *pPara;
     747           6 :     if( GetDrawObjs() ||
     748           6 :         GetTextNode()->GetSwAttrSet().GetLRSpace().IsAutoFirst() ||
     749           2 :         ( pPara = GetPara() )->IsFixLineHeight() )
     750             :     {
     751           0 :         Init();
     752           0 :         return;
     753             :     }
     754             : 
     755           2 :     Size aNewSize( Prt().SSize() );
     756             : 
     757           2 :     SwTextFormatInfo aInf( this );
     758           4 :     SwTextFormatter aLine( this, &aInf );
     759           2 :     if( aLine.GetDropLines() )
     760             :     {
     761           0 :         Init();
     762           0 :         return;
     763             :     }
     764             : 
     765           2 :     aLine.Top();
     766           2 :     aLine.RecalcRealHeight();
     767             : 
     768           2 :     aNewSize.Height() = (aLine.Y() - Frm().Top()) + aLine.GetLineHeight();
     769             : 
     770           2 :     SwTwips nDelta = aNewSize.Height() - Prt().Height();
     771             :     // Underflow with free-flying frames
     772           2 :     if( aInf.GetTextFly().IsOn() )
     773             :     {
     774           0 :         SwRect aTmpFrm( Frm() );
     775           0 :         if( nDelta < 0 )
     776           0 :             aTmpFrm.Height( Prt().Height() );
     777             :         else
     778           0 :             aTmpFrm.Height( aNewSize.Height() );
     779           0 :         if( aInf.GetTextFly().Relax( aTmpFrm ) )
     780             :         {
     781           0 :             Init();
     782           0 :             return;
     783             :         }
     784             :     }
     785             : 
     786           2 :     if( nDelta )
     787             :     {
     788           0 :         SwTextFrmBreak aBreak( this );
     789           0 :         if( GetFollow() || aBreak.IsBreakNow( aLine ) )
     790             :         {
     791             :             // if there is a Follow() or if we need to break here, reformat
     792           0 :             Init();
     793             :         }
     794             :         else
     795             :         {
     796             :             // everything is business as usual...
     797           0 :             pPara->SetPrepAdjust();
     798           0 :             pPara->SetPrep();
     799             :         }
     800           2 :     }
     801             : }
     802             : 
     803       13155 : static void lcl_SetWrong( SwTextFrm& rFrm, sal_Int32 nPos, sal_Int32 nCnt, bool bMove )
     804             : {
     805       13155 :     if ( !rFrm.IsFollow() )
     806             :     {
     807       12239 :         SwTextNode* pTextNode = rFrm.GetTextNode();
     808       12239 :         IGrammarContact* pGrammarContact = getGrammarContact( *pTextNode );
     809             :         SwGrammarMarkUp* pWrongGrammar = pGrammarContact ?
     810       12239 :             pGrammarContact->getGrammarCheck( *pTextNode, false ) :
     811       24478 :             pTextNode->GetGrammarCheck();
     812       12239 :         bool bGrammarProxy = pWrongGrammar != pTextNode->GetGrammarCheck();
     813       12239 :         if( bMove )
     814             :         {
     815        9485 :             if( pTextNode->GetWrong() )
     816         268 :                 pTextNode->GetWrong()->Move( nPos, nCnt );
     817        9485 :             if( pWrongGrammar )
     818           0 :                 pWrongGrammar->MoveGrammar( nPos, nCnt );
     819        9485 :             if( bGrammarProxy && pTextNode->GetGrammarCheck() )
     820           0 :                 pTextNode->GetGrammarCheck()->MoveGrammar( nPos, nCnt );
     821        9485 :             if( pTextNode->GetSmartTags() )
     822           0 :                 pTextNode->GetSmartTags()->Move( nPos, nCnt );
     823             :         }
     824             :         else
     825             :         {
     826        2754 :             if( pTextNode->GetWrong() )
     827          67 :                 pTextNode->GetWrong()->Invalidate( nPos, nCnt );
     828        2754 :             if( pWrongGrammar )
     829           0 :                 pWrongGrammar->Invalidate( nPos, nCnt );
     830        2754 :             if( pTextNode->GetSmartTags() )
     831           0 :                 pTextNode->GetSmartTags()->Invalidate( nPos, nCnt );
     832             :         }
     833       12239 :         const sal_Int32 nEnd = nPos + (nCnt > 0 ? nCnt : 1 );
     834       12239 :         if ( !pTextNode->GetWrong() && !pTextNode->IsWrongDirty() )
     835             :         {
     836        4071 :             pTextNode->SetWrong( new SwWrongList( WRONGLIST_SPELL ) );
     837        4071 :             pTextNode->GetWrong()->SetInvalid( nPos, nEnd );
     838             :         }
     839       12239 :         if ( !pTextNode->GetSmartTags() && !pTextNode->IsSmartTagDirty() )
     840             :         {
     841           0 :             pTextNode->SetSmartTags( new SwWrongList( WRONGLIST_SMARTTAG ) );
     842           0 :             pTextNode->GetSmartTags()->SetInvalid( nPos, nEnd );
     843             :         }
     844       12239 :         pTextNode->SetWrongDirty( true );
     845       12239 :         pTextNode->SetGrammarCheckDirty( true );
     846       12239 :         pTextNode->SetWordCountDirty( true );
     847       12239 :         pTextNode->SetAutoCompleteWordDirty( true );
     848       12239 :         pTextNode->SetSmartTagDirty( true );
     849             :     }
     850             : 
     851       13155 :     SwRootFrm *pRootFrm = rFrm.getRootFrm();
     852       13155 :     if (pRootFrm)
     853             :     {
     854       13155 :         pRootFrm->SetNeedGrammarCheck( true );
     855             :     }
     856             : 
     857       13155 :     SwPageFrm *pPage = rFrm.FindPageFrm();
     858       13155 :     if( pPage )
     859             :     {
     860       13155 :         pPage->InvalidateSpelling();
     861       13155 :         pPage->InvalidateAutoCompleteWords();
     862       13155 :         pPage->InvalidateWordCount();
     863       13155 :         pPage->InvalidateSmartTags();
     864             :     }
     865       13155 : }
     866             : 
     867       14339 : static void lcl_SetScriptInval( SwTextFrm& rFrm, sal_Int32 nPos )
     868             : {
     869       14339 :     if( rFrm.GetPara() )
     870        5419 :         rFrm.GetPara()->GetScriptInfo().SetInvalidityA( nPos );
     871       14339 : }
     872             : 
     873         916 : static void lcl_ModifyOfst( SwTextFrm* pFrm, sal_Int32 nPos, sal_Int32 nLen )
     874             : {
     875        3574 :     while( pFrm && pFrm->GetOfst() <= nPos )
     876        1742 :         pFrm = pFrm->GetFollow();
     877        2293 :     while( pFrm )
     878             :     {
     879         461 :         if (nLen == COMPLETE_STRING)
     880          21 :             pFrm->ManipOfst( pFrm->GetTextNode()->GetText().getLength() );
     881             :         else
     882         440 :             pFrm->ManipOfst( pFrm->GetOfst() + nLen );
     883         461 :         pFrm = pFrm->GetFollow();
     884             :     }
     885         916 : }
     886             : 
     887             : /**
     888             :  * Related: fdo#56031 filter out attribute changes that don't matter for
     889             :  * humans/a11y to stop flooding the destination mortal with useless noise
     890             :  */
     891        7515 : static bool isA11yRelevantAttribute(sal_uInt16 nWhich)
     892             : {
     893        7515 :     return nWhich != RES_CHRATR_RSID;
     894             : }
     895             : 
     896        3036 : static bool hasA11yRelevantAttribute( const std::vector<sal_uInt16>& nWhich )
     897             : {
     898        9108 :     for( std::vector<sal_uInt16>::const_iterator nItr = nWhich.begin();
     899        6072 :             nItr < nWhich.end(); ++nItr )
     900           0 :         if ( isA11yRelevantAttribute( *nItr ) )
     901           0 :             return true;
     902             : 
     903        3036 :     return false;
     904             : }
     905             : 
     906       22038 : void SwTextFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
     907             : {
     908       22038 :     const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
     909             : 
     910             :     // modifications concerning frame attributes are processed by the base class
     911       22038 :     if( IsInRange( aFrameFormatSetRange, nWhich ) || RES_FMT_CHG == nWhich )
     912             :     {
     913        2137 :         SwContentFrm::Modify( pOld, pNew );
     914        2137 :         if( nWhich == RES_FMT_CHG && getRootFrm()->GetCurrShell() )
     915             :         {
     916             :             // collection has changed
     917         262 :             Prepare( PREP_CLEAR );
     918         262 :             _InvalidatePrt();
     919         262 :             lcl_SetWrong( *this, 0, COMPLETE_STRING, false );
     920         262 :             SetDerivedR2L( false );
     921         262 :             CheckDirChange();
     922             :             // OD 09.12.2002 #105576# - Force complete paint due to existing
     923             :             // indents.
     924         262 :             SetCompletePaint();
     925         262 :             InvalidateLineNum();
     926             :         }
     927        2137 :         return;
     928             :     }
     929             : 
     930             :     // while locked ignore all modifications
     931       19901 :     if( IsLocked() )
     932           0 :         return;
     933             : 
     934             :     // save stack
     935             :     // warning: one has to ensure that all variables are set
     936             :     sal_Int32 nPos;
     937             :     sal_Int32 nLen;
     938       19901 :     bool bSetFieldsDirty = false;
     939       19901 :     bool bRecalcFootnoteFlag = false;
     940             : 
     941       19901 :     switch( nWhich )
     942             :     {
     943             :         case RES_LINENUMBER:
     944             :         {
     945           0 :             InvalidateLineNum();
     946             :         }
     947           0 :         break;
     948             :         case RES_INS_TXT:
     949             :         {
     950        9170 :             nPos = static_cast<const SwInsText*>(pNew)->nPos;
     951        9170 :             nLen = static_cast<const SwInsText*>(pNew)->nLen;
     952        9170 :             if( IsIdxInside( nPos, nLen ) )
     953             :             {
     954        8684 :                 if( !nLen )
     955             :                 {
     956             :                     // Refresh NumPortions even when line is empty!
     957           0 :                     if( nPos )
     958           0 :                         InvalidateSize();
     959             :                     else
     960           0 :                         Prepare( PREP_CLEAR );
     961             :                 }
     962             :                 else
     963        8684 :                     _InvalidateRange( SwCharRange( nPos, nLen ), nLen );
     964             :             }
     965        9170 :             lcl_SetWrong( *this, nPos, nLen, true );
     966        9170 :             lcl_SetScriptInval( *this, nPos );
     967        9170 :             bSetFieldsDirty = true;
     968        9170 :             if( HasFollow() )
     969         499 :                 lcl_ModifyOfst( this, nPos, nLen );
     970             :         }
     971        9170 :         break;
     972             :         case RES_DEL_CHR:
     973             :         {
     974         234 :             nPos = static_cast<const SwDelChr*>(pNew)->nPos;
     975         234 :             InvalidateRange( SwCharRange( nPos, 1 ), -1 );
     976         234 :             lcl_SetWrong( *this, nPos, -1, true );
     977         234 :             lcl_SetScriptInval( *this, nPos );
     978         234 :             bSetFieldsDirty = bRecalcFootnoteFlag = true;
     979         234 :             if( HasFollow() )
     980          23 :                 lcl_ModifyOfst( this, nPos, COMPLETE_STRING );
     981             :         }
     982         234 :         break;
     983             :         case RES_DEL_TXT:
     984             :         {
     985         997 :             nPos = static_cast<const SwDelText*>(pNew)->nStart;
     986         997 :             nLen = static_cast<const SwDelText*>(pNew)->nLen;
     987         997 :             const sal_Int32 m = -nLen;
     988         997 :             if( IsIdxInside( nPos, nLen ) )
     989             :             {
     990         608 :                 if( !nLen )
     991          26 :                     InvalidateSize();
     992             :                 else
     993         582 :                     InvalidateRange( SwCharRange( nPos, 1 ), m );
     994             :             }
     995         997 :             lcl_SetWrong( *this, nPos, m, true );
     996         997 :             lcl_SetScriptInval( *this, nPos );
     997         997 :             bSetFieldsDirty = bRecalcFootnoteFlag = true;
     998         997 :             if( HasFollow() )
     999         394 :                 lcl_ModifyOfst( this, nPos, nLen );
    1000             :         }
    1001         997 :         break;
    1002             :         case RES_UPDATE_ATTR:
    1003             :         {
    1004        3036 :             nPos = static_cast<const SwUpdateAttr*>(pNew)->getStart();
    1005        3036 :             nLen = static_cast<const SwUpdateAttr*>(pNew)->getEnd() - nPos;
    1006        3036 :             if( IsIdxInside( nPos, nLen ) )
    1007             :             {
    1008             :                 // We need to reformat anyways, even if the invalidated
    1009             :                 // area is NULL.
    1010             :                 // E.g.: empty line, set 14 pt!
    1011             :                 // if( !nLen ) nLen = 1;
    1012             : 
    1013             :                 // FootnoteNummbers need to be formatted
    1014        3036 :                 if( !nLen )
    1015         747 :                     nLen = 1;
    1016             : 
    1017        3036 :                 _InvalidateRange( SwCharRange( nPos, nLen) );
    1018        3036 :                 const sal_uInt16 nTmp = static_cast<const SwUpdateAttr*>(pNew)->getWhichAttr();
    1019             : 
    1020        3036 :                 if( ! nTmp || RES_TXTATR_CHARFMT == nTmp || RES_TXTATR_AUTOFMT == nTmp ||
    1021         814 :                     RES_FMT_CHG == nTmp || RES_ATTRSET_CHG == nTmp )
    1022             :                 {
    1023        2355 :                     lcl_SetWrong( *this, nPos, nPos + nLen, false );
    1024        2355 :                     lcl_SetScriptInval( *this, nPos );
    1025             :                 }
    1026             :             }
    1027             : 
    1028        6072 :             if( isA11yRelevantAttribute( static_cast<const SwUpdateAttr*>(pNew)->getWhichAttr() ) &&
    1029        3036 :                     hasA11yRelevantAttribute( static_cast<const SwUpdateAttr*>(pNew)->getFormatAttr() ) )
    1030             :             {
    1031             :                 // #i104008#
    1032           0 :                 SwViewShell* pViewSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
    1033           0 :                 if ( pViewSh  )
    1034             :                 {
    1035           0 :                     pViewSh->InvalidateAccessibleParaAttrs( *this );
    1036             :                 }
    1037             :             }
    1038             :         }
    1039        3036 :         break;
    1040             :         case RES_OBJECTDYING:
    1041           0 :         break;
    1042             : 
    1043             :         case RES_PARATR_LINESPACING:
    1044             :             {
    1045           0 :                 CalcLineSpace();
    1046           0 :                 InvalidateSize();
    1047           0 :                 _InvalidatePrt();
    1048           0 :                 if( IsInSct() && !GetPrev() )
    1049             :                 {
    1050           0 :                     SwSectionFrm *pSect = FindSctFrm();
    1051           0 :                     if( pSect->ContainsAny() == this )
    1052           0 :                         pSect->InvalidatePrt();
    1053             :                 }
    1054             : 
    1055             :                 // OD 09.01.2004 #i11859# - correction:
    1056             :                 //  (1) Also invalidate next frame on next page/column.
    1057             :                 //  (2) Skip empty sections and hidden paragraphs
    1058             :                 //  Thus, use method <InvalidateNextPrtArea()>
    1059           0 :                 InvalidateNextPrtArea();
    1060             : 
    1061           0 :                 SetCompletePaint();
    1062             :             }
    1063           0 :             break;
    1064             : 
    1065             :         case RES_TXTATR_FIELD:
    1066             :         case RES_TXTATR_ANNOTATION:
    1067             :             {
    1068        1225 :                 nPos = static_cast<const SwFormatField*>(pNew)->GetTextField()->GetStart();
    1069        1225 :                 if( IsIdxInside( nPos, 1 ) )
    1070             :                 {
    1071        1225 :                     if( pNew == pOld )
    1072             :                     {
    1073             :                         // only repaint
    1074             :                         // opt: invalidate window?
    1075           0 :                         InvalidatePage();
    1076           0 :                         SetCompletePaint();
    1077             :                     }
    1078             :                     else
    1079        1225 :                         _InvalidateRange( SwCharRange( nPos, 1 ) );
    1080             :                 }
    1081        1225 :                 bSetFieldsDirty = true;
    1082             :                 // ST2
    1083        1225 :                 if ( SwSmartTagMgr::Get().IsSmartTagsEnabled() )
    1084           0 :                     lcl_SetWrong( *this, nPos, nPos + 1, false );
    1085             :             }
    1086        1225 :             break;
    1087             : 
    1088             :         case RES_TXTATR_FTN :
    1089             :         {
    1090          77 :             nPos = static_cast<const SwFormatFootnote*>(pNew)->GetTextFootnote()->GetStart();
    1091          77 :             if( IsInFootnote() || IsIdxInside( nPos, 1 ) )
    1092          77 :                 Prepare( PREP_FTN, static_cast<const SwFormatFootnote*>(pNew)->GetTextFootnote() );
    1093          77 :             break;
    1094             :         }
    1095             : 
    1096             :         case RES_ATTRSET_CHG:
    1097             :         {
    1098        4479 :             InvalidateLineNum();
    1099             : 
    1100        4479 :             const SwAttrSet& rNewSet = *static_cast<const SwAttrSetChg*>(pNew)->GetChgSet();
    1101        4479 :             const SfxPoolItem* pItem = 0;
    1102        4479 :             int nClear = 0;
    1103        4479 :             sal_uInt16 nCount = rNewSet.Count();
    1104             : 
    1105        4479 :             if( SfxItemState::SET == rNewSet.GetItemState( RES_TXTATR_FTN, false, &pItem ))
    1106             :             {
    1107           0 :                 nPos = static_cast<const SwFormatFootnote*>(pItem)->GetTextFootnote()->GetStart();
    1108           0 :                 if( IsIdxInside( nPos, 1 ) )
    1109           0 :                     Prepare( PREP_FTN, pNew );
    1110           0 :                 nClear = 0x01;
    1111           0 :                 --nCount;
    1112             :             }
    1113             : 
    1114        4479 :             if( SfxItemState::SET == rNewSet.GetItemState( RES_TXTATR_FIELD, false, &pItem ))
    1115             :             {
    1116           0 :                 nPos = static_cast<const SwFormatField*>(pItem)->GetTextField()->GetStart();
    1117           0 :                 if( IsIdxInside( nPos, 1 ) )
    1118             :                 {
    1119             :                     const SfxPoolItem* pOldItem = pOld ?
    1120           0 :                         &(static_cast<const SwAttrSetChg*>(pOld)->GetChgSet()->Get(RES_TXTATR_FIELD)) : NULL;
    1121           0 :                     if( pItem == pOldItem )
    1122             :                     {
    1123           0 :                         InvalidatePage();
    1124           0 :                         SetCompletePaint();
    1125             :                     }
    1126             :                     else
    1127           0 :                         _InvalidateRange( SwCharRange( nPos, 1 ) );
    1128             :                 }
    1129           0 :                 nClear |= 0x02;
    1130           0 :                 --nCount;
    1131             :             }
    1132             :             bool bLineSpace = SfxItemState::SET == rNewSet.GetItemState(
    1133        4479 :                                             RES_PARATR_LINESPACING, false ),
    1134             :                      bRegister  = SfxItemState::SET == rNewSet.GetItemState(
    1135        4479 :                                             RES_PARATR_REGISTER, false );
    1136        4479 :             if ( bLineSpace || bRegister )
    1137             :             {
    1138          69 :                 Prepare( bRegister ? PREP_REGISTER : PREP_ADJUST_FRM );
    1139          69 :                 CalcLineSpace();
    1140          69 :                 InvalidateSize();
    1141          69 :                 _InvalidatePrt();
    1142             : 
    1143             :                 // OD 09.01.2004 #i11859# - correction:
    1144             :                 //  (1) Also invalidate next frame on next page/column.
    1145             :                 //  (2) Skip empty sections and hidden paragraphs
    1146             :                 //  Thus, use method <InvalidateNextPrtArea()>
    1147          69 :                 InvalidateNextPrtArea();
    1148             : 
    1149          69 :                 SetCompletePaint();
    1150          69 :                 nClear |= 0x04;
    1151          69 :                 if ( bLineSpace )
    1152             :                 {
    1153          69 :                     --nCount;
    1154          69 :                     if( IsInSct() && !GetPrev() )
    1155             :                     {
    1156           0 :                         SwSectionFrm *pSect = FindSctFrm();
    1157           0 :                         if( pSect->ContainsAny() == this )
    1158           0 :                             pSect->InvalidatePrt();
    1159             :                     }
    1160             :                 }
    1161          69 :                 if ( bRegister )
    1162           0 :                     --nCount;
    1163             :             }
    1164        4479 :             if ( SfxItemState::SET == rNewSet.GetItemState( RES_PARATR_SPLIT,
    1165        4479 :                                                        false ))
    1166             :             {
    1167           0 :                 if ( GetPrev() )
    1168           0 :                     CheckKeep();
    1169           0 :                 Prepare( PREP_CLEAR );
    1170           0 :                 InvalidateSize();
    1171           0 :                 nClear |= 0x08;
    1172           0 :                 --nCount;
    1173             :             }
    1174             : 
    1175        8958 :             if( SfxItemState::SET == rNewSet.GetItemState( RES_BACKGROUND, false)
    1176        4479 :                 && !IsFollow() && GetDrawObjs() )
    1177             :             {
    1178           0 :                 SwSortedObjs *pObjs = GetDrawObjs();
    1179           0 :                 for ( size_t i = 0; GetDrawObjs() && i < pObjs->size(); ++i )
    1180             :                 {
    1181           0 :                     SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
    1182           0 :                     if ( pAnchoredObj->ISA(SwFlyFrm) )
    1183             :                     {
    1184           0 :                         SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
    1185           0 :                         if( !pFly->IsFlyInCntFrm() )
    1186             :                         {
    1187             :                             const SvxBrushItem &rBack =
    1188           0 :                                 pFly->GetAttrSet()->GetBackground();
    1189             :                             // OD 20.08.2002 #99657# #GetTransChg#
    1190             :                             //     following condition determines, if the fly frame
    1191             :                             //     "inherites" the background color of text frame.
    1192             :                             //     This is the case, if fly frame background
    1193             :                             //     color is "no fill"/"auto fill" and if the fly frame
    1194             :                             //     has no background graphic.
    1195             :                             //     Thus, check complete fly frame background
    1196             :                             //     color and *not* only its transparency value
    1197           0 :                             if ( (rBack.GetColor() == COL_TRANSPARENT)  &&
    1198           0 :                                 rBack.GetGraphicPos() == GPOS_NONE )
    1199             :                             {
    1200           0 :                                 pFly->SetCompletePaint();
    1201           0 :                                 pFly->InvalidatePage();
    1202             :                             }
    1203             :                         }
    1204             :                     }
    1205             :                 }
    1206             :             }
    1207             : 
    1208        4479 :             if ( SfxItemState::SET ==
    1209        4479 :                  rNewSet.GetItemState( RES_TXTATR_CHARFMT, false ) )
    1210             :             {
    1211           0 :                 lcl_SetWrong( *this, 0, COMPLETE_STRING, false );
    1212           0 :                 lcl_SetScriptInval( *this, 0 );
    1213             :             }
    1214        4479 :             else if ( SfxItemState::SET ==
    1215        8872 :                       rNewSet.GetItemState( RES_CHRATR_LANGUAGE, false ) ||
    1216             :                       SfxItemState::SET ==
    1217        8843 :                       rNewSet.GetItemState( RES_CHRATR_CJK_LANGUAGE, false ) ||
    1218             :                       SfxItemState::SET ==
    1219        4364 :                       rNewSet.GetItemState( RES_CHRATR_CTL_LANGUAGE, false ) )
    1220         137 :                 lcl_SetWrong( *this, 0, COMPLETE_STRING, false );
    1221        4342 :             else if ( SfxItemState::SET ==
    1222        7323 :                       rNewSet.GetItemState( RES_CHRATR_FONT, false ) ||
    1223             :                       SfxItemState::SET ==
    1224        7211 :                       rNewSet.GetItemState( RES_CHRATR_CJK_FONT, false ) ||
    1225             :                       SfxItemState::SET ==
    1226        2869 :                       rNewSet.GetItemState( RES_CHRATR_CTL_FONT, false ) )
    1227        1583 :                 lcl_SetScriptInval( *this, 0 );
    1228        2759 :             else if ( SfxItemState::SET ==
    1229        2759 :                       rNewSet.GetItemState( RES_FRAMEDIR, false ) )
    1230             :             {
    1231         182 :                 SetDerivedR2L( false );
    1232         182 :                 CheckDirChange();
    1233             :                 // OD 09.12.2002 #105576# - Force complete paint due to existing
    1234             :                 // indents.
    1235         182 :                 SetCompletePaint();
    1236             :             }
    1237             : 
    1238        4479 :             if( nCount )
    1239             :             {
    1240        4479 :                 if( getRootFrm()->GetCurrShell() )
    1241             :                 {
    1242        4479 :                     Prepare( PREP_CLEAR );
    1243        4479 :                     _InvalidatePrt();
    1244             :                 }
    1245             : 
    1246        4479 :                 if( nClear )
    1247             :                 {
    1248          69 :                     SwAttrSetChg aOldSet( *static_cast<const SwAttrSetChg*>(pOld) );
    1249         138 :                     SwAttrSetChg aNewSet( *static_cast<const SwAttrSetChg*>(pNew) );
    1250             : 
    1251          69 :                     if( 0x01 & nClear )
    1252             :                     {
    1253           0 :                         aOldSet.ClearItem( RES_TXTATR_FTN );
    1254           0 :                         aNewSet.ClearItem( RES_TXTATR_FTN );
    1255             :                     }
    1256          69 :                     if( 0x02 & nClear )
    1257             :                     {
    1258           0 :                         aOldSet.ClearItem( RES_TXTATR_FIELD );
    1259           0 :                         aNewSet.ClearItem( RES_TXTATR_FIELD );
    1260             :                     }
    1261          69 :                     if ( 0x04 & nClear )
    1262             :                     {
    1263          69 :                         if ( bLineSpace )
    1264             :                         {
    1265          69 :                             aOldSet.ClearItem( RES_PARATR_LINESPACING );
    1266          69 :                             aNewSet.ClearItem( RES_PARATR_LINESPACING );
    1267             :                         }
    1268          69 :                         if ( bRegister )
    1269             :                         {
    1270           0 :                             aOldSet.ClearItem( RES_PARATR_REGISTER );
    1271           0 :                             aNewSet.ClearItem( RES_PARATR_REGISTER );
    1272             :                         }
    1273             :                     }
    1274          69 :                     if ( 0x08 & nClear )
    1275             :                     {
    1276           0 :                         aOldSet.ClearItem( RES_PARATR_SPLIT );
    1277           0 :                         aNewSet.ClearItem( RES_PARATR_SPLIT );
    1278             :                     }
    1279         138 :                     SwContentFrm::Modify( &aOldSet, &aNewSet );
    1280             :                 }
    1281             :                 else
    1282        4410 :                     SwContentFrm::Modify( pOld, pNew );
    1283             :             }
    1284             : 
    1285        4479 :             if (isA11yRelevantAttribute(nWhich))
    1286             :             {
    1287             :                 // #i88069#
    1288        4479 :                 SwViewShell* pViewSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
    1289        4479 :                 if ( pViewSh  )
    1290             :                 {
    1291        4479 :                     pViewSh->InvalidateAccessibleParaAttrs( *this );
    1292             :                 }
    1293             :             }
    1294             :         }
    1295        4479 :         break;
    1296             : 
    1297             :         // Process SwDocPosUpdate
    1298             :         case RES_DOCPOS_UPDATE:
    1299             :         {
    1300         678 :             if( pOld && pNew )
    1301             :             {
    1302         678 :                 const SwDocPosUpdate *pDocPos = static_cast<const SwDocPosUpdate*>(pOld);
    1303         678 :                 if( pDocPos->nDocPos <= maFrm.Top() )
    1304             :                 {
    1305         648 :                     const SwFormatField *pField = static_cast<const SwFormatField *>(pNew);
    1306             :                     InvalidateRange(
    1307         648 :                         SwCharRange( pField->GetTextField()->GetStart(), 1 ) );
    1308             :                 }
    1309             :             }
    1310         678 :             break;
    1311             :         }
    1312             :         case RES_PARATR_SPLIT:
    1313           0 :             if ( GetPrev() )
    1314           0 :                 CheckKeep();
    1315           0 :             Prepare( PREP_CLEAR );
    1316           0 :             bSetFieldsDirty = true;
    1317           0 :             break;
    1318             :         case RES_FRAMEDIR :
    1319           0 :             SetDerivedR2L( false );
    1320           0 :             CheckDirChange();
    1321           0 :             break;
    1322             :         default:
    1323             :         {
    1324           5 :             Prepare( PREP_CLEAR );
    1325           5 :             _InvalidatePrt();
    1326           5 :             if ( !nWhich )
    1327             :             {
    1328             :                 // is called by e. g. HiddenPara with 0
    1329             :                 SwFrm *pNxt;
    1330           0 :                 if ( 0 != (pNxt = FindNext()) )
    1331           0 :                     pNxt->InvalidatePrt();
    1332             :             }
    1333             :         }
    1334             :     } // switch
    1335             : 
    1336       19901 :     if( bSetFieldsDirty )
    1337       11626 :         GetNode()->getIDocumentFieldsAccess()->SetFieldsDirty( true, GetNode(), 1 );
    1338             : 
    1339       19901 :     if ( bRecalcFootnoteFlag )
    1340        1231 :         CalcFootnoteFlag();
    1341             : }
    1342             : 
    1343        1197 : bool SwTextFrm::GetInfo( SfxPoolItem &rHint ) const
    1344             : {
    1345        1197 :     if ( RES_VIRTPAGENUM_INFO == rHint.Which() && IsInDocBody() && ! IsFollow() )
    1346             :     {
    1347        1197 :         SwVirtPageNumInfo &rInfo = static_cast<SwVirtPageNumInfo&>(rHint);
    1348        1197 :         const SwPageFrm *pPage = FindPageFrm();
    1349        1197 :         if ( pPage )
    1350             :         {
    1351        1197 :             if ( pPage == rInfo.GetOrigPage() && !GetPrev() )
    1352             :             {
    1353             :                 // this should be the one
    1354             :                 // (could only differ temporarily; is that disturbing?)
    1355         220 :                 rInfo.SetInfo( pPage, this );
    1356         220 :                 return false;
    1357             :             }
    1358        2477 :             if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() &&
    1359         750 :                  (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum()))
    1360             :             {
    1361             :                 // this could be the one
    1362         750 :                 rInfo.SetInfo( pPage, this );
    1363             :             }
    1364             :         }
    1365             :     }
    1366         977 :     return true;
    1367             : }
    1368             : 
    1369         170 : void SwTextFrm::PrepWidows( const sal_uInt16 nNeed, bool bNotify )
    1370             : {
    1371             :     OSL_ENSURE(GetFollow() && nNeed, "+SwTextFrm::Prepare: lost all friends");
    1372             : 
    1373         170 :     SwParaPortion *pPara = GetPara();
    1374         170 :     if ( !pPara )
    1375         170 :         return;
    1376         170 :     pPara->SetPrepWidows();
    1377             : 
    1378         170 :     sal_uInt16 nHave = nNeed;
    1379             : 
    1380             :     // We yield a few lines and shrink in CalcPreps()
    1381         170 :     SWAP_IF_NOT_SWAPPED swap( this );
    1382             : 
    1383         340 :     SwTextSizeInfo aInf( this );
    1384         340 :     SwTextMargin aLine( this, &aInf );
    1385         170 :     aLine.Bottom();
    1386         170 :     sal_Int32 nTmpLen = aLine.GetCurr()->GetLen();
    1387         484 :     while( nHave && aLine.PrevLine() )
    1388             :     {
    1389         144 :         if( nTmpLen )
    1390         144 :             --nHave;
    1391         144 :         nTmpLen = aLine.GetCurr()->GetLen();
    1392             :     }
    1393             : 
    1394             :     // If it's certain that we can yield lines, the Master needs
    1395             :     // to check the widow rule
    1396         170 :     if( !nHave )
    1397             :     {
    1398         144 :         bool bSplit = true;
    1399         144 :         if( !IsFollow() ) // only a master decides about orphans
    1400             :         {
    1401         138 :             const WidowsAndOrphans aWidOrp( this );
    1402         158 :             bSplit = ( aLine.GetLineNr() >= aWidOrp.GetOrphansLines() &&
    1403         158 :                        aLine.GetLineNr() >= aLine.GetDropLines() );
    1404             :         }
    1405             : 
    1406         144 :         if( bSplit )
    1407             :         {
    1408          26 :             GetFollow()->SetOfst( aLine.GetEnd() );
    1409          26 :             aLine.TruncLines( true );
    1410          26 :             if( pPara->IsFollowField() )
    1411           0 :                 GetFollow()->SetFieldFollow( true );
    1412             :         }
    1413             :     }
    1414         170 :     if ( bNotify )
    1415             :     {
    1416         170 :         _InvalidateSize();
    1417         170 :         InvalidatePage();
    1418         170 :     }
    1419             : }
    1420             : 
    1421         129 : static bool lcl_ErgoVadis( SwTextFrm* pFrm, sal_Int32 &rPos, const PrepareHint ePrep )
    1422             : {
    1423         129 :     const SwFootnoteInfo &rFootnoteInfo = pFrm->GetNode()->GetDoc()->GetFootnoteInfo();
    1424         129 :     if( ePrep == PREP_ERGOSUM )
    1425             :     {
    1426          52 :         if( rFootnoteInfo.aErgoSum.isEmpty() )
    1427          52 :             return false;
    1428           0 :         rPos = pFrm->GetOfst();
    1429             :     }
    1430             :     else
    1431             :     {
    1432          77 :         if( rFootnoteInfo.aQuoVadis.isEmpty() )
    1433          77 :             return false;
    1434           0 :         if( pFrm->HasFollow() )
    1435           0 :             rPos = pFrm->GetFollow()->GetOfst();
    1436             :         else
    1437           0 :             rPos = pFrm->GetText().getLength();
    1438           0 :         if( rPos )
    1439           0 :             --rPos; // our last character
    1440             :     }
    1441           0 :     return true;
    1442             : }
    1443             : 
    1444      192049 : bool SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid,
    1445             :                         bool bNotify )
    1446             : {
    1447      192049 :     bool bParaPossiblyInvalid = false;
    1448             : 
    1449      192049 :     SwFrmSwapper aSwapper( this, false );
    1450             : 
    1451             : #if OSL_DEBUG_LEVEL > 1
    1452             :     const SwTwips nDbgY = Frm().Top();
    1453             :     (void)nDbgY;
    1454             : #endif
    1455             : 
    1456      192049 :     if ( IsEmpty() )
    1457             :     {
    1458       16029 :         switch ( ePrep )
    1459             :         {
    1460             :             case PREP_BOSS_CHGD:
    1461        2060 :                 SetInvalidVert( true ); // Test
    1462             :             case PREP_WIDOWS_ORPHANS:
    1463             :             case PREP_WIDOWS:
    1464        2184 :             case PREP_FTN_GONE :    return bParaPossiblyInvalid;
    1465             : 
    1466             :             case PREP_POS_CHGD :
    1467             :             {
    1468             :                 // We also need an InvalidateSize for Areas (with and without columns),
    1469             :                 // so that we format and bUndersized is set (if needed)
    1470        4717 :                 if( IsInFly() || IsInSct() )
    1471             :                 {
    1472         476 :                     SwTwips nTmpBottom = GetUpper()->Frm().Top() +
    1473         476 :                         GetUpper()->Prt().Bottom();
    1474         476 :                     if( nTmpBottom < Frm().Bottom() )
    1475         449 :                         break;
    1476             :                 }
    1477             :                 // Are there any free-flying frames on this page?
    1478        4568 :                 SwTextFly aTextFly( this );
    1479        4568 :                 if( aTextFly.IsOn() )
    1480             :                 {
    1481             :                     // Does any free-flying frame overlap?
    1482         735 :                     if ( aTextFly.Relax() || IsUndersized() )
    1483         130 :                         break;
    1484             :                 }
    1485        4438 :                 if( GetTextNode()->GetSwAttrSet().GetRegister().GetValue())
    1486           0 :                     break;
    1487             : 
    1488        4438 :                 SwTextGridItem const*const pGrid(GetGridItem(FindPageFrm()));
    1489        4438 :                 if ( pGrid && GetTextNode()->GetSwAttrSet().GetParaGrid().GetValue() )
    1490           0 :                     break;
    1491             : 
    1492             :                 // #i28701# - consider anchored objects
    1493        4438 :                 if ( GetDrawObjs() )
    1494          21 :                     break;
    1495             : 
    1496        4417 :                 return bParaPossiblyInvalid;
    1497             :             }
    1498             :             default:
    1499        9128 :                 break;
    1500             :         }
    1501             :     }
    1502             : 
    1503      185448 :     if( !HasPara() && PREP_MUST_FIT != ePrep )
    1504             :     {
    1505      145444 :         SetInvalidVert( true ); // Test
    1506             :         OSL_ENSURE( !IsLocked(), "SwTextFrm::Prepare: three of a perfect pair" );
    1507      145444 :         if ( bNotify )
    1508      106344 :             InvalidateSize();
    1509             :         else
    1510       39100 :             _InvalidateSize();
    1511      145444 :         return bParaPossiblyInvalid;
    1512             :     }
    1513             : 
    1514             :     // Get object from cache while locking
    1515       40004 :     SwTextLineAccess aAccess( this );
    1516       40004 :     SwParaPortion *pPara = aAccess.GetPara();
    1517             : 
    1518       40004 :     switch( ePrep )
    1519             :     {
    1520          10 :         case PREP_MOVEFTN :     Frm().Height(0);
    1521          10 :                                 Prt().Height(0);
    1522          10 :                                 _InvalidatePrt();
    1523          10 :                                 _InvalidateSize();
    1524             :                                 /* no break here */
    1525        9530 :         case PREP_ADJUST_FRM :  pPara->SetPrepAdjust();
    1526       19057 :                                 if( IsFootnoteNumFrm() != pPara->IsFootnoteNum() ||
    1527        9527 :                                     IsUndersized() )
    1528             :                                 {
    1529        2272 :                                     InvalidateRange( SwCharRange( 0, 1 ), 1);
    1530        2272 :                                     if( GetOfst() && !IsFollow() )
    1531           0 :                                         _SetOfst( 0 );
    1532             :                                 }
    1533        9530 :                                 break;
    1534         221 :         case PREP_MUST_FIT :        pPara->SetPrepMustFit();
    1535             :                                 /* no break here */
    1536        1418 :         case PREP_WIDOWS_ORPHANS :  pPara->SetPrepAdjust();
    1537        1418 :                                     break;
    1538             : 
    1539             :         case PREP_WIDOWS :
    1540             :             // MustFit is stronger than anything else
    1541         170 :             if( pPara->IsPrepMustFit() )
    1542           0 :                 return bParaPossiblyInvalid;
    1543             :             // see comment in WidowsAndOrphans::FindOrphans and CalcPreps()
    1544         170 :             PrepWidows( *static_cast<const sal_uInt16 *>(pVoid), bNotify );
    1545         170 :             break;
    1546             : 
    1547             :         case PREP_FTN :
    1548             :         {
    1549         137 :             SwTextFootnote const *pFootnote = static_cast<SwTextFootnote const *>(pVoid);
    1550         137 :             if( IsInFootnote() )
    1551             :             {
    1552             :                 // Am I the first TextFrm of a footnote?
    1553          31 :                 if( !GetPrev() )
    1554             :                     // So we're a TextFrm of the footnote, which has
    1555             :                     // to display the footnote number or the ErgoSum text
    1556          27 :                     InvalidateRange( SwCharRange( 0, 1 ), 1);
    1557             : 
    1558          31 :                 if( !GetNext() )
    1559             :                 {
    1560             :                     // We're the last Footnote; we need to update the
    1561             :                     // QuoVadis texts now
    1562          27 :                     const SwFootnoteInfo &rFootnoteInfo = GetNode()->GetDoc()->GetFootnoteInfo();
    1563          27 :                     if( !pPara->UpdateQuoVadis( rFootnoteInfo.aQuoVadis ) )
    1564             :                     {
    1565          27 :                         sal_Int32 nPos = pPara->GetParLen();
    1566          27 :                         if( nPos )
    1567           6 :                             --nPos;
    1568          27 :                         InvalidateRange( SwCharRange( nPos, 1 ), 1);
    1569             :                     }
    1570             :                 }
    1571             :             }
    1572             :             else
    1573             :             {
    1574             :                 // We are the TextFrm _with_ the footnote
    1575         106 :                 const sal_Int32 nPos = pFootnote->GetStart();
    1576         106 :                 InvalidateRange( SwCharRange( nPos, 1 ), 1);
    1577             :             }
    1578         137 :             break;
    1579             :         }
    1580             :         case PREP_BOSS_CHGD :
    1581             :         {
    1582             :             // Test
    1583             :             {
    1584        4459 :                 SetInvalidVert( false );
    1585        4459 :                 bool bOld = IsVertical();
    1586        4459 :                 SetInvalidVert( true );
    1587        4459 :                 if( bOld != IsVertical() )
    1588           0 :                     InvalidateRange( SwCharRange( GetOfst(), COMPLETE_STRING ) );
    1589             :             }
    1590             : 
    1591        4459 :             if( HasFollow() )
    1592             :             {
    1593          24 :                 sal_Int32 nNxtOfst = GetFollow()->GetOfst();
    1594          24 :                 if( nNxtOfst )
    1595          24 :                     --nNxtOfst;
    1596          24 :                 InvalidateRange( SwCharRange( nNxtOfst, 1 ), 1);
    1597             :             }
    1598        4459 :             if( IsInFootnote() )
    1599             :             {
    1600             :                 sal_Int32 nPos;
    1601          25 :                 if( lcl_ErgoVadis( this, nPos, PREP_QUOVADIS ) )
    1602           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1603          25 :                 if( lcl_ErgoVadis( this, nPos, PREP_ERGOSUM ) )
    1604           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1605             :             }
    1606             :             // If we have a page number field, we must invalidate those spots
    1607        4459 :             SwpHints *pHints = GetTextNode()->GetpSwpHints();
    1608        4459 :             if( pHints )
    1609             :             {
    1610        3163 :                 const size_t nSize = pHints->Count();
    1611        3163 :                 const sal_Int32 nEnd = GetFollow() ?
    1612        3163 :                                     GetFollow()->GetOfst() : COMPLETE_STRING;
    1613       11764 :                 for ( size_t i = 0; i < nSize; ++i )
    1614             :                 {
    1615        8615 :                     const SwTextAttr *pHt = (*pHints)[i];
    1616        8615 :                     const sal_Int32 nStart = pHt->GetStart();
    1617        8615 :                     if( nStart >= GetOfst() )
    1618             :                     {
    1619        8615 :                         if( nStart >= nEnd )
    1620          14 :                             break;
    1621             : 
    1622             :                 // If we're flowing back and own a Footnote, the Footnote also flows
    1623             :                 // with us. So that it doesn't obstruct us, we send ourselves
    1624             :                 // a ADJUST_FRM.
    1625             :                 // pVoid != 0 means MoveBwd()
    1626        8601 :                         const sal_uInt16 nWhich = pHt->Which();
    1627       17204 :                         if( RES_TXTATR_FIELD == nWhich ||
    1628        8589 :                             (HasFootnote() && pVoid && RES_TXTATR_FTN == nWhich))
    1629          17 :                         InvalidateRange( SwCharRange( nStart, 1 ), 1 );
    1630             :                     }
    1631             :                 }
    1632             :             }
    1633             :             // A new boss, a new chance for growing
    1634        4459 :             if( IsUndersized() )
    1635             :             {
    1636         179 :                 _InvalidateSize();
    1637         179 :                 InvalidateRange( SwCharRange( GetOfst(), 1 ), 1);
    1638             :             }
    1639        4459 :             break;
    1640             :         }
    1641             : 
    1642             :         case PREP_POS_CHGD :
    1643             :         {
    1644        9947 :             if ( GetValidPrtAreaFlag() )
    1645             :             {
    1646        9512 :                 SwTextGridItem const*const pGrid(GetGridItem(FindPageFrm()));
    1647        9512 :                 if ( pGrid && GetTextNode()->GetSwAttrSet().GetParaGrid().GetValue() )
    1648           0 :                     InvalidatePrt();
    1649             :             }
    1650             : 
    1651             :             // If we don't overlap with anybody:
    1652             :             // did any free-flying frame overlapped _before_ the position change?
    1653        9947 :             bool bFormat = pPara->HasFly();
    1654        9947 :             if( !bFormat )
    1655             :             {
    1656        9861 :                 if( IsInFly() )
    1657             :                 {
    1658         293 :                     SwTwips nTmpBottom = GetUpper()->Frm().Top() +
    1659         293 :                         GetUpper()->Prt().Bottom();
    1660         293 :                     if( nTmpBottom < Frm().Bottom() )
    1661           2 :                         bFormat = true;
    1662             :                 }
    1663        9861 :                 if( !bFormat )
    1664             :                 {
    1665        9859 :                     if ( GetDrawObjs() )
    1666             :                     {
    1667         230 :                         const size_t nCnt = GetDrawObjs()->size();
    1668         564 :                         for ( size_t i = 0; i < nCnt; ++i )
    1669             :                         {
    1670         357 :                             SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
    1671             :                             // #i28701# - consider all
    1672             :                             // to-character anchored objects
    1673         357 :                             if ( pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId()
    1674             :                                     == FLY_AT_CHAR )
    1675             :                             {
    1676          23 :                                 bFormat = true;
    1677          23 :                                 break;
    1678             :                             }
    1679             :                         }
    1680             :                     }
    1681        9859 :                     if( !bFormat )
    1682             :                     {
    1683             :                         // Are there any free-flying frames on this page?
    1684        9836 :                         SwTextFly aTextFly( this );
    1685        9836 :                         if( aTextFly.IsOn() )
    1686             :                         {
    1687             :                             // Does any free-flying frame overlap?
    1688        3039 :                             bFormat = aTextFly.Relax() || IsUndersized();
    1689        9836 :                         }
    1690             :                     }
    1691             :                 }
    1692             :             }
    1693             : 
    1694        9947 :             if( bFormat )
    1695             :             {
    1696        1971 :                 if( !IsLocked() )
    1697             :                 {
    1698        1971 :                     if( pPara->GetRepaint().HasArea() )
    1699        1971 :                         SetCompletePaint();
    1700        1971 :                     Init();
    1701        1971 :                     pPara = 0;
    1702        1971 :                     _InvalidateSize();
    1703             :                 }
    1704             :             }
    1705             :             else
    1706             :             {
    1707        7976 :                 if( GetTextNode()->GetSwAttrSet().GetRegister().GetValue() )
    1708           0 :                     bParaPossiblyInvalid = Prepare( PREP_REGISTER, 0, bNotify );
    1709             :                 // The Frames need to be readjusted, which caused by changes
    1710             :                 // in position
    1711        7976 :                 else if( HasFootnote() )
    1712             :                 {
    1713           5 :                     bParaPossiblyInvalid = Prepare( PREP_ADJUST_FRM, 0, bNotify );
    1714           5 :                     _InvalidateSize();
    1715             :                 }
    1716             :                 else
    1717        7971 :                     return bParaPossiblyInvalid; // So that there's no SetPrep()
    1718             : 
    1719           5 :                 if (bParaPossiblyInvalid)
    1720             :                 {
    1721             :                     // It's possible that pPara was deleted above; retrieve it again
    1722           0 :                     pPara = aAccess.GetPara();
    1723             :                 }
    1724             : 
    1725             :             }
    1726        1976 :             break;
    1727             :         }
    1728             :         case PREP_REGISTER:
    1729           0 :             if( GetTextNode()->GetSwAttrSet().GetRegister().GetValue() )
    1730             :             {
    1731           0 :                 pPara->SetPrepAdjust();
    1732           0 :                 CalcLineSpace();
    1733             : 
    1734             :                 // It's possible that pPara was deleted above; retrieve it again
    1735           0 :                 bParaPossiblyInvalid = true;
    1736           0 :                 pPara = aAccess.GetPara();
    1737             : 
    1738           0 :                 InvalidateSize();
    1739           0 :                 _InvalidatePrt();
    1740             :                 SwFrm* pNxt;
    1741           0 :                 if ( 0 != ( pNxt = GetIndNext() ) )
    1742             :                 {
    1743           0 :                     pNxt->_InvalidatePrt();
    1744           0 :                     if ( pNxt->IsLayoutFrm() )
    1745           0 :                         pNxt->InvalidatePage();
    1746             :                 }
    1747           0 :                 SetCompletePaint();
    1748             :             }
    1749           0 :             break;
    1750             :         case PREP_FTN_GONE :
    1751             :             {
    1752             :                 // If a Follow is calling us, because a footnote is being deleted, our last
    1753             :                 // line has to be formatted, so that the first line of the Follow can flow up.
    1754             :                 // Which had flowed to the next page to be together with the footnote (this is
    1755             :                 // especially true for areas with columns)
    1756             :                 OSL_ENSURE( GetFollow(), "PREP_FTN_GONE darf nur vom Follow gerufen werden" );
    1757           0 :                 sal_Int32 nPos = GetFollow()->GetOfst();
    1758           0 :                 if( IsFollow() && GetOfst() == nPos )       // If we don't have a mass of text, we call our
    1759           0 :                     FindMaster()->Prepare( PREP_FTN_GONE ); // Master's Prepare
    1760           0 :                 if( nPos )
    1761           0 :                     --nPos; // The char preceding our Follow
    1762           0 :                 InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1763           0 :                 return bParaPossiblyInvalid;
    1764             :             }
    1765             :         case PREP_ERGOSUM:
    1766             :         case PREP_QUOVADIS:
    1767             :             {
    1768             :                 sal_Int32 nPos;
    1769          79 :                 if( lcl_ErgoVadis( this, nPos, ePrep ) )
    1770           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1771             :             }
    1772          79 :             break;
    1773             :         case PREP_FLY_ATTR_CHG:
    1774             :         {
    1775         158 :             if( pVoid )
    1776             :             {
    1777         158 :                 sal_Int32 nWhere = CalcFlyPos( const_cast<SwFrameFormat *>(static_cast<SwFrameFormat const *>(pVoid)) );
    1778             :                 OSL_ENSURE( COMPLETE_STRING != nWhere, "Prepare: Why me?" );
    1779         158 :                 InvalidateRange( SwCharRange( nWhere, 1 ) );
    1780         158 :                 return bParaPossiblyInvalid;
    1781             :             }
    1782             :             // else: continue with default case block
    1783             :         }
    1784             :         case PREP_CLEAR:
    1785             :         default:
    1786             :         {
    1787       14106 :             if( IsLocked() )
    1788             :             {
    1789        3040 :                 if( PREP_FLY_ARRIVE == ePrep || PREP_FLY_LEAVE == ePrep )
    1790             :                 {
    1791        2403 :                     sal_Int32 nLen = ( GetFollow() ? GetFollow()->GetOfst() :
    1792        2403 :                                       COMPLETE_STRING ) - GetOfst();
    1793        2394 :                     InvalidateRange( SwCharRange( GetOfst(), nLen ), 0 );
    1794             :                 }
    1795             :             }
    1796             :             else
    1797             :             {
    1798       11066 :                 if( pPara->GetRepaint().HasArea() )
    1799       10327 :                     SetCompletePaint();
    1800       11066 :                 Init();
    1801       11066 :                 pPara = 0;
    1802       11066 :                 if( GetOfst() && !IsFollow() )
    1803           6 :                     _SetOfst( 0 );
    1804       11066 :                 if ( bNotify )
    1805       11059 :                     InvalidateSize();
    1806             :                 else
    1807           7 :                     _InvalidateSize();
    1808             :             }
    1809       14106 :             return bParaPossiblyInvalid; // no SetPrep() happened
    1810             :         }
    1811             :     }
    1812       17769 :     if( pPara )
    1813             :     {
    1814       15798 :         pPara->SetPrep();
    1815             :     }
    1816             : 
    1817       17769 :     return bParaPossiblyInvalid;
    1818             : }
    1819             : 
    1820             : /**
    1821             :  * Small Helper class:
    1822             :  * Prepares a test format.
    1823             :  * The frame is changed in size and position, its SwParaPortion is moved aside
    1824             :  * and a new one is created.
    1825             :  * To achieve this, run formatting with bTestFormat flag set.
    1826             :  * In the destructor the TextFrm is reset to its original state.
    1827             :  */
    1828             : class SwTestFormat
    1829             : {
    1830             :     SwTextFrm *pFrm;
    1831             :     SwParaPortion *pOldPara;
    1832             :     SwRect aOldFrm, aOldPrt;
    1833             : public:
    1834             :     SwTestFormat( SwTextFrm* pTextFrm, const SwFrm* pPrv, SwTwips nMaxHeight );
    1835             :     ~SwTestFormat();
    1836             : };
    1837             : 
    1838          91 : SwTestFormat::SwTestFormat( SwTextFrm* pTextFrm, const SwFrm* pPre, SwTwips nMaxHeight )
    1839          91 :     : pFrm( pTextFrm )
    1840             : {
    1841          91 :     aOldFrm = pFrm->Frm();
    1842          91 :     aOldPrt = pFrm->Prt();
    1843             : 
    1844          91 :     SWRECTFN( pFrm )
    1845          91 :     SwTwips nLower = (pFrm->*fnRect->fnGetBottomMargin)();
    1846             : 
    1847          91 :     pFrm->Frm() = pFrm->GetUpper()->Prt();
    1848          91 :     pFrm->Frm() += pFrm->GetUpper()->Frm().Pos();
    1849             : 
    1850          91 :     (pFrm->Frm().*fnRect->fnSetHeight)( nMaxHeight );
    1851          91 :     if( pFrm->GetPrev() )
    1852          91 :         (pFrm->Frm().*fnRect->fnSetPosY)(
    1853          91 :                 (pFrm->GetPrev()->Frm().*fnRect->fnGetBottom)() -
    1854         182 :                 ( bVert ? nMaxHeight + 1 : 0 ) );
    1855             : 
    1856          91 :     SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
    1857          91 :     const SwBorderAttrs &rAttrs = *aAccess.Get();
    1858          91 :     (pFrm->Prt().*fnRect->fnSetPosX)( rAttrs.CalcLeft( pFrm ) );
    1859             : 
    1860          91 :     if( pPre )
    1861             :     {
    1862          91 :         SwTwips nUpper = pFrm->CalcUpperSpace( &rAttrs, pPre );
    1863          91 :         (pFrm->Prt().*fnRect->fnSetPosY)( nUpper );
    1864             :     }
    1865          91 :     (pFrm->Prt().*fnRect->fnSetHeight)(
    1866         182 :         std::max( 0L , (pFrm->Frm().*fnRect->fnGetHeight)() -
    1867         273 :                   (pFrm->Prt().*fnRect->fnGetTop)() - nLower ) );
    1868          91 :     (pFrm->Prt().*fnRect->fnSetWidth)(
    1869          91 :         (pFrm->Frm().*fnRect->fnGetWidth)() -
    1870         182 :         ( rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm ) ) );
    1871          91 :     pOldPara = pFrm->HasPara() ? pFrm->GetPara() : NULL;
    1872          91 :     pFrm->SetPara( new SwParaPortion(), false );
    1873             : 
    1874             :     OSL_ENSURE( ! pFrm->IsSwapped(), "A frame is swapped before _Format" );
    1875             : 
    1876          91 :     if ( pFrm->IsVertical() )
    1877           0 :         pFrm->SwapWidthAndHeight();
    1878             : 
    1879         182 :     SwTextFormatInfo aInf( pFrm, false, true, true );
    1880         182 :     SwTextFormatter  aLine( pFrm, &aInf );
    1881             : 
    1882          91 :     pFrm->_Format( aLine, aInf );
    1883             : 
    1884          91 :     if ( pFrm->IsVertical() )
    1885           0 :         pFrm->SwapWidthAndHeight();
    1886             : 
    1887          91 :     OSL_ENSURE( ! pFrm->IsSwapped(), "A frame is swapped after _Format" );
    1888          91 : }
    1889             : 
    1890          91 : SwTestFormat::~SwTestFormat()
    1891             : {
    1892          91 :     pFrm->Frm() = aOldFrm;
    1893          91 :     pFrm->Prt() = aOldPrt;
    1894          91 :     pFrm->SetPara( pOldPara );
    1895          91 : }
    1896             : 
    1897          91 : bool SwTextFrm::TestFormat( const SwFrm* pPrv, SwTwips &rMaxHeight, bool &bSplit )
    1898             : {
    1899             :     PROTOCOL_ENTER( this, PROT_TESTFORMAT, 0, 0 )
    1900             : 
    1901          91 :     if( IsLocked() && GetUpper()->Prt().Width() <= 0 )
    1902           0 :         return false;
    1903             : 
    1904          91 :     SwTestFormat aSave( this, pPrv, rMaxHeight );
    1905             : 
    1906          91 :     return SwTextFrm::WouldFit( rMaxHeight, bSplit, true );
    1907             : }
    1908             : 
    1909             : /**
    1910             :  * We should not and don't need to reformat.
    1911             :  * We assume that we already formatted and that the formatting
    1912             :  * data is still current.
    1913             :  *
    1914             :  * We also assume that the frame width of the Master and Follow
    1915             :  * are the same. That's why we're not calling FindBreak() for
    1916             :  * FindOrphans().
    1917             :  * The required height is coming from nMaxHeight.
    1918             :  *
    1919             :  * @returns true if I can split
    1920             :  */
    1921        2986 : bool SwTextFrm::WouldFit( SwTwips &rMaxHeight, bool &bSplit, bool bTst )
    1922             : {
    1923             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
    1924             :             "SwTextFrm::WouldFit with swapped frame" );
    1925        2986 :     SWRECTFN( this );
    1926             : 
    1927        2986 :     if( IsLocked() )
    1928           0 :         return false;
    1929             : 
    1930             :     // it can happen that the IdleCollector removed the cached information
    1931        2986 :     if( !IsEmpty() )
    1932        1225 :         GetFormatted();
    1933             : 
    1934             :     // OD 2004-05-24 #i27801# - correction: 'short cut' for empty paragraph
    1935             :     // can *not* be applied, if test format is in progress. The test format doesn't
    1936             :     // adjust the frame and the printing area - see method <SwTextFrm::_Format(..)>,
    1937             :     // which is called in <SwTextFrm::TestFormat(..)>
    1938        2986 :     if ( IsEmpty() && !bTst )
    1939             :     {
    1940        1757 :         bSplit = false;
    1941        1757 :         SwTwips nHeight = bVert ? Prt().SSize().Width() : Prt().SSize().Height();
    1942        1757 :         if( rMaxHeight < nHeight )
    1943           8 :             return false;
    1944             :         else
    1945             :         {
    1946        1749 :             rMaxHeight -= nHeight;
    1947        1749 :             return true;
    1948             :         }
    1949             :     }
    1950             : 
    1951             :     // GetPara can still be 0 in edge cases
    1952             :     // We return true in order to be reformatted on the new Page
    1953             :     OSL_ENSURE( HasPara() || IsHiddenNow(), "WouldFit: GetFormatted() and then !HasPara()" );
    1954        1229 :     if( !HasPara() || ( !(Frm().*fnRect->fnGetHeight)() && IsHiddenNow() ) )
    1955           0 :         return true;
    1956             : 
    1957             :     // Because the Orphan flag only exists for a short moment, we also check
    1958             :     // whether the Framesize is set to very huge by CalcPreps, in order to
    1959             :     // force a MoveFwd
    1960        2458 :     if( IsWidow() || ( bVert ?
    1961           0 :                        ( 0 == Frm().Left() ) :
    1962        1229 :                        ( LONG_MAX - 20000 < Frm().Bottom() ) ) )
    1963             :     {
    1964           3 :         SetWidow(false);
    1965           3 :         if ( GetFollow() )
    1966             :         {
    1967             :             // If we've ended up here due to a Widow request by our Follow, we check
    1968             :             // whether there's a Follow with a real height at all.
    1969             :             // Else (e.g. for newly created SctFrms) we ignore the IsWidow() and
    1970             :             // still check if we can find enough room
    1971           9 :             if( ( ( ! bVert && LONG_MAX - 20000 >= Frm().Bottom() ) ||
    1972           3 :                   (   bVert && 0 < Frm().Left() ) ) &&
    1973           0 :                   ( GetFollow()->IsVertical() ?
    1974           0 :                     !GetFollow()->Frm().Width() :
    1975           0 :                     !GetFollow()->Frm().Height() ) )
    1976             :             {
    1977           0 :                 SwTextFrm* pFoll = GetFollow()->GetFollow();
    1978           0 :                 while( pFoll &&
    1979           0 :                         ( pFoll->IsVertical() ?
    1980           0 :                          !pFoll->Frm().Width() :
    1981           0 :                          !pFoll->Frm().Height() ) )
    1982           0 :                     pFoll = pFoll->GetFollow();
    1983           0 :                 if( pFoll )
    1984           0 :                     return false;
    1985             :             }
    1986             :             else
    1987           3 :                 return false;
    1988             :         }
    1989             :     }
    1990             : 
    1991        1226 :     SWAP_IF_NOT_SWAPPED swap( this );
    1992             : 
    1993        2452 :     SwTextSizeInfo aInf( this );
    1994        2452 :     SwTextMargin aLine( this, &aInf );
    1995             : 
    1996        1226 :     WidowsAndOrphans aFrmBreak( this, rMaxHeight, bSplit );
    1997             : 
    1998        1226 :     bool bRet = true;
    1999             : 
    2000        1226 :     aLine.Bottom();
    2001             :     // is breaking necessary?
    2002        1226 :     bSplit = !aFrmBreak.IsInside( aLine );
    2003        1226 :     if ( bSplit )
    2004         100 :         bRet = !aFrmBreak.IsKeepAlways() && aFrmBreak.WouldFit( aLine, rMaxHeight, bTst );
    2005             :     else
    2006             :     {
    2007             :         // we need the total height including the current line
    2008        1126 :         aLine.Top();
    2009        1313 :         do
    2010             :         {
    2011        1313 :             rMaxHeight -= aLine.GetLineHeight();
    2012        1313 :         } while ( aLine.Next() );
    2013             :     }
    2014             : 
    2015        2452 :     return bRet;
    2016             : }
    2017             : 
    2018        3474 : sal_uInt16 SwTextFrm::GetParHeight() const
    2019             : {
    2020             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
    2021             :             "SwTextFrm::GetParHeight with swapped frame" );
    2022             : 
    2023        3474 :     if( !HasPara() )
    2024             :     {   // For non-empty paragraphs this is a special case
    2025             :         // For UnderSized we can simply just ask 1 Twip more
    2026         858 :         sal_uInt16 nRet = (sal_uInt16)Prt().SSize().Height();
    2027         858 :         if( IsUndersized() )
    2028             :         {
    2029         858 :             if( IsEmpty() || GetText().isEmpty() )
    2030         837 :                 nRet = (sal_uInt16)EmptyHeight();
    2031             :             else
    2032          21 :                 ++nRet;
    2033             :         }
    2034         858 :         return nRet;
    2035             :     }
    2036             : 
    2037             :     // TODO: Refactor and improve code
    2038        2616 :     const SwLineLayout* pLineLayout = GetPara();
    2039        2616 :     sal_uInt16 nHeight = pLineLayout ? pLineLayout->GetRealHeight() : 0;
    2040             : 
    2041             :     // Is this paragraph scrolled? Our height until now is at least
    2042             :     // one line height too low then
    2043        2616 :     if( GetOfst() && !IsFollow() )
    2044           0 :         nHeight *= 2;
    2045             : 
    2046             :     // OD 2004-03-04 #115793#
    2047        5709 :     while ( pLineLayout && pLineLayout->GetNext() )
    2048             :     {
    2049         477 :         pLineLayout = pLineLayout->GetNext();
    2050         477 :         nHeight = nHeight + pLineLayout->GetRealHeight();
    2051             :     }
    2052             : 
    2053        2616 :     return nHeight;
    2054             : }
    2055             : 
    2056             : /**
    2057             :  * @returns this _always_ in the formatted state!
    2058             :  */
    2059       89861 : SwTextFrm* SwTextFrm::GetFormatted( bool bForceQuickFormat )
    2060             : {
    2061       89861 :     SWAP_IF_SWAPPED swap( this );
    2062             : 
    2063             :     // The IdleCollector could've removed my cached information
    2064             :     // Calc() calls our format
    2065             :     // Not for empty paragraphs
    2066       89861 :     if( !HasPara() && !(IsValid() && IsEmpty()) )
    2067             :     {
    2068             :         // Calc() must be called, because frame position can be wrong
    2069         222 :         const bool bFormat = GetValidSizeFlag();
    2070         222 :         Calc();
    2071             : 
    2072             :         // It could be that Calc() did not trigger Format(), because
    2073             :         // we've been asked by the IdleCollector to throw away our
    2074             :         // format information
    2075             :         // Optimization with FormatQuick()
    2076         222 :         if( bFormat && !FormatQuick( bForceQuickFormat ) )
    2077           0 :             Format();
    2078             :     }
    2079             : 
    2080       89861 :     return this;
    2081             : }
    2082             : 
    2083         542 : SwTwips SwTextFrm::CalcFitToContent()
    2084             : {
    2085             :     // #i31490#
    2086             :     // If we are currently locked, we better return with a
    2087             :     // fairly reasonable value:
    2088         542 :     if ( IsLocked() )
    2089           0 :         return Prt().Width();
    2090             : 
    2091         542 :     SwParaPortion* pOldPara = GetPara();
    2092         542 :     SwParaPortion *pDummy = new SwParaPortion();
    2093         542 :     SetPara( pDummy, false );
    2094         542 :     const SwPageFrm* pPage = FindPageFrm();
    2095             : 
    2096         542 :     const Point   aOldFrmPos   = Frm().Pos();
    2097         542 :     const SwTwips nOldFrmWidth = Frm().Width();
    2098         542 :     const SwTwips nOldPrtWidth = Prt().Width();
    2099         542 :     const SwTwips nPageWidth = GetUpper()->IsVertical() ?
    2100           0 :                                pPage->Prt().Height() :
    2101         542 :                                pPage->Prt().Width();
    2102             : 
    2103         542 :     Frm().Width( nPageWidth );
    2104         542 :     Prt().Width( nPageWidth );
    2105             : 
    2106             :     // #i25422# objects anchored as character in RTL
    2107         542 :     if ( IsRightToLeft() )
    2108           0 :         Frm().Pos().X() += nOldFrmWidth - nPageWidth;
    2109             : 
    2110             :     // #i31490#
    2111         542 :     TextFrmLockGuard aLock( this );
    2112             : 
    2113        1084 :     SwTextFormatInfo aInf( this, false, true, true );
    2114         542 :     aInf.SetIgnoreFly( true );
    2115        1084 :     SwTextFormatter  aLine( this, &aInf );
    2116        1084 :     SwHookOut aHook( aInf );
    2117             : 
    2118             :     // #i54031# - assure mininum of MINLAY twips.
    2119             :     const SwTwips nMax = std::max( (SwTwips)MINLAY,
    2120         542 :                               aLine._CalcFitToContent() + 1 );
    2121             : 
    2122         542 :     Frm().Width( nOldFrmWidth );
    2123         542 :     Prt().Width( nOldPrtWidth );
    2124             : 
    2125             :     // #i25422# objects anchored as character in RTL
    2126         542 :     if ( IsRightToLeft() )
    2127           0 :         Frm().Pos() = aOldFrmPos;
    2128             : 
    2129         542 :     SetPara( pOldPara );
    2130             : 
    2131        1084 :     return nMax;
    2132             : }
    2133             : 
    2134             : /**
    2135             :  * Simulate format for a list item paragraph, whose list level attributes
    2136             :  * are in LABEL_ALIGNMENT mode, in order to determine additional first
    2137             :  * line offset for the real text formatting due to the value of label
    2138             :  * adjustment attribute of the list level.
    2139             :  */
    2140       72843 : void SwTextFrm::CalcAdditionalFirstLineOffset()
    2141             : {
    2142       72843 :     if ( IsLocked() )
    2143       72843 :         return;
    2144             : 
    2145             :     // reset additional first line offset
    2146       72843 :     mnAdditionalFirstLineOffset = 0;
    2147             : 
    2148       72843 :     const SwTextNode* pTextNode( GetTextNode() );
    2149       76795 :     if ( pTextNode && pTextNode->IsNumbered() && pTextNode->IsCountedInList() &&
    2150        3952 :          pTextNode->GetNumRule() )
    2151             :     {
    2152        3952 :         int nListLevel = pTextNode->GetActualListLevel();
    2153             : 
    2154        3952 :         if (nListLevel < 0)
    2155           0 :             nListLevel = 0;
    2156             : 
    2157        3952 :         if (nListLevel >= MAXLEVEL)
    2158           0 :             nListLevel = MAXLEVEL - 1;
    2159             : 
    2160             :         const SwNumFormat& rNumFormat =
    2161        3952 :                 pTextNode->GetNumRule()->Get( static_cast<sal_uInt16>(nListLevel) );
    2162        3952 :         if ( rNumFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
    2163             :         {
    2164             :             // keep current paragraph portion and apply dummy paragraph portion
    2165        3503 :             SwParaPortion* pOldPara = GetPara();
    2166        3503 :             SwParaPortion *pDummy = new SwParaPortion();
    2167        3503 :             SetPara( pDummy, false );
    2168             : 
    2169             :             // lock paragraph
    2170        3503 :             TextFrmLockGuard aLock( this );
    2171             : 
    2172             :             // simulate text formatting
    2173        7006 :             SwTextFormatInfo aInf( this, false, true, true );
    2174        3503 :             aInf.SetIgnoreFly( true );
    2175        7006 :             SwTextFormatter aLine( this, &aInf );
    2176        7006 :             SwHookOut aHook( aInf );
    2177        3503 :             aLine._CalcFitToContent();
    2178             : 
    2179             :             // determine additional first line offset
    2180        3503 :             const SwLinePortion* pFirstPortion = aLine.GetCurr()->GetFirstPortion();
    2181        3503 :             if ( pFirstPortion->InNumberGrp() && !pFirstPortion->IsFootnoteNumPortion() )
    2182             :             {
    2183        3281 :                 SwTwips nNumberPortionWidth( pFirstPortion->Width() );
    2184             : 
    2185        3281 :                 const SwLinePortion* pPortion = pFirstPortion->GetPortion();
    2186       12087 :                 while ( pPortion &&
    2187        5525 :                         pPortion->InNumberGrp() && !pPortion->IsFootnoteNumPortion())
    2188             :                 {
    2189        1122 :                     nNumberPortionWidth += pPortion->Width();
    2190        1122 :                     pPortion = pPortion->GetPortion();
    2191             :                 }
    2192             : 
    2193        6562 :                 if ( ( IsRightToLeft() &&
    2194        6563 :                        rNumFormat.GetNumAdjust() == SVX_ADJUST_LEFT ) ||
    2195        6562 :                      ( !IsRightToLeft() &&
    2196        3281 :                        rNumFormat.GetNumAdjust() == SVX_ADJUST_RIGHT ) )
    2197             :                 {
    2198           1 :                     mnAdditionalFirstLineOffset = -nNumberPortionWidth;
    2199             :                 }
    2200        3280 :                 else if ( rNumFormat.GetNumAdjust() == SVX_ADJUST_CENTER )
    2201             :                 {
    2202           0 :                     mnAdditionalFirstLineOffset = -(nNumberPortionWidth/2);
    2203             :                 }
    2204             :             }
    2205             : 
    2206             :             // restore paragraph portion
    2207        7006 :             SetPara( pOldPara );
    2208             :         }
    2209             :     }
    2210             : }
    2211             : 
    2212             : /**
    2213             :  * Determine the height of the last line for the calculation of
    2214             :  * the proportional line spacing
    2215             :  *
    2216             :  * Height of last line will be stored in new member
    2217             :  * mnHeightOfLastLine and can be accessed via method
    2218             :  * GetHeightOfLastLine()
    2219             :  *
    2220             :  * @param _bUseFont force the usage of the former algorithm to
    2221             :  *                  determine the height of the last line, which
    2222             :  *                  uses the font
    2223             :  */
    2224       74545 : void SwTextFrm::_CalcHeightOfLastLine( const bool _bUseFont )
    2225             : {
    2226             :     // #i71281#
    2227             :     // invalidate printing area, if height of last line changes
    2228       74545 :     const SwTwips mnOldHeightOfLastLine( mnHeightOfLastLine );
    2229             : 
    2230             :     // determine output device
    2231       74545 :     SwViewShell* pVsh = getRootFrm()->GetCurrShell();
    2232             :     OSL_ENSURE( pVsh, "<SwTextFrm::_GetHeightOfLastLineForPropLineSpacing()> - no SwViewShell" );
    2233             : 
    2234             :     // #i78921# - make code robust, according to provided patch
    2235             :     // There could be no <SwViewShell> instance in the case of loading a binary
    2236             :     // StarOffice file format containing an embedded Writer document.
    2237       74545 :     if ( !pVsh )
    2238             :     {
    2239           0 :         return;
    2240             :     }
    2241       74545 :     OutputDevice* pOut = pVsh->GetOut();
    2242       74545 :     const IDocumentSettingAccess* pIDSA = GetTextNode()->getIDocumentSettingAccess();
    2243       74589 :     if ( !pVsh->GetViewOptions()->getBrowseMode() ||
    2244          44 :           pVsh->GetViewOptions()->IsPrtFormat() )
    2245             :     {
    2246       74501 :         pOut = GetTextNode()->getIDocumentDeviceAccess()->getReferenceDevice( true );
    2247             :     }
    2248             :     OSL_ENSURE( pOut, "<SwTextFrm::_GetHeightOfLastLineForPropLineSpacing()> - no OutputDevice" );
    2249             :     // #i78921# - make code robust, according to provided patch
    2250       74545 :     if ( !pOut )
    2251             :     {
    2252           0 :         return;
    2253             :     }
    2254             : 
    2255             :     // determine height of last line
    2256       74545 :     if ( _bUseFont || pIDSA->get(DocumentSettingId::OLD_LINE_SPACING ) )
    2257             :     {
    2258             :         // former determination of last line height for proprotional line
    2259             :         // spacing - take height of font set at the paragraph
    2260        2586 :         SwFont aFont( GetAttrSet(), pIDSA );
    2261             : 
    2262             :         // we must ensure that the font is restored correctly on the OutputDevice
    2263             :         // otherwise Last!=Owner could occur
    2264        2586 :         if ( pLastFont )
    2265             :         {
    2266        2586 :             SwFntObj *pOldFont = pLastFont;
    2267        2586 :             pLastFont = NULL;
    2268        2586 :             aFont.SetFntChg( true );
    2269        2586 :             aFont.ChgPhysFnt( pVsh, *pOut );
    2270        2586 :             mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
    2271             :             //coverity[var_deref_model] - pLastFont is set in SwSubFont::ChgFnt
    2272        2586 :             pLastFont->Unlock();
    2273        2586 :             pLastFont = pOldFont;
    2274        2586 :             pLastFont->SetDevFont( pVsh, *pOut );
    2275             :         }
    2276             :         else
    2277             :         {
    2278           0 :             vcl::Font aOldFont = pOut->GetFont();
    2279           0 :             aFont.SetFntChg( true );
    2280           0 :             aFont.ChgPhysFnt( pVsh, *pOut );
    2281           0 :             mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
    2282             :             //coverity[var_deref_model] - pLastFont is set in SwSubFont::ChgFnt
    2283           0 :             pLastFont->Unlock();
    2284           0 :             pLastFont = NULL;
    2285           0 :             pOut->SetFont( aOldFont );
    2286        2586 :         }
    2287             :     }
    2288             :     else
    2289             :     {
    2290             :         // new determination of last line height - take actually height of last line
    2291             :         // #i89000#
    2292             :         // assure same results, if paragraph is undersized
    2293       71959 :         if ( IsUndersized() )
    2294             :         {
    2295        5052 :             mnHeightOfLastLine = 0;
    2296             :         }
    2297             :         else
    2298             :         {
    2299       66907 :             bool bCalcHeightOfLastLine = true;
    2300       66907 :             if ( ( !HasPara() && IsEmpty( ) ) || GetText().isEmpty() )
    2301             :             {
    2302       25789 :                 mnHeightOfLastLine = EmptyHeight();
    2303       25789 :                 bCalcHeightOfLastLine = false;
    2304             :             }
    2305             : 
    2306       66907 :             if ( bCalcHeightOfLastLine )
    2307             :             {
    2308             :                 OSL_ENSURE( HasPara(),
    2309             :                         "<SwTextFrm::_CalcHeightOfLastLine()> - missing paragraph portions." );
    2310       41118 :                 const SwLineLayout* pLineLayout = GetPara();
    2311      147946 :                 while ( pLineLayout && pLineLayout->GetNext() )
    2312             :                 {
    2313             :                     // iteration to last line
    2314       65710 :                     pLineLayout = pLineLayout->GetNext();
    2315             :                 }
    2316       41118 :                 if ( pLineLayout )
    2317             :                 {
    2318             :                     SwTwips nAscent, nDescent, nDummy1, nDummy2;
    2319             :                     // #i47162# - suppress consideration of
    2320             :                     // fly content portions and the line portion.
    2321             :                     pLineLayout->MaxAscentDescent( nAscent, nDescent,
    2322             :                                                    nDummy1, nDummy2,
    2323       41118 :                                                    0, true );
    2324             :                     // #i71281#
    2325             :                     // Suppress wrong invalidation of printing area, if method is
    2326             :                     // called recursive.
    2327             :                     // Thus, member <mnHeightOfLastLine> is only set directly, if
    2328             :                     // no recursive call is needed.
    2329       41118 :                     const SwTwips nNewHeightOfLastLine = nAscent + nDescent;
    2330             :                     // #i47162# - if last line only contains
    2331             :                     // fly content portions, <mnHeightOfLastLine> is zero.
    2332             :                     // In this case determine height of last line by the font
    2333       41118 :                     if ( nNewHeightOfLastLine == 0 )
    2334             :                     {
    2335        2270 :                         _CalcHeightOfLastLine( true );
    2336             :                     }
    2337             :                     else
    2338             :                     {
    2339       38848 :                         mnHeightOfLastLine = nNewHeightOfLastLine;
    2340             :                     }
    2341             :                 }
    2342             :             }
    2343             :         }
    2344             :     }
    2345             :     // #i71281#
    2346             :     // invalidate printing area, if height of last line changes
    2347       74545 :     if ( mnHeightOfLastLine != mnOldHeightOfLastLine )
    2348             :     {
    2349       34824 :         InvalidatePrt();
    2350             :     }
    2351             : }
    2352             : 
    2353             : /**
    2354             :  * Method returns the value of the inter line spacing for a text frame.
    2355             :  * Such a value exists for proportional line spacings ("1,5 Lines",
    2356             :  * "Double", "Proportional" and for leading line spacing ("Leading").
    2357             :  *
    2358             :  * @param _bNoPropLineSpacing (default = false) control whether the
    2359             :  *                            value of a proportional line spacing is
    2360             :  *                            returned or not
    2361             :  */
    2362       96408 : long SwTextFrm::GetLineSpace( const bool _bNoPropLineSpace ) const
    2363             : {
    2364       96408 :     long nRet = 0;
    2365             : 
    2366       96408 :     const SwAttrSet* pSet = GetAttrSet();
    2367       96408 :     const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
    2368             : 
    2369       96408 :     switch( rSpace.GetInterLineSpaceRule() )
    2370             :     {
    2371             :         case SVX_INTER_LINE_SPACE_PROP:
    2372             :         {
    2373             :             // OD 07.01.2004 #i11859#
    2374       27973 :             if ( _bNoPropLineSpace )
    2375             :             {
    2376       17366 :                 break;
    2377             :             }
    2378             : 
    2379             :             // OD 2004-03-17 #i11860# - use method GetHeightOfLastLine()
    2380       10607 :             nRet = GetHeightOfLastLine();
    2381             : 
    2382       10607 :             long nTmp = nRet;
    2383       10607 :             nTmp *= rSpace.GetPropLineSpace();
    2384       10607 :             nTmp /= 100;
    2385       10607 :             nTmp -= nRet;
    2386       10607 :             if ( nTmp > 0 )
    2387       10259 :                 nRet = nTmp;
    2388             :             else
    2389         348 :                 nRet = 0;
    2390             :         }
    2391       10607 :             break;
    2392             :         case SVX_INTER_LINE_SPACE_FIX:
    2393             :         {
    2394           0 :             if ( rSpace.GetInterLineSpace() > 0 )
    2395           0 :                 nRet = rSpace.GetInterLineSpace();
    2396             :         }
    2397           0 :             break;
    2398             :         default:
    2399       68435 :             break;
    2400             :     }
    2401       96408 :     return nRet;
    2402             : }
    2403             : 
    2404        1379 : sal_uInt16 SwTextFrm::FirstLineHeight() const
    2405             : {
    2406        1379 :     if ( !HasPara() )
    2407             :     {
    2408         139 :         if( IsEmpty() && IsValid() )
    2409         138 :             return IsVertical() ? (sal_uInt16)Prt().Width() : (sal_uInt16)Prt().Height();
    2410           1 :         return USHRT_MAX;
    2411             :     }
    2412        1240 :     const SwParaPortion *pPara = GetPara();
    2413        1240 :     if ( !pPara )
    2414           0 :         return USHRT_MAX;
    2415             : 
    2416        1240 :     return pPara->Height();
    2417             : }
    2418             : 
    2419          28 : sal_uInt16 SwTextFrm::GetLineCount( sal_Int32 nPos )
    2420             : {
    2421          28 :     sal_uInt16 nRet = 0;
    2422          28 :     SwTextFrm *pFrm = this;
    2423          28 :     do
    2424             :     {
    2425          28 :         pFrm->GetFormatted();
    2426          28 :         if( !pFrm->HasPara() )
    2427           0 :             break;
    2428          28 :         SwTextSizeInfo aInf( pFrm );
    2429          56 :         SwTextMargin aLine( pFrm, &aInf );
    2430          28 :         if( COMPLETE_STRING == nPos )
    2431          28 :             aLine.Bottom();
    2432             :         else
    2433           0 :             aLine.CharToLine( nPos );
    2434          28 :         nRet = nRet + aLine.GetLineNr();
    2435          56 :         pFrm = pFrm->GetFollow();
    2436          28 :     } while ( pFrm && pFrm->GetOfst() <= nPos );
    2437          28 :     return nRet;
    2438             : }
    2439             : 
    2440       72663 : void SwTextFrm::ChgThisLines()
    2441             : {
    2442             :     // not necessary to format here (GerFormatted etc.), because we have to come from there!
    2443       72663 :     sal_uLong nNew = 0;
    2444       72663 :     const SwLineNumberInfo &rInf = GetNode()->GetDoc()->GetLineNumberInfo();
    2445       72663 :     if ( !GetText().isEmpty() && HasPara() )
    2446             :     {
    2447       43562 :         SwTextSizeInfo aInf( this );
    2448       87124 :         SwTextMargin aLine( this, &aInf );
    2449       43562 :         if ( rInf.IsCountBlankLines() )
    2450             :         {
    2451       43562 :             aLine.Bottom();
    2452       43562 :             nNew = (sal_uLong)aLine.GetLineNr();
    2453             :         }
    2454             :         else
    2455             :         {
    2456           0 :             do
    2457             :             {
    2458           0 :                 if( aLine.GetCurr()->HasContent() )
    2459           0 :                     ++nNew;
    2460           0 :             } while ( aLine.NextLine() );
    2461       43562 :         }
    2462             :     }
    2463       29101 :     else if ( rInf.IsCountBlankLines() )
    2464       29101 :         nNew = 1;
    2465             : 
    2466       72663 :     if ( nNew != nThisLines )
    2467             :     {
    2468       34923 :         if ( !IsInTab() && GetAttrSet()->GetLineNumber().IsCount() )
    2469             :         {
    2470       24936 :             nAllLines -= nThisLines;
    2471       24936 :             nThisLines = nNew;
    2472       24936 :             nAllLines  += nThisLines;
    2473       24936 :             SwFrm *pNxt = GetNextContentFrm();
    2474       50190 :             while( pNxt && pNxt->IsInTab() )
    2475             :             {
    2476         318 :                 if( 0 != (pNxt = pNxt->FindTabFrm()) )
    2477         318 :                     pNxt = pNxt->FindNextCnt();
    2478             :             }
    2479       24936 :             if( pNxt )
    2480       19736 :                 pNxt->InvalidateLineNum();
    2481             : 
    2482             :             // Extend repaint to the bottom.
    2483       24936 :             if ( HasPara() )
    2484             :             {
    2485       18457 :                 SwRepaint& rRepaint = GetPara()->GetRepaint();
    2486       18457 :                 rRepaint.Bottom( std::max( rRepaint.Bottom(),
    2487       36914 :                                        Frm().Top()+Prt().Bottom()));
    2488             :             }
    2489             :         }
    2490             :         else // Paragraphs which are not counted should not manipulate the AllLines.
    2491        9987 :             nThisLines = nNew;
    2492             :     }
    2493       72663 : }
    2494             : 
    2495       36445 : void SwTextFrm::RecalcAllLines()
    2496             : {
    2497       36445 :     ValidateLineNum();
    2498             : 
    2499       36445 :     const SwAttrSet *pAttrSet = GetAttrSet();
    2500             : 
    2501       36445 :     if ( !IsInTab() )
    2502             :     {
    2503       25941 :         const sal_uLong nOld = GetAllLines();
    2504       25941 :         const SwFormatLineNumber &rLineNum = pAttrSet->GetLineNumber();
    2505             :         sal_uLong nNewNum;
    2506       25941 :         const bool bRestart = GetTextNode()->GetDoc()->GetLineNumberInfo().IsRestartEachPage();
    2507             : 
    2508       25941 :         if ( !IsFollow() && rLineNum.GetStartValue() && rLineNum.IsCount() )
    2509           3 :             nNewNum = rLineNum.GetStartValue() - 1;
    2510             :         // If it is a follow or not has not be considered if it is a restart at each page; the
    2511             :         // restart should also take affekt at follows.
    2512       25938 :         else if ( bRestart && FindPageFrm()->FindFirstBodyContent() == this )
    2513             :         {
    2514           0 :             nNewNum = 0;
    2515             :         }
    2516             :         else
    2517             :         {
    2518       25938 :             SwContentFrm *pPrv = GetPrevContentFrm();
    2519      130957 :             while ( pPrv &&
    2520       68682 :                     (pPrv->IsInTab() || pPrv->IsInDocBody() != IsInDocBody()) )
    2521       19319 :                 pPrv = pPrv->GetPrevContentFrm();
    2522             : 
    2523             :             // #i78254# Restart line numbering at page change
    2524             :             // First body content may be in table!
    2525       25938 :             if ( bRestart && pPrv && pPrv->FindPageFrm() != FindPageFrm() )
    2526           0 :                 pPrv = 0;
    2527             : 
    2528       25938 :             nNewNum = pPrv ? static_cast<SwTextFrm*>(pPrv)->GetAllLines() : 0;
    2529             :         }
    2530       25941 :         if ( rLineNum.IsCount() )
    2531       25498 :             nNewNum += GetThisLines();
    2532             : 
    2533       25941 :         if ( nOld != nNewNum )
    2534             :         {
    2535       20631 :             nAllLines = nNewNum;
    2536       20631 :             SwContentFrm *pNxt = GetNextContentFrm();
    2537      304178 :             while ( pNxt &&
    2538      195040 :                     (pNxt->IsInTab() || pNxt->IsInDocBody() != IsInDocBody()) )
    2539       81421 :                 pNxt = pNxt->GetNextContentFrm();
    2540       20631 :             if ( pNxt )
    2541             :             {
    2542       18653 :                 if ( pNxt->GetUpper() != GetUpper() )
    2543        7496 :                     pNxt->InvalidateLineNum();
    2544             :                 else
    2545       11157 :                     pNxt->_InvalidateLineNum();
    2546             :             }
    2547             :         }
    2548             :     }
    2549       36445 : }
    2550             : 
    2551        1062 : void SwTextFrm::VisitPortions( SwPortionHandler& rPH ) const
    2552             : {
    2553        1062 :     const SwParaPortion* pPara = IsValid() ? GetPara() : NULL;
    2554             : 
    2555        1062 :     if (pPara)
    2556             :     {
    2557         619 :         if ( IsFollow() )
    2558           1 :             rPH.Skip( GetOfst() );
    2559             : 
    2560         619 :         const SwLineLayout* pLine = pPara;
    2561        1889 :         while ( pLine )
    2562             :         {
    2563         651 :             const SwLinePortion* pPor = pLine->GetFirstPortion();
    2564        2168 :             while ( pPor )
    2565             :             {
    2566         866 :                 pPor->HandlePortion( rPH );
    2567         866 :                 pPor = pPor->GetPortion();
    2568             :             }
    2569             : 
    2570         651 :             rPH.LineBreak(pLine->Width());
    2571         651 :             pLine = pLine->GetNext();
    2572             :         }
    2573             :     }
    2574             : 
    2575        1062 :     rPH.Finish();
    2576        1062 : }
    2577             : 
    2578       95954 : const SwScriptInfo* SwTextFrm::GetScriptInfo() const
    2579             : {
    2580       95954 :     const SwParaPortion* pPara = GetPara();
    2581       95954 :     return pPara ? &pPara->GetScriptInfo() : 0;
    2582             : }
    2583             : 
    2584             : /**
    2585             :  * Helper function for SwTextFrm::CalcBasePosForFly()
    2586             :  */
    2587      109250 : static SwTwips lcl_CalcFlyBasePos( const SwTextFrm& rFrm, SwRect aFlyRect,
    2588             :                             SwTextFly& rTextFly )
    2589             : {
    2590      109250 :     SWRECTFN( (&rFrm) )
    2591      109250 :     SwTwips nRet = rFrm.IsRightToLeft() ?
    2592         138 :                    (rFrm.Frm().*fnRect->fnGetRight)() :
    2593      109388 :                    (rFrm.Frm().*fnRect->fnGetLeft)();
    2594             : 
    2595         172 :     do
    2596             :     {
    2597      109391 :         SwRect aRect = rTextFly.GetFrm( aFlyRect );
    2598      109391 :         if ( 0 != (aRect.*fnRect->fnGetWidth)() )
    2599             :         {
    2600         450 :             if ( rFrm.IsRightToLeft() )
    2601             :             {
    2602           0 :                 if ( (aRect.*fnRect->fnGetRight)() -
    2603           0 :                      (aFlyRect.*fnRect->fnGetRight)() >= 0 )
    2604             :                 {
    2605             :                     (aFlyRect.*fnRect->fnSetRight)(
    2606           0 :                         (aRect.*fnRect->fnGetLeft)() );
    2607           0 :                     nRet = (aRect.*fnRect->fnGetLeft)();
    2608             :                 }
    2609             :                 else
    2610      109219 :                     break;
    2611             :             }
    2612             :             else
    2613             :             {
    2614         900 :                 if ( (aFlyRect.*fnRect->fnGetLeft)() -
    2615         450 :                      (aRect.*fnRect->fnGetLeft)() >= 0 )
    2616             :                 {
    2617             :                     (aFlyRect.*fnRect->fnSetLeft)(
    2618         172 :                         (aRect.*fnRect->fnGetRight)() + 1 );
    2619         172 :                     nRet = (aRect.*fnRect->fnGetRight)();
    2620             :                 }
    2621             :                 else
    2622         278 :                     break;
    2623             :             }
    2624             :         }
    2625             :         else
    2626      108941 :             break;
    2627             :     }
    2628         172 :     while ( (aFlyRect.*fnRect->fnGetWidth)() > 0 );
    2629             : 
    2630      109250 :     return nRet;
    2631             : }
    2632             : 
    2633       72275 : void SwTextFrm::CalcBaseOfstForFly()
    2634             : {
    2635             :     OSL_ENSURE( !IsVertical() || !IsSwapped(),
    2636             :             "SwTextFrm::CalcBasePosForFly with swapped frame!" );
    2637             : 
    2638       72275 :     const SwNode* pNode = GetTextNode();
    2639       72275 :     if ( !pNode->getIDocumentSettingAccess()->get(DocumentSettingId::ADD_FLY_OFFSETS) )
    2640       89925 :         return;
    2641             : 
    2642       54625 :     SWRECTFN( this )
    2643             : 
    2644       54625 :     SwRect aFlyRect( Frm().Pos() + Prt().Pos(), Prt().SSize() );
    2645             : 
    2646             :     // Get first 'real' line and adjust position and height of line rectangle
    2647             :     // OD 08.09.2003 #110978#, #108749#, #110354# - correct behaviour,
    2648             :     // if no 'real' line exists (empty paragraph with and without a dummy portion)
    2649             :     {
    2650       54625 :         SwTwips nTop = (aFlyRect.*fnRect->fnGetTop)();
    2651       54625 :         const SwLineLayout* pLay = GetPara();
    2652       54625 :         SwTwips nLineHeight = 200;
    2653      109346 :         while( pLay && pLay->IsDummy() && pLay->GetNext() )
    2654             :         {
    2655          96 :             nTop += pLay->Height();
    2656          96 :             pLay = pLay->GetNext();
    2657             :         }
    2658       54625 :         if ( pLay )
    2659             :         {
    2660       42015 :             nLineHeight = pLay->Height();
    2661             :         }
    2662       54625 :         (aFlyRect.*fnRect->fnSetTopAndHeight)( nTop, nLineHeight );
    2663             :     }
    2664             : 
    2665       54625 :     SwTextFly aTextFly( this );
    2666       54625 :     aTextFly.SetIgnoreCurrentFrame( true );
    2667       54625 :     aTextFly.SetIgnoreContour( true );
    2668             :     // #118809# - ignore objects in page header|footer for
    2669             :     // text frames not in page header|footer
    2670       54625 :     aTextFly.SetIgnoreObjsInHeaderFooter( true );
    2671       54625 :     SwTwips nRet1 = lcl_CalcFlyBasePos( *this, aFlyRect, aTextFly );
    2672       54625 :     aTextFly.SetIgnoreCurrentFrame( false );
    2673       54625 :     SwTwips nRet2 = lcl_CalcFlyBasePos( *this, aFlyRect, aTextFly );
    2674             : 
    2675             :     // make values relative to frame start position
    2676       54625 :     SwTwips nLeft = IsRightToLeft() ?
    2677          69 :                     (Frm().*fnRect->fnGetRight)() :
    2678       54694 :                     (Frm().*fnRect->fnGetLeft)();
    2679             : 
    2680       54625 :     mnFlyAnchorOfst = nRet1 - nLeft;
    2681       54625 :     mnFlyAnchorOfstNoWrap = nRet2 - nLeft;
    2682             : }
    2683             : 
    2684             : /**
    2685             :  * Repaint all text frames of the given text node
    2686             :  */
    2687           0 : void SwTextFrm::repaintTextFrames( const SwTextNode& rNode )
    2688             : {
    2689           0 :     SwIterator<SwTextFrm,SwTextNode> aIter( rNode );
    2690           0 :     for( const SwTextFrm *pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
    2691             :     {
    2692           0 :         SwRect aRec( pFrm->PaintArea() );
    2693           0 :         const SwRootFrm *pRootFrm = pFrm->getRootFrm();
    2694           0 :         SwViewShell *pCurShell = pRootFrm ? pRootFrm->GetCurrShell() : NULL;
    2695           0 :         if( pCurShell )
    2696           0 :             pCurShell->InvalidateWindows( aRec );
    2697           0 :     }
    2698         177 : }
    2699             : 
    2700             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11