LCOV - code coverage report
Current view: top level - sw/source/core/text - txtfrm.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 984 1294 76.0 %
Date: 2014-11-03 Functions: 60 69 87.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <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 <switerator.hxx>
      78             : #include <ftnidx.hxx>
      79             : 
      80     7688683 : TYPEINIT1( SwTxtFrm, SwCntntFrm );
      81             : 
      82             : // Switches width and height of the text frame
      83          88 : void SwTxtFrm::SwapWidthAndHeight()
      84             : {
      85          88 :     if ( ! bIsSwapped )
      86             :     {
      87          44 :         const long nPrtOfstX = Prt().Pos().X();
      88          44 :         Prt().Pos().X() = Prt().Pos().Y();
      89          44 :         if( IsVertLR() )
      90           0 :             Prt().Pos().Y() = nPrtOfstX;
      91             :         else
      92          44 :             Prt().Pos().Y() = Frm().Width() - ( nPrtOfstX + Prt().Width() );
      93             : 
      94             :     }
      95             :     else
      96             :     {
      97          44 :         const long nPrtOfstY = Prt().Pos().Y();
      98          44 :         Prt().Pos().Y() = Prt().Pos().X();
      99          44 :         if( IsVertLR() )
     100           0 :             Prt().Pos().X() = nPrtOfstY;
     101             :         else
     102          44 :             Prt().Pos().X() = Frm().Height() - ( nPrtOfstY + Prt().Height() );
     103             :     }
     104             : 
     105          88 :     const long nFrmWidth = Frm().Width();
     106          88 :     Frm().Width( Frm().Height() );
     107          88 :     Frm().Height( nFrmWidth );
     108          88 :     const long nPrtWidth = Prt().Width();
     109          88 :     Prt().Width( Prt().Height() );
     110          88 :     Prt().Height( nPrtWidth );
     111             : 
     112          88 :     bIsSwapped = ! bIsSwapped;
     113          88 : }
     114             : 
     115             : // Calculates the coordinates of a rectangle when switching from
     116             : // horizontal to vertical layout.
     117           0 : void SwTxtFrm::SwitchHorizontalToVertical( SwRect& rRect ) const
     118             : {
     119             :     // calc offset inside frame
     120             :     long nOfstX, nOfstY;
     121           0 :     if ( IsVertLR() )
     122             :     {
     123           0 :         nOfstX = rRect.Left() - Frm().Left();
     124           0 :         nOfstY = rRect.Top() - Frm().Top();
     125             :     }
     126             :     else
     127             :     {
     128           0 :         nOfstX = rRect.Left() - Frm().Left();
     129           0 :         nOfstY = rRect.Top() + rRect.Height() - Frm().Top();
     130             :     }
     131             : 
     132           0 :     const long nWidth = rRect.Width();
     133           0 :     const long nHeight = rRect.Height();
     134             : 
     135           0 :     if ( IsVertLR() )
     136           0 :         rRect.Left(Frm().Left() + nOfstY);
     137             :     else
     138             :     {
     139           0 :         if ( bIsSwapped )
     140           0 :             rRect.Left( Frm().Left() + Frm().Height() - nOfstY );
     141             :         else
     142             :             // frame is rotated
     143           0 :             rRect.Left( Frm().Left() + Frm().Width() - nOfstY );
     144             :     }
     145             : 
     146           0 :     rRect.Top( Frm().Top() + nOfstX );
     147           0 :     rRect.Width( nHeight );
     148           0 :     rRect.Height( nWidth );
     149           0 : }
     150             : 
     151             : // Calculates the coordinates of a point when switching from
     152             : // horizontal to vertical layout.
     153          48 : void SwTxtFrm::SwitchHorizontalToVertical( Point& rPoint ) const
     154             : {
     155             :     // calc offset inside frame
     156          48 :     const long nOfstX = rPoint.X() - Frm().Left();
     157          48 :     const long nOfstY = rPoint.Y() - Frm().Top();
     158          48 :     if ( IsVertLR() )
     159           0 :         rPoint.X() = Frm().Left() + nOfstY;
     160             :     else
     161             :     {
     162          48 :         if ( bIsSwapped )
     163          48 :             rPoint.X() = Frm().Left() + Frm().Height() - nOfstY;
     164             :         else
     165             :             // calc rotated coords
     166           0 :             rPoint.X() = Frm().Left() + Frm().Width() - nOfstY;
     167             :     }
     168             : 
     169          48 :     rPoint.Y() = Frm().Top() + nOfstX;
     170          48 : }
     171             : 
     172             : // Calculates the a limit value when switching from
     173             : // horizontal to vertical layout.
     174           0 : long SwTxtFrm::SwitchHorizontalToVertical( long nLimit ) const
     175             : {
     176           0 :     Point aTmp( 0, nLimit );
     177           0 :     SwitchHorizontalToVertical( aTmp );
     178           0 :     return aTmp.X();
     179             : }
     180             : 
     181             : // Calculates the coordinates of a rectangle when switching from
     182             : // vertical to horizontal layout.
     183           0 : void SwTxtFrm::SwitchVerticalToHorizontal( SwRect& rRect ) const
     184             : {
     185             :     long nOfstX;
     186             : 
     187             :     // calc offset inside frame
     188             : 
     189           0 :     if ( IsVertLR() )
     190           0 :         nOfstX = rRect.Left() - Frm().Left();
     191             :     else
     192             :     {
     193           0 :         if ( bIsSwapped )
     194           0 :             nOfstX = Frm().Left() + Frm().Height() - ( rRect.Left() + rRect.Width() );
     195             :         else
     196           0 :             nOfstX = Frm().Left() + Frm().Width() - ( rRect.Left() + rRect.Width() );
     197             :     }
     198             : 
     199           0 :     const long nOfstY = rRect.Top() - Frm().Top();
     200           0 :     const long nWidth = rRect.Height();
     201           0 :     const long nHeight = rRect.Width();
     202             : 
     203             :     // calc rotated coords
     204           0 :     rRect.Left( Frm().Left() + nOfstY );
     205           0 :     rRect.Top( Frm().Top() + nOfstX );
     206           0 :     rRect.Width( nWidth );
     207           0 :     rRect.Height( nHeight );
     208           0 : }
     209             : 
     210             : // Calculates the coordinates of a point when switching from
     211             : // vertical to horizontal layout.
     212           0 : void SwTxtFrm::SwitchVerticalToHorizontal( Point& rPoint ) const
     213             : {
     214             :     long nOfstX;
     215             : 
     216             :     // calc offset inside frame
     217             : 
     218           0 :     if ( IsVertLR() )
     219           0 :         nOfstX = rPoint.X() - Frm().Left();
     220             :     else
     221             :     {
     222           0 :         if ( bIsSwapped )
     223           0 :             nOfstX = Frm().Left() + Frm().Height() - rPoint.X();
     224             :         else
     225           0 :             nOfstX = Frm().Left() + Frm().Width() - rPoint.X();
     226             :     }
     227             : 
     228           0 :     const long nOfstY = rPoint.Y() - Frm().Top();
     229             : 
     230             :     // calc rotated coords
     231           0 :     rPoint.X() = Frm().Left() + nOfstY;
     232           0 :     rPoint.Y() = Frm().Top() + nOfstX;
     233           0 : }
     234             : 
     235             : // Calculates the a limit value when switching from
     236             : // vertical to horizontal layout.
     237           0 : long SwTxtFrm::SwitchVerticalToHorizontal( long nLimit ) const
     238             : {
     239           0 :     Point aTmp( nLimit, 0 );
     240           0 :     SwitchVerticalToHorizontal( aTmp );
     241           0 :     return aTmp.Y();
     242             : }
     243             : 
     244     1493596 : SwFrmSwapper::SwFrmSwapper( const SwTxtFrm* pTxtFrm, bool bSwapIfNotSwapped )
     245     1493596 :     : pFrm( pTxtFrm ), bUndo( false )
     246             : {
     247     1493604 :     if ( pFrm->IsVertical() &&
     248          26 :         ( (   bSwapIfNotSwapped && ! pFrm->IsSwapped() ) ||
     249          36 :           ( ! bSwapIfNotSwapped && pFrm->IsSwapped() ) ) )
     250             :     {
     251           8 :         bUndo = true;
     252           8 :         ((SwTxtFrm*)pFrm)->SwapWidthAndHeight();
     253             :     }
     254     1493596 : }
     255             : 
     256     1493596 : SwFrmSwapper::~SwFrmSwapper()
     257             : {
     258     1493596 :     if ( bUndo )
     259           8 :         ((SwTxtFrm*)pFrm)->SwapWidthAndHeight();
     260     1493596 : }
     261             : 
     262         550 : void SwTxtFrm::SwitchLTRtoRTL( SwRect& rRect ) const
     263             : {
     264         550 :     SWAP_IF_NOT_SWAPPED( this )
     265             : 
     266         550 :     long nWidth = rRect.Width();
     267        1100 :     rRect.Left( 2 * ( Frm().Left() + Prt().Left() ) +
     268        1100 :                 Prt().Width() - rRect.Right() - 1 );
     269             : 
     270         550 :     rRect.Width( nWidth );
     271             : 
     272         550 :     UNDO_SWAP( this )
     273         550 : }
     274             : 
     275          92 : void SwTxtFrm::SwitchLTRtoRTL( Point& rPoint ) const
     276             : {
     277          92 :     SWAP_IF_NOT_SWAPPED( this )
     278             : 
     279          92 :     rPoint.X() = 2 * ( Frm().Left() + Prt().Left() ) + Prt().Width() - rPoint.X() - 1;
     280             : 
     281          92 :     UNDO_SWAP( this )
     282          92 : }
     283             : 
     284       29546 : SwLayoutModeModifier::SwLayoutModeModifier( const OutputDevice& rOutp ) :
     285       29546 :         rOut( rOutp ), nOldLayoutMode( rOutp.GetLayoutMode() )
     286             : {
     287       29546 : }
     288             : 
     289       29546 : SwLayoutModeModifier::~SwLayoutModeModifier()
     290             : {
     291       29546 :     ((OutputDevice&)rOut).SetLayoutMode( nOldLayoutMode );
     292       29546 : }
     293             : 
     294        4204 : void SwLayoutModeModifier::Modify( bool bChgToRTL )
     295             : {
     296             :     ((OutputDevice&)rOut).SetLayoutMode( bChgToRTL ?
     297             :                                          TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL :
     298        4204 :                                          TEXT_LAYOUT_BIDI_STRONG );
     299        4204 : }
     300             : 
     301       25810 : void SwLayoutModeModifier::SetAuto()
     302             : {
     303       25810 :     const ComplexTextLayoutMode nNewLayoutMode = nOldLayoutMode & ~TEXT_LAYOUT_BIDI_STRONG;
     304       25810 :     ((OutputDevice&)rOut).SetLayoutMode( nNewLayoutMode );
     305       25810 : }
     306             : 
     307      207875 : SwDigitModeModifier::SwDigitModeModifier( const OutputDevice& rOutp, LanguageType eCurLang ) :
     308      207875 :         rOut( rOutp ), nOldLanguageType( rOutp.GetDigitLanguage() )
     309             : {
     310      207875 :     LanguageType eLang = eCurLang;
     311      207875 :     const SvtCTLOptions::TextNumerals nTextNumerals = SW_MOD()->GetCTLOptions().GetCTLTextNumerals();
     312             : 
     313      207875 :     if ( SvtCTLOptions::NUMERALS_HINDI == nTextNumerals )
     314           0 :         eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
     315      207875 :     else if ( SvtCTLOptions::NUMERALS_ARABIC == nTextNumerals )
     316      207875 :         eLang = LANGUAGE_ENGLISH;
     317           0 :     else if ( SvtCTLOptions::NUMERALS_SYSTEM == nTextNumerals )
     318           0 :         eLang = ::GetAppLanguage();
     319             : 
     320      207875 :     ((OutputDevice&)rOut).SetDigitLanguage( eLang );
     321      207875 : }
     322             : 
     323      207875 : SwDigitModeModifier::~SwDigitModeModifier()
     324             : {
     325      207875 :     ((OutputDevice&)rOut).SetDigitLanguage( nOldLanguageType );
     326      207875 : }
     327             : 
     328       31840 : void SwTxtFrm::Init()
     329             : {
     330             :     OSL_ENSURE( !IsLocked(), "+SwTxtFrm::Init: this is locked." );
     331       31840 :     if( !IsLocked() )
     332             :     {
     333       31840 :         ClearPara();
     334       31840 :         ResetBlinkPor();
     335             :         // set flags directly to save a ResetPreps call,
     336             :         // and thereby an unnecessary GetPara call
     337             :         // don't set bOrphan, bLocked or bWait to false!
     338             :         // bOrphan = bFlag7 = bFlag8 = false;
     339             :     }
     340       31840 : }
     341             : 
     342       63976 : SwTxtFrm::SwTxtFrm(SwTxtNode * const pNode, SwFrm* pSib )
     343             :     : SwCntntFrm( pNode, pSib )
     344             :     , nAllLines( 0 )
     345             :     , nThisLines( 0 )
     346             :     , mnFlyAnchorOfst( 0 )
     347             :     , mnFlyAnchorOfstNoWrap( 0 )
     348             :     , mnFtnLine( 0 )
     349             :     , mnHeightOfLastLine( 0 ) // OD 2004-03-17 #i11860#
     350             :     , mnAdditionalFirstLineOffset( 0 )
     351             :     , nOfst( 0 )
     352             :     , nCacheIdx( USHRT_MAX )
     353             :     , bLocked( false )
     354             :     , bWidow( false )
     355             :     , bJustWidow( false )
     356             :     , bEmpty( false )
     357             :     , bInFtnConnect( false )
     358             :     , bFtn( false )
     359             :     , bRepaint( false )
     360             :     , bBlinkPor( false )
     361             :     , bFieldFollow( false )
     362             :     , bHasAnimation( false )
     363             :     , bIsSwapped( false )
     364       63976 :     , mbFollowFormatAllowed( true ) // OD 14.03.2003 #i11760#
     365             : {
     366       63976 :     mnType = FRMC_TXT;
     367       63976 : }
     368             : 
     369      191700 : SwTxtFrm::~SwTxtFrm()
     370             : {
     371             :     // Remove associated SwParaPortion from pTxtCache
     372       63900 :     ClearPara();
     373             : 
     374             :     const SwCntntNode* pCNd;
     375      255600 :     if( 0 != ( pCNd = PTR_CAST( SwCntntNode, GetRegisteredIn() )) &&
     376      255600 :         !pCNd->GetDoc()->IsInDtor() && HasFtn() )
     377             :     {
     378         132 :         SwTxtNode *pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
     379         132 :         const SwFtnIdxs &rFtnIdxs = pCNd->GetDoc()->GetFtnIdxs();
     380         132 :         size_t nPos = 0;
     381         132 :         sal_uLong nIndex = pCNd->GetIndex();
     382         132 :         rFtnIdxs.SeekEntry( *pTxtNd, &nPos );
     383             :         SwTxtFtn* pTxtFtn;
     384         132 :         if( nPos < rFtnIdxs.size() )
     385             :         {
     386         292 :             while( nPos && pTxtNd == &(rFtnIdxs[ nPos ]->GetTxtNode()) )
     387          28 :                 --nPos;
     388         132 :             if( nPos || pTxtNd != &(rFtnIdxs[ nPos ]->GetTxtNode()) )
     389          26 :                 ++nPos;
     390             :         }
     391         410 :         while( nPos < rFtnIdxs.size() )
     392             :         {
     393         172 :             pTxtFtn = rFtnIdxs[ nPos ];
     394         172 :             if( pTxtFtn->GetTxtNode().GetIndex() > nIndex )
     395          26 :                 break;
     396         146 :             pTxtFtn->DelFrms( this );
     397         146 :             ++nPos;
     398             :         }
     399             :     }
     400      127800 : }
     401             : 
     402      356747 : const OUString& SwTxtFrm::GetTxt() const
     403             : {
     404      356747 :     return GetTxtNode()->GetTxt();
     405             : }
     406             : 
     407       29440 : void SwTxtFrm::ResetPreps()
     408             : {
     409       29440 :     if ( GetCacheIdx() != USHRT_MAX )
     410             :     {
     411             :         SwParaPortion *pPara;
     412       29440 :         if( 0 != (pPara = GetPara()) )
     413       29436 :             pPara->ResetPreps();
     414             :     }
     415       29440 : }
     416             : 
     417     1006839 : bool SwTxtFrm::IsHiddenNow() const
     418             : {
     419     1006839 :     SwFrmSwapper aSwapper( this, true );
     420             : 
     421     1006839 :     if( !Frm().Width() && IsValid() && GetUpper()->IsValid() )
     422             :                                        // invalid when stack overflows (StackHack)!
     423             :     {
     424             : //        OSL_FAIL( "SwTxtFrm::IsHiddenNow: thin frame" );
     425           0 :         return true;
     426             :     }
     427             : 
     428     1006839 :     const bool bHiddenCharsHidePara = GetTxtNode()->HasHiddenCharAttribute( true );
     429     1006839 :     const bool bHiddenParaField = GetTxtNode()->HasHiddenParaField();
     430     1006839 :     const SwViewShell* pVsh = getRootFrm()->GetCurrShell();
     431             : 
     432     1006839 :     if ( pVsh && ( bHiddenCharsHidePara || bHiddenParaField ) )
     433             :     {
     434        2132 :         if (
     435           0 :              ( bHiddenParaField &&
     436           0 :                ( !pVsh->GetViewOptions()->IsShowHiddenPara() &&
     437        6396 :                  !pVsh->GetViewOptions()->IsFldName() ) ) ||
     438        2132 :              ( bHiddenCharsHidePara &&
     439        2132 :                !pVsh->GetViewOptions()->IsShowHiddenChar() ) )
     440             :         {
     441        2132 :             return true;
     442             :         }
     443             :     }
     444             : 
     445     1004707 :     return false;
     446             : }
     447             : 
     448             : // removes Textfrm's attachments, when it's hidden
     449          46 : void SwTxtFrm::HideHidden()
     450             : {
     451             :     OSL_ENSURE( !GetFollow() && IsHiddenNow(),
     452             :             "HideHidden on visible frame of hidden frame has follow" );
     453             : 
     454          46 :     const sal_Int32 nEnd = COMPLETE_STRING;
     455          46 :     HideFootnotes( GetOfst(), nEnd );
     456             :     // OD 2004-01-15 #110582#
     457          46 :     HideAndShowObjects();
     458             : 
     459             :     // format information is obsolete
     460          46 :     ClearPara();
     461          46 : }
     462             : 
     463          54 : void SwTxtFrm::HideFootnotes( sal_Int32 nStart, sal_Int32 nEnd )
     464             : {
     465          54 :     const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
     466          54 :     if( pHints )
     467             :     {
     468          54 :         const size_t nSize = pHints->Count();
     469          54 :         SwPageFrm *pPage = 0;
     470         160 :         for ( size_t i = 0; i < nSize; ++i )
     471             :         {
     472         106 :             const SwTxtAttr *pHt = (*pHints)[i];
     473         106 :             if ( pHt->Which() == RES_TXTATR_FTN )
     474             :             {
     475           0 :                 const sal_Int32 nIdx = pHt->GetStart();
     476           0 :                 if ( nEnd < nIdx )
     477           0 :                     break;
     478           0 :                 if( nStart <= nIdx )
     479             :                 {
     480           0 :                     if( !pPage )
     481           0 :                         pPage = FindPageFrm();
     482           0 :                     pPage->RemoveFtn( this, (SwTxtFtn*)pHt );
     483             :                 }
     484             :             }
     485             :         }
     486             :     }
     487          54 : }
     488             : 
     489             : // #120729# - hotfix
     490             : // as-character anchored graphics, which are used for a graphic bullet list.
     491             : // As long as these graphic bullet list aren't imported, do not hide a
     492             : // at-character anchored object, if
     493             : // (a) the document is an imported WW8 document -
     494             : //     checked by checking certain compatibility options -,
     495             : // (b) the paragraph is the last content in the document and
     496             : // (c) the anchor character is an as-character anchored graphic.
     497           0 : bool sw_HideObj( const SwTxtFrm& _rFrm,
     498             :                   const RndStdIds _eAnchorType,
     499             :                   const sal_Int32 _nObjAnchorPos,
     500             :                   SwAnchoredObject* _pAnchoredObj )
     501             : {
     502           0 :     bool bRet( true );
     503             : 
     504           0 :     if (_eAnchorType == FLY_AT_CHAR)
     505             :     {
     506           0 :         const IDocumentSettingAccess* pIDSA = _rFrm.GetTxtNode()->getIDocumentSettingAccess();
     507           0 :         if ( !pIDSA->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING) &&
     508           0 :              !pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING) &&
     509           0 :              !pIDSA->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) &&
     510           0 :               pIDSA->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) &&
     511           0 :              _rFrm.IsInDocBody() && !_rFrm.FindNextCnt() )
     512             :         {
     513             :             const sal_Unicode cAnchorChar =
     514           0 :                         _rFrm.GetTxtNode()->GetTxt()[_nObjAnchorPos];
     515           0 :             if ( cAnchorChar == CH_TXTATR_BREAKWORD )
     516             :             {
     517             :                 const SwTxtAttr* const pHint(
     518             :                     _rFrm.GetTxtNode()->GetTxtAttrForCharAt(_nObjAnchorPos,
     519           0 :                         RES_TXTATR_FLYCNT) );
     520           0 :                 if ( pHint )
     521             :                 {
     522             :                     const SwFrmFmt* pFrmFmt =
     523           0 :                         static_cast<const SwTxtFlyCnt*>(pHint)->GetFlyCnt().GetFrmFmt();
     524           0 :                     if ( pFrmFmt->Which() == RES_FLYFRMFMT )
     525             :                     {
     526           0 :                         SwNodeIndex nCntntIndex = *(pFrmFmt->GetCntnt().GetCntntIdx());
     527           0 :                         ++nCntntIndex;
     528           0 :                         if ( nCntntIndex.GetNode().IsNoTxtNode() )
     529             :                         {
     530           0 :                             bRet = false;
     531             :                             // set needed data structure values for object positioning
     532           0 :                             SWRECTFN( (&_rFrm) );
     533           0 :                             SwRect aLastCharRect( _rFrm.Frm() );
     534           0 :                             (aLastCharRect.*fnRect->fnSetWidth)( 1 );
     535           0 :                             _pAnchoredObj->maLastCharRect = aLastCharRect;
     536           0 :                             _pAnchoredObj->mnLastTopOfLine = (aLastCharRect.*fnRect->fnGetTop)();
     537           0 :                         }
     538             :                     }
     539             :                 }
     540             :             }
     541             :         }
     542             :     }
     543             : 
     544           0 :     return bRet;
     545             : }
     546             : 
     547             : /** method to hide/show objects
     548             : 
     549             :     OD 2004-01-15 #110582#
     550             :     method hides respectively shows objects, which are anchored at paragraph,
     551             :     at/as a character of the paragraph, corresponding to the paragraph and
     552             :     paragraph portion visibility.
     553             : 
     554             :     - is called from HideHidden() - should hide objects in hidden paragraphs and
     555             :     - from _Format() - should hide/show objects in partly visible paragraphs
     556             : */
     557      121467 : void SwTxtFrm::HideAndShowObjects()
     558             : {
     559      121467 :     if ( GetDrawObjs() )
     560             :     {
     561       12312 :         if ( IsHiddenNow() )
     562             :         {
     563             :             // complete paragraph is hidden. Thus, hide all objects
     564           0 :             for ( size_t i = 0; i < GetDrawObjs()->size(); ++i )
     565             :             {
     566           0 :                 SdrObject* pObj = (*GetDrawObjs())[i]->DrawObj();
     567           0 :                 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
     568             :                 // #120729# - hotfix
     569             :                 // under certain conditions
     570           0 :                 const RndStdIds eAnchorType( pContact->GetAnchorId() );
     571           0 :                 const sal_Int32 nObjAnchorPos = pContact->GetCntntAnchorIndex().GetIndex();
     572           0 :                 if ((eAnchorType != FLY_AT_CHAR) ||
     573             :                     sw_HideObj( *this, eAnchorType, nObjAnchorPos,
     574           0 :                                  (*GetDrawObjs())[i] ))
     575             :                 {
     576           0 :                     pContact->MoveObjToInvisibleLayer( pObj );
     577             :                 }
     578             :             }
     579             :         }
     580             :         else
     581             :         {
     582             :             // paragraph is visible, but can contain hidden text portion.
     583             :             // first we check if objects are allowed to be hidden:
     584       12312 :             const SwTxtNode& rNode = *GetTxtNode();
     585       12312 :             const SwViewShell* pVsh = getRootFrm()->GetCurrShell();
     586       24624 :             const bool bShouldBeHidden = !pVsh || !pVsh->GetWin() ||
     587       24624 :                                          !pVsh->GetViewOptions()->IsShowHiddenChar();
     588             : 
     589             :             // Thus, show all objects, which are anchored at paragraph and
     590             :             // hide/show objects, which are anchored at/as character, according
     591             :             // to the visibility of the anchor character.
     592      127676 :             for ( size_t i = 0; i < GetDrawObjs()->size(); ++i )
     593             :             {
     594      115364 :                 SdrObject* pObj = (*GetDrawObjs())[i]->DrawObj();
     595      115364 :                 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
     596             :                 // #120729# - determine anchor type only once
     597      115364 :                 const RndStdIds eAnchorType( pContact->GetAnchorId() );
     598             : 
     599      115364 :                 if (eAnchorType == FLY_AT_PARA)
     600             :                 {
     601      109380 :                     pContact->MoveObjToVisibleLayer( pObj );
     602             :                 }
     603        5984 :                 else if ((eAnchorType == FLY_AT_CHAR) ||
     604             :                          (eAnchorType == FLY_AS_CHAR))
     605             :                 {
     606             :                     sal_Int32 nHiddenStart;
     607             :                     sal_Int32 nHiddenEnd;
     608        5984 :                     const sal_Int32 nObjAnchorPos = pContact->GetCntntAnchorIndex().GetIndex();
     609        5984 :                     SwScriptInfo::GetBoundsOfHiddenRange( rNode, nObjAnchorPos, nHiddenStart, nHiddenEnd, 0 );
     610             :                     // #120729# - hotfix
     611             :                     // under certain conditions
     612        5984 :                     if ( nHiddenStart != COMPLETE_STRING && bShouldBeHidden &&
     613           0 :                          sw_HideObj( *this, eAnchorType, nObjAnchorPos, (*GetDrawObjs())[i] ) )
     614           0 :                         pContact->MoveObjToInvisibleLayer( pObj );
     615             :                     else
     616        5984 :                         pContact->MoveObjToVisibleLayer( pObj );
     617             :                 }
     618             :                 else
     619             :                 {
     620             :                     OSL_FAIL( "<SwTxtFrm::HideAndShowObjects()> - object not anchored at/inside paragraph!?" );
     621             :                 }
     622             :             }
     623             :         }
     624             :     }
     625             : 
     626      121467 :     if (IsFollow())
     627             :     {
     628        7352 :         SwTxtFrm *pMaster = FindMaster();
     629             :         OSL_ENSURE(pMaster, "SwTxtFrm without master");
     630        7352 :         if (pMaster)
     631        7352 :             pMaster->HideAndShowObjects();
     632             :     }
     633      121467 : }
     634             : 
     635             : // Returns the first possible break point in the current line.
     636             : // This method is used in SwTxtFrm::Format() to decide whether the previous
     637             : // line has to be formatted as well.
     638             : // nFound is <= nEndLine.
     639        2891 : sal_Int32 SwTxtFrm::FindBrk( const OUString &rTxt,
     640             :                               const sal_Int32 nStart,
     641             :                               const sal_Int32 nEnd ) const
     642             : {
     643        2891 :     sal_Int32 nFound = nStart;
     644        2891 :     const sal_Int32 nEndLine = std::min( nEnd, rTxt.getLength() - 1 );
     645             : 
     646             :     // skip all leading blanks (see bug #2235).
     647        5788 :     while( nFound <= nEndLine && ' ' == rTxt[nFound] )
     648             :     {
     649           6 :          nFound++;
     650             :     }
     651             : 
     652             :     // A tricky situation with the TxtAttr-Dummy-character (in this case "$"):
     653             :     // "Dr.$Meyer" at the beginning of the second line. Typing a blank after that
     654             :     // doesn't result in the word moving into first line, even though that would work.
     655             :     // For this reason we don't skip the dummy char.
     656       69753 :     while( nFound <= nEndLine && ' ' != rTxt[nFound] )
     657             :     {
     658       63971 :         nFound++;
     659             :     }
     660             : 
     661        2891 :     return nFound;
     662             : }
     663             : 
     664       40813 : bool SwTxtFrm::IsIdxInside( const sal_Int32 nPos, const sal_Int32 nLen ) const
     665             : {
     666       40813 :     if( nLen != COMPLETE_STRING && GetOfst() > nPos + nLen ) // the range preceded us
     667         380 :         return false;
     668             : 
     669       40433 :     if( !GetFollow() )            // the range doesn't precede us,
     670       38517 :         return true;          // nobody follows us.
     671             : 
     672        1916 :     const sal_Int32 nMax = GetFollow()->GetOfst();
     673             : 
     674             :     // either the range overlap or our text has been deleted
     675        1916 :     if( nMax > nPos || nMax > GetTxt().getLength() )
     676         508 :         return true;
     677             : 
     678             :     // changes made in the first line of a follow can modify the master
     679        1408 :     const SwParaPortion* pPara = GetFollow()->GetPara();
     680        1408 :     return pPara && ( nPos <= nMax + pPara->GetLen() );
     681             : }
     682             : 
     683       12839 : inline void SwTxtFrm::InvalidateRange(const SwCharRange &aRange, const long nD)
     684             : {
     685       12839 :     if ( IsIdxInside( aRange.Start(), aRange.Len() ) )
     686       12793 :         _InvalidateRange( aRange, nD );
     687       12839 : }
     688             : 
     689       37661 : void SwTxtFrm::_InvalidateRange( const SwCharRange &aRange, const long nD)
     690             : {
     691       37661 :     if ( !HasPara() )
     692       17472 :     {   InvalidateSize();
     693       55133 :         return;
     694             :     }
     695             : 
     696       20189 :     SetWidow( false );
     697       20189 :     SwParaPortion *pPara = GetPara();
     698             : 
     699       20189 :     bool bInv = false;
     700       20189 :     if( 0 != nD )
     701             :     {
     702             :         // In nDelta the differences betwen old and new
     703             :         // linelengths are being added, that's why it's negative
     704             :         // if chars have been added and positive, if chars have
     705             :         // deleted
     706       12476 :         pPara->GetDelta() += nD;
     707       12476 :         bInv = true;
     708             :     }
     709       20189 :     SwCharRange &rReformat = pPara->GetReformat();
     710       20189 :     if(aRange != rReformat) {
     711       16137 :         if( COMPLETE_STRING == rReformat.Len() )
     712           0 :             rReformat = aRange;
     713             :         else
     714       16137 :             rReformat += aRange;
     715       16137 :         bInv = true;
     716             :     }
     717       20189 :     if(bInv)
     718             :     {
     719       16507 :         InvalidateSize();
     720             :     }
     721             : }
     722             : 
     723         134 : void SwTxtFrm::CalcLineSpace()
     724             : {
     725             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
     726             :             "SwTxtFrm::CalcLineSpace with swapped frame!" );
     727             : 
     728         134 :     if( IsLocked() || !HasPara() )
     729         264 :         return;
     730             : 
     731             :     SwParaPortion *pPara;
     732           6 :     if( GetDrawObjs() ||
     733           6 :         GetTxtNode()->GetSwAttrSet().GetLRSpace().IsAutoFirst() ||
     734           2 :         ( pPara = GetPara() )->IsFixLineHeight() )
     735             :     {
     736           0 :         Init();
     737           0 :         return;
     738             :     }
     739             : 
     740           2 :     Size aNewSize( Prt().SSize() );
     741             : 
     742           2 :     SwTxtFormatInfo aInf( this );
     743           4 :     SwTxtFormatter aLine( this, &aInf );
     744           2 :     if( aLine.GetDropLines() )
     745             :     {
     746           0 :         Init();
     747           0 :         return;
     748             :     }
     749             : 
     750           2 :     aLine.Top();
     751           2 :     aLine.RecalcRealHeight();
     752             : 
     753           2 :     aNewSize.Height() = (aLine.Y() - Frm().Top()) + aLine.GetLineHeight();
     754             : 
     755           2 :     SwTwips nDelta = aNewSize.Height() - Prt().Height();
     756             :     // 4291: underflow with free-flying frames
     757           2 :     if( aInf.GetTxtFly().IsOn() )
     758             :     {
     759           0 :         SwRect aTmpFrm( Frm() );
     760           0 :         if( nDelta < 0 )
     761           0 :             aTmpFrm.Height( Prt().Height() );
     762             :         else
     763           0 :             aTmpFrm.Height( aNewSize.Height() );
     764           0 :         if( aInf.GetTxtFly().Relax( aTmpFrm ) )
     765             :         {
     766           0 :             Init();
     767           0 :             return;
     768             :         }
     769             :     }
     770             : 
     771           2 :     if( nDelta )
     772             :     {
     773           0 :         SwTxtFrmBreak aBreak( this );
     774           0 :         if( GetFollow() || aBreak.IsBreakNow( aLine ) )
     775             :         {
     776             :             // if there is a Follow() or if we need to break here, reformat
     777           0 :             Init();
     778             :         }
     779             :         else
     780             :         {
     781             :             // everything is business as usual...
     782           0 :             pPara->SetPrepAdjust();
     783           0 :             pPara->SetPrep();
     784             :         }
     785           2 :     }
     786             : }
     787             : 
     788       26420 : static void lcl_SetWrong( SwTxtFrm& rFrm, sal_Int32 nPos, sal_Int32 nCnt, bool bMove )
     789             : {
     790       26420 :     if ( !rFrm.IsFollow() )
     791             :     {
     792       24652 :         SwTxtNode* pTxtNode = rFrm.GetTxtNode();
     793       24652 :         IGrammarContact* pGrammarContact = getGrammarContact( *pTxtNode );
     794             :         SwGrammarMarkUp* pWrongGrammar = pGrammarContact ?
     795       24652 :             pGrammarContact->getGrammarCheck( *pTxtNode, false ) :
     796       49304 :             pTxtNode->GetGrammarCheck();
     797       24652 :         bool bGrammarProxy = pWrongGrammar != pTxtNode->GetGrammarCheck();
     798       24652 :         if( bMove )
     799             :         {
     800       19384 :             if( pTxtNode->GetWrong() )
     801        1440 :                 pTxtNode->GetWrong()->Move( nPos, nCnt );
     802       19384 :             if( pWrongGrammar )
     803           0 :                 pWrongGrammar->MoveGrammar( nPos, nCnt );
     804       19384 :             if( bGrammarProxy && pTxtNode->GetGrammarCheck() )
     805           0 :                 pTxtNode->GetGrammarCheck()->MoveGrammar( nPos, nCnt );
     806       19384 :             if( pTxtNode->GetSmartTags() )
     807           0 :                 pTxtNode->GetSmartTags()->Move( nPos, nCnt );
     808             :         }
     809             :         else
     810             :         {
     811        5268 :             if( pTxtNode->GetWrong() )
     812           6 :                 pTxtNode->GetWrong()->Invalidate( nPos, nCnt );
     813        5268 :             if( pWrongGrammar )
     814           0 :                 pWrongGrammar->Invalidate( nPos, nCnt );
     815        5268 :             if( pTxtNode->GetSmartTags() )
     816           0 :                 pTxtNode->GetSmartTags()->Invalidate( nPos, nCnt );
     817             :         }
     818       24652 :         const sal_Int32 nEnd = nPos + (nCnt > 0 ? nCnt : 1 );
     819       24652 :         if ( !pTxtNode->GetWrong() && !pTxtNode->IsWrongDirty() )
     820             :         {
     821          35 :             pTxtNode->SetWrong( new SwWrongList( WRONGLIST_SPELL ) );
     822          35 :             pTxtNode->GetWrong()->SetInvalid( nPos, nEnd );
     823             :         }
     824       24652 :         if ( !pTxtNode->GetSmartTags() && !pTxtNode->IsSmartTagDirty() )
     825             :         {
     826           0 :             pTxtNode->SetSmartTags( new SwWrongList( WRONGLIST_SMARTTAG ) );
     827           0 :             pTxtNode->GetSmartTags()->SetInvalid( nPos, nEnd );
     828             :         }
     829       24652 :         pTxtNode->SetWrongDirty( true );
     830       24652 :         pTxtNode->SetGrammarCheckDirty( true );
     831       24652 :         pTxtNode->SetWordCountDirty( true );
     832       24652 :         pTxtNode->SetAutoCompleteWordDirty( true );
     833       24652 :         pTxtNode->SetSmartTagDirty( true );
     834             :     }
     835             : 
     836       26420 :     SwRootFrm *pRootFrm = rFrm.getRootFrm();
     837       26420 :     if (pRootFrm)
     838             :     {
     839       26420 :         pRootFrm->SetNeedGrammarCheck( true );
     840             :     }
     841             : 
     842       26420 :     SwPageFrm *pPage = rFrm.FindPageFrm();
     843       26420 :     if( pPage )
     844             :     {
     845       26420 :         pPage->InvalidateSpelling();
     846       26420 :         pPage->InvalidateAutoCompleteWords();
     847       26420 :         pPage->InvalidateWordCount();
     848       26420 :         pPage->InvalidateSmartTags();
     849             :     }
     850       26420 : }
     851             : 
     852       28732 : static void lcl_SetScriptInval( SwTxtFrm& rFrm, sal_Int32 nPos )
     853             : {
     854       28732 :     if( rFrm.GetPara() )
     855        9724 :         rFrm.GetPara()->GetScriptInfo().SetInvalidityA( nPos );
     856       28732 : }
     857             : 
     858        1768 : static void lcl_ModifyOfst( SwTxtFrm* pFrm, sal_Int32 nPos, sal_Int32 nLen )
     859             : {
     860        6922 :     while( pFrm && pFrm->GetOfst() <= nPos )
     861        3386 :         pFrm = pFrm->GetFollow();
     862        4428 :     while( pFrm )
     863             :     {
     864         892 :         if (nLen == COMPLETE_STRING)
     865          40 :             pFrm->ManipOfst( pFrm->GetTxtNode()->GetTxt().getLength() );
     866             :         else
     867         852 :             pFrm->ManipOfst( pFrm->GetOfst() + nLen );
     868         892 :         pFrm = pFrm->GetFollow();
     869             :     }
     870        1768 : }
     871             : 
     872             : // Related: fdo#56031 filter out attribute changes that don't matter for
     873             : // humans/a11y to stop flooding the destination mortal with useless noise
     874       14166 : static bool isA11yRelevantAttribute(sal_uInt16 nWhich)
     875             : {
     876       14166 :     return nWhich != RES_CHRATR_RSID;
     877             : }
     878             : 
     879        5782 : static bool hasA11yRelevantAttribute( const std::vector<sal_uInt16>& nWhich )
     880             : {
     881       17346 :     for( std::vector<sal_uInt16>::const_iterator nItr = nWhich.begin();
     882       11564 :             nItr < nWhich.end(); ++nItr )
     883           0 :         if ( isA11yRelevantAttribute( *nItr ) )
     884           0 :             return true;
     885             : 
     886        5782 :     return false;
     887             : }
     888             : 
     889       39362 : void SwTxtFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
     890             : {
     891       39362 :     const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
     892             : 
     893             :     // modifications concerning frame attributes are processed by the base class
     894       39362 :     if( IsInRange( aFrmFmtSetRange, nWhich ) || RES_FMT_CHG == nWhich )
     895             :     {
     896        1302 :         SwCntntFrm::Modify( pOld, pNew );
     897        1302 :         if( nWhich == RES_FMT_CHG && getRootFrm()->GetCurrShell() )
     898             :         {
     899             :             // collection has changed
     900         550 :             Prepare( PREP_CLEAR );
     901         550 :             _InvalidatePrt();
     902         550 :             lcl_SetWrong( *this, 0, COMPLETE_STRING, false );
     903         550 :             SetDerivedR2L( false );
     904         550 :             CheckDirChange();
     905             :             // OD 09.12.2002 #105576# - Force complete paint due to existing
     906             :             // indents.
     907         550 :             SetCompletePaint();
     908         550 :             InvalidateLineNum();
     909             :         }
     910        1302 :         return;
     911             :     }
     912             : 
     913             :     // while locked ignore all modifications
     914       38060 :     if( IsLocked() )
     915           0 :         return;
     916             : 
     917             :     // save stack
     918             :     // warning: one has to ensure that all variables are set
     919             :     sal_Int32 nPos;
     920             :     sal_Int32 nLen;
     921       38060 :     bool bSetFldsDirty = false;
     922       38060 :     bool bRecalcFtnFlag = false;
     923             : 
     924       38060 :     switch( nWhich )
     925             :     {
     926             :         case RES_LINENUMBER:
     927             :         {
     928           0 :             InvalidateLineNum();
     929             :         }
     930           0 :         break;
     931             :         case RES_INS_TXT:
     932             :         {
     933       18724 :             nPos = ((SwInsTxt*)pNew)->nPos;
     934       18724 :             nLen = ((SwInsTxt*)pNew)->nLen;
     935       18724 :             if( IsIdxInside( nPos, nLen ) )
     936             :             {
     937       17756 :                 if( !nLen )
     938             :                 {
     939             :                     // 6969: refresh NumPortions even when line is empty!
     940           0 :                     if( nPos )
     941           0 :                         InvalidateSize();
     942             :                     else
     943           0 :                         Prepare( PREP_CLEAR );
     944             :                 }
     945             :                 else
     946       17756 :                     _InvalidateRange( SwCharRange( nPos, nLen ), nLen );
     947             :             }
     948       18724 :             lcl_SetWrong( *this, nPos, nLen, true );
     949       18724 :             lcl_SetScriptInval( *this, nPos );
     950       18724 :             bSetFldsDirty = true;
     951       18724 :             if( HasFollow() )
     952         994 :                 lcl_ModifyOfst( this, nPos, nLen );
     953             :         }
     954       18724 :         break;
     955             :         case RES_DEL_CHR:
     956             :         {
     957         386 :             nPos = ((SwDelChr*)pNew)->nPos;
     958         386 :             InvalidateRange( SwCharRange( nPos, 1 ), -1 );
     959         386 :             lcl_SetWrong( *this, nPos, -1, true );
     960         386 :             lcl_SetScriptInval( *this, nPos );
     961         386 :             bSetFldsDirty = bRecalcFtnFlag = true;
     962         386 :             if( HasFollow() )
     963          44 :                 lcl_ModifyOfst( this, nPos, COMPLETE_STRING );
     964             :         }
     965         386 :         break;
     966             :         case RES_DEL_TXT:
     967             :         {
     968        2042 :             nPos = ((SwDelTxt*)pNew)->nStart;
     969        2042 :             nLen = ((SwDelTxt*)pNew)->nLen;
     970        2042 :             const sal_Int32 m = -nLen;
     971        2042 :             if( IsIdxInside( nPos, nLen ) )
     972             :             {
     973        1322 :                 if( !nLen )
     974          48 :                     InvalidateSize();
     975             :                 else
     976        1274 :                     InvalidateRange( SwCharRange( nPos, 1 ), m );
     977             :             }
     978        2042 :             lcl_SetWrong( *this, nPos, m, true );
     979        2042 :             lcl_SetScriptInval( *this, nPos );
     980        2042 :             bSetFldsDirty = bRecalcFtnFlag = true;
     981        2042 :             if( HasFollow() )
     982         730 :                 lcl_ModifyOfst( this, nPos, nLen );
     983             :         }
     984        2042 :         break;
     985             :         case RES_UPDATE_ATTR:
     986             :         {
     987        5782 :             nPos = ((SwUpdateAttr*)pNew)->getStart();
     988        5782 :             nLen = ((SwUpdateAttr*)pNew)->getEnd() - nPos;
     989        5782 :             if( IsIdxInside( nPos, nLen ) )
     990             :             {
     991             :                 // Es muss in jedem Fall neu formatiert werden,
     992             :                 // auch wenn der invalidierte Bereich null ist.
     993             :                 // Beispiel: leere Zeile, 14Pt einstellen !
     994             :                 // if( !nLen ) nLen = 1;
     995             : 
     996             :                 // 6680: FtnNummern muessen formatiert werden.
     997        5782 :                 if( !nLen )
     998        1366 :                     nLen = 1;
     999             : 
    1000        5782 :                 _InvalidateRange( SwCharRange( nPos, nLen) );
    1001        5782 :                 const sal_uInt16 nTmp = ((SwUpdateAttr*)pNew)->getWhichAttr();
    1002             : 
    1003        5782 :                 if( ! nTmp || RES_TXTATR_CHARFMT == nTmp || RES_TXTATR_AUTOFMT == nTmp ||
    1004        1666 :                     RES_FMT_CHG == nTmp || RES_ATTRSET_CHG == nTmp )
    1005             :                 {
    1006        4382 :                     lcl_SetWrong( *this, nPos, nPos + nLen, false );
    1007        4382 :                     lcl_SetScriptInval( *this, nPos );
    1008             :                 }
    1009             :             }
    1010             : 
    1011       11564 :             if( isA11yRelevantAttribute( ((SwUpdateAttr*)pNew)->getWhichAttr() ) &&
    1012        5782 :                     hasA11yRelevantAttribute( ((SwUpdateAttr*)pNew)->getFmtAttr() ) )
    1013             :             {
    1014             :                 // #i104008#
    1015           0 :                 SwViewShell* pViewSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
    1016           0 :                 if ( pViewSh  )
    1017             :                 {
    1018           0 :                     pViewSh->InvalidateAccessibleParaAttrs( *this );
    1019             :                 }
    1020             :             }
    1021             :         }
    1022        5782 :         break;
    1023             :         case RES_OBJECTDYING:
    1024           0 :         break;
    1025             : 
    1026             :         case RES_PARATR_LINESPACING:
    1027             :             {
    1028           0 :                 CalcLineSpace();
    1029           0 :                 InvalidateSize();
    1030           0 :                 _InvalidatePrt();
    1031           0 :                 if( IsInSct() && !GetPrev() )
    1032             :                 {
    1033           0 :                     SwSectionFrm *pSect = FindSctFrm();
    1034           0 :                     if( pSect->ContainsAny() == this )
    1035           0 :                         pSect->InvalidatePrt();
    1036             :                 }
    1037             : 
    1038             :                 // OD 09.01.2004 #i11859# - correction:
    1039             :                 //  (1) Also invalidate next frame on next page/column.
    1040             :                 //  (2) Skip empty sections and hidden paragraphs
    1041             :                 //  Thus, use method <InvalidateNextPrtArea()>
    1042           0 :                 InvalidateNextPrtArea();
    1043             : 
    1044           0 :                 SetCompletePaint();
    1045             :             }
    1046           0 :             break;
    1047             : 
    1048             :         case RES_TXTATR_FIELD:
    1049             :         case RES_TXTATR_ANNOTATION:
    1050             :             {
    1051        1312 :                 nPos = ((SwFmtFld*)pNew)->GetTxtFld()->GetStart();
    1052        1312 :                 if( IsIdxInside( nPos, 1 ) )
    1053             :                 {
    1054        1312 :                     if( pNew == pOld )
    1055             :                     {
    1056             :                         // only repaint
    1057             :                         // opt: invalidate window?
    1058           0 :                         InvalidatePage();
    1059           0 :                         SetCompletePaint();
    1060             :                     }
    1061             :                     else
    1062        1312 :                         _InvalidateRange( SwCharRange( nPos, 1 ) );
    1063             :                 }
    1064        1312 :                 bSetFldsDirty = true;
    1065             :                 // ST2
    1066        1312 :                 if ( SwSmartTagMgr::Get().IsSmartTagsEnabled() )
    1067           0 :                     lcl_SetWrong( *this, nPos, nPos + 1, false );
    1068             :             }
    1069        1312 :             break;
    1070             : 
    1071             :         case RES_TXTATR_FTN :
    1072             :         {
    1073         166 :             nPos = ((SwFmtFtn*)pNew)->GetTxtFtn()->GetStart();
    1074         166 :             if( IsInFtn() || IsIdxInside( nPos, 1 ) )
    1075         166 :                 Prepare( PREP_FTN, ((SwFmtFtn*)pNew)->GetTxtFtn() );
    1076         166 :             break;
    1077             :         }
    1078             : 
    1079             :         case RES_ATTRSET_CHG:
    1080             :         {
    1081        8384 :             InvalidateLineNum();
    1082             : 
    1083        8384 :             SwAttrSet& rNewSet = *((SwAttrSetChg*)pNew)->GetChgSet();
    1084        8384 :             const SfxPoolItem* pItem = 0;
    1085        8384 :             int nClear = 0;
    1086        8384 :             sal_uInt16 nCount = rNewSet.Count();
    1087             : 
    1088        8384 :             if( SfxItemState::SET == rNewSet.GetItemState( RES_TXTATR_FTN, false, &pItem ))
    1089             :             {
    1090           0 :                 nPos = ((SwFmtFtn*)pItem)->GetTxtFtn()->GetStart();
    1091           0 :                 if( IsIdxInside( nPos, 1 ) )
    1092           0 :                     Prepare( PREP_FTN, pNew );
    1093           0 :                 nClear = 0x01;
    1094           0 :                 --nCount;
    1095             :             }
    1096             : 
    1097        8384 :             if( SfxItemState::SET == rNewSet.GetItemState( RES_TXTATR_FIELD, false, &pItem ))
    1098             :             {
    1099           0 :                 nPos = ((SwFmtFld*)pItem)->GetTxtFld()->GetStart();
    1100           0 :                 if( IsIdxInside( nPos, 1 ) )
    1101             :                 {
    1102             :                     const SfxPoolItem& rOldItem =
    1103           0 :                         ((SwAttrSetChg*)pOld)->GetChgSet()->Get( RES_TXTATR_FIELD );
    1104           0 :                     if( pItem == &rOldItem )
    1105             :                     {
    1106           0 :                         InvalidatePage();
    1107           0 :                         SetCompletePaint();
    1108             :                     }
    1109             :                     else
    1110           0 :                         _InvalidateRange( SwCharRange( nPos, 1 ) );
    1111             :                 }
    1112           0 :                 nClear |= 0x02;
    1113           0 :                 --nCount;
    1114             :             }
    1115             :             bool bLineSpace = SfxItemState::SET == rNewSet.GetItemState(
    1116        8384 :                                             RES_PARATR_LINESPACING, false ),
    1117             :                      bRegister  = SfxItemState::SET == rNewSet.GetItemState(
    1118        8384 :                                             RES_PARATR_REGISTER, false );
    1119        8384 :             if ( bLineSpace || bRegister )
    1120             :             {
    1121         134 :                 Prepare( bRegister ? PREP_REGISTER : PREP_ADJUST_FRM );
    1122         134 :                 CalcLineSpace();
    1123         134 :                 InvalidateSize();
    1124         134 :                 _InvalidatePrt();
    1125             : 
    1126             :                 // OD 09.01.2004 #i11859# - correction:
    1127             :                 //  (1) Also invalidate next frame on next page/column.
    1128             :                 //  (2) Skip empty sections and hidden paragraphs
    1129             :                 //  Thus, use method <InvalidateNextPrtArea()>
    1130         134 :                 InvalidateNextPrtArea();
    1131             : 
    1132         134 :                 SetCompletePaint();
    1133         134 :                 nClear |= 0x04;
    1134         134 :                 if ( bLineSpace )
    1135             :                 {
    1136         134 :                     --nCount;
    1137         134 :                     if( IsInSct() && !GetPrev() )
    1138             :                     {
    1139           0 :                         SwSectionFrm *pSect = FindSctFrm();
    1140           0 :                         if( pSect->ContainsAny() == this )
    1141           0 :                             pSect->InvalidatePrt();
    1142             :                     }
    1143             :                 }
    1144         134 :                 if ( bRegister )
    1145           0 :                     --nCount;
    1146             :             }
    1147        8384 :             if ( SfxItemState::SET == rNewSet.GetItemState( RES_PARATR_SPLIT,
    1148        8384 :                                                        false ))
    1149             :             {
    1150           0 :                 if ( GetPrev() )
    1151           0 :                     CheckKeep();
    1152           0 :                 Prepare( PREP_CLEAR );
    1153           0 :                 InvalidateSize();
    1154           0 :                 nClear |= 0x08;
    1155           0 :                 --nCount;
    1156             :             }
    1157             : 
    1158       16768 :             if( SfxItemState::SET == rNewSet.GetItemState( RES_BACKGROUND, false)
    1159        8384 :                 && !IsFollow() && GetDrawObjs() )
    1160             :             {
    1161           0 :                 SwSortedObjs *pObjs = GetDrawObjs();
    1162           0 :                 for ( size_t i = 0; GetDrawObjs() && i < pObjs->size(); ++i )
    1163             :                 {
    1164           0 :                     SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
    1165           0 :                     if ( pAnchoredObj->ISA(SwFlyFrm) )
    1166             :                     {
    1167           0 :                         SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
    1168           0 :                         if( !pFly->IsFlyInCntFrm() )
    1169             :                         {
    1170             :                             const SvxBrushItem &rBack =
    1171           0 :                                 pFly->GetAttrSet()->GetBackground();
    1172             :                             // OD 20.08.2002 #99657# #GetTransChg#
    1173             :                             //     following condition determines, if the fly frame
    1174             :                             //     "inherites" the background color of text frame.
    1175             :                             //     This is the case, if fly frame background
    1176             :                             //     color is "no fill"/"auto fill" and if the fly frame
    1177             :                             //     has no background graphic.
    1178             :                             //     Thus, check complete fly frame background
    1179             :                             //     color and *not* only its transparency value
    1180           0 :                             if ( (rBack.GetColor() == COL_TRANSPARENT)  &&
    1181           0 :                                 rBack.GetGraphicPos() == GPOS_NONE )
    1182             :                             {
    1183           0 :                                 pFly->SetCompletePaint();
    1184           0 :                                 pFly->InvalidatePage();
    1185             :                             }
    1186             :                         }
    1187             :                     }
    1188             :                 }
    1189             :             }
    1190             : 
    1191        8384 :             if ( SfxItemState::SET ==
    1192        8384 :                  rNewSet.GetItemState( RES_TXTATR_CHARFMT, false ) )
    1193             :             {
    1194           0 :                 lcl_SetWrong( *this, 0, COMPLETE_STRING, false );
    1195           0 :                 lcl_SetScriptInval( *this, 0 );
    1196             :             }
    1197        8384 :             else if ( SfxItemState::SET ==
    1198       16538 :                       rNewSet.GetItemState( RES_CHRATR_LANGUAGE, false ) ||
    1199             :                       SfxItemState::SET ==
    1200       16478 :                       rNewSet.GetItemState( RES_CHRATR_CJK_LANGUAGE, false ) ||
    1201             :                       SfxItemState::SET ==
    1202        8094 :                       rNewSet.GetItemState( RES_CHRATR_CTL_LANGUAGE, false ) )
    1203         336 :                 lcl_SetWrong( *this, 0, COMPLETE_STRING, false );
    1204        8048 :             else if ( SfxItemState::SET ==
    1205       13358 :                       rNewSet.GetItemState( RES_CHRATR_FONT, false ) ||
    1206             :                       SfxItemState::SET ==
    1207       13128 :                       rNewSet.GetItemState( RES_CHRATR_CJK_FONT, false ) ||
    1208             :                       SfxItemState::SET ==
    1209        5080 :                       rNewSet.GetItemState( RES_CHRATR_CTL_FONT, false ) )
    1210        3198 :                 lcl_SetScriptInval( *this, 0 );
    1211        4850 :             else if ( SfxItemState::SET ==
    1212        4850 :                       rNewSet.GetItemState( RES_FRAMEDIR, false ) )
    1213             :             {
    1214         356 :                 SetDerivedR2L( false );
    1215         356 :                 CheckDirChange();
    1216             :                 // OD 09.12.2002 #105576# - Force complete paint due to existing
    1217             :                 // indents.
    1218         356 :                 SetCompletePaint();
    1219             :             }
    1220             : 
    1221        8384 :             if( nCount )
    1222             :             {
    1223        8384 :                 if( getRootFrm()->GetCurrShell() )
    1224             :                 {
    1225        8384 :                     Prepare( PREP_CLEAR );
    1226        8384 :                     _InvalidatePrt();
    1227             :                 }
    1228             : 
    1229        8384 :                 if( nClear )
    1230             :                 {
    1231         134 :                     SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
    1232         268 :                     SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
    1233             : 
    1234         134 :                     if( 0x01 & nClear )
    1235             :                     {
    1236           0 :                         aOldSet.ClearItem( RES_TXTATR_FTN );
    1237           0 :                         aNewSet.ClearItem( RES_TXTATR_FTN );
    1238             :                     }
    1239         134 :                     if( 0x02 & nClear )
    1240             :                     {
    1241           0 :                         aOldSet.ClearItem( RES_TXTATR_FIELD );
    1242           0 :                         aNewSet.ClearItem( RES_TXTATR_FIELD );
    1243             :                     }
    1244         134 :                     if ( 0x04 & nClear )
    1245             :                     {
    1246         134 :                         if ( bLineSpace )
    1247             :                         {
    1248         134 :                             aOldSet.ClearItem( RES_PARATR_LINESPACING );
    1249         134 :                             aNewSet.ClearItem( RES_PARATR_LINESPACING );
    1250             :                         }
    1251         134 :                         if ( bRegister )
    1252             :                         {
    1253           0 :                             aOldSet.ClearItem( RES_PARATR_REGISTER );
    1254           0 :                             aNewSet.ClearItem( RES_PARATR_REGISTER );
    1255             :                         }
    1256             :                     }
    1257         134 :                     if ( 0x08 & nClear )
    1258             :                     {
    1259           0 :                         aOldSet.ClearItem( RES_PARATR_SPLIT );
    1260           0 :                         aNewSet.ClearItem( RES_PARATR_SPLIT );
    1261             :                     }
    1262         268 :                     SwCntntFrm::Modify( &aOldSet, &aNewSet );
    1263             :                 }
    1264             :                 else
    1265        8250 :                     SwCntntFrm::Modify( pOld, pNew );
    1266             :             }
    1267             : 
    1268        8384 :             if (isA11yRelevantAttribute(nWhich))
    1269             :             {
    1270             :                 // #i88069#
    1271        8384 :                 SwViewShell* pViewSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
    1272        8384 :                 if ( pViewSh  )
    1273             :                 {
    1274        8384 :                     pViewSh->InvalidateAccessibleParaAttrs( *this );
    1275             :                 }
    1276             :             }
    1277             :         }
    1278        8384 :         break;
    1279             : 
    1280             :         // 6870: process SwDocPosUpdate
    1281             :         case RES_DOCPOS_UPDATE:
    1282             :         {
    1283        1238 :             if( pOld && pNew )
    1284             :             {
    1285        1238 :                 const SwDocPosUpdate *pDocPos = (const SwDocPosUpdate*)pOld;
    1286        1238 :                 if( pDocPos->nDocPos <= maFrm.Top() )
    1287             :                 {
    1288        1162 :                     const SwFmtFld *pFld = (const SwFmtFld *)pNew;
    1289             :                     InvalidateRange(
    1290        1162 :                         SwCharRange( pFld->GetTxtFld()->GetStart(), 1 ) );
    1291             :                 }
    1292             :             }
    1293        1238 :             break;
    1294             :         }
    1295             :         case RES_PARATR_SPLIT:
    1296           0 :             if ( GetPrev() )
    1297           0 :                 CheckKeep();
    1298           0 :             Prepare( PREP_CLEAR );
    1299           0 :             bSetFldsDirty = true;
    1300           0 :             break;
    1301             :         case RES_FRAMEDIR :
    1302           0 :             SetDerivedR2L( false );
    1303           0 :             CheckDirChange();
    1304           0 :             break;
    1305             :         default:
    1306             :         {
    1307          26 :             Prepare( PREP_CLEAR );
    1308          26 :             _InvalidatePrt();
    1309          26 :             if ( !nWhich )
    1310             :             {
    1311             :                 // is called by e. g. HiddenPara with 0
    1312             :                 SwFrm *pNxt;
    1313           0 :                 if ( 0 != (pNxt = FindNext()) )
    1314           0 :                     pNxt->InvalidatePrt();
    1315             :             }
    1316             :         }
    1317             :     } // switch
    1318             : 
    1319       38060 :     if( bSetFldsDirty )
    1320       22464 :         GetNode()->getIDocumentFieldsAccess()->SetFieldsDirty( true, GetNode(), 1 );
    1321             : 
    1322       38060 :     if ( bRecalcFtnFlag )
    1323        2428 :         CalcFtnFlag();
    1324             : }
    1325             : 
    1326         430 : bool SwTxtFrm::GetInfo( SfxPoolItem &rHnt ) const
    1327             : {
    1328         430 :     if ( RES_VIRTPAGENUM_INFO == rHnt.Which() && IsInDocBody() && ! IsFollow() )
    1329             :     {
    1330         430 :         SwVirtPageNumInfo &rInfo = (SwVirtPageNumInfo&)rHnt;
    1331         430 :         const SwPageFrm *pPage = FindPageFrm();
    1332         430 :         if ( pPage )
    1333             :         {
    1334         430 :             if ( pPage == rInfo.GetOrigPage() && !GetPrev() )
    1335             :             {
    1336             :                 // this should be the one
    1337             :                 // (could only differ temporarily; is that disturbing?)
    1338         166 :                 rInfo.SetInfo( pPage, this );
    1339         166 :                 return false;
    1340             :             }
    1341         576 :             if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() &&
    1342         156 :                  (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum()))
    1343             :             {
    1344             :                 // this could be the one
    1345         156 :                 rInfo.SetInfo( pPage, this );
    1346             :             }
    1347             :         }
    1348             :     }
    1349         264 :     return true;
    1350             : }
    1351             : 
    1352         338 : void SwTxtFrm::PrepWidows( const sal_uInt16 nNeed, bool bNotify )
    1353             : {
    1354             :     OSL_ENSURE(GetFollow() && nNeed, "+SwTxtFrm::Prepare: lost all friends");
    1355             : 
    1356         338 :     SwParaPortion *pPara = GetPara();
    1357         338 :     if ( !pPara )
    1358         338 :         return;
    1359         338 :     pPara->SetPrepWidows();
    1360             : 
    1361         338 :     sal_uInt16 nHave = nNeed;
    1362             : 
    1363             :     // Wir geben ein paar Zeilen ab und schrumpfen im CalcPreps()
    1364         338 :     SWAP_IF_NOT_SWAPPED( this )
    1365             : 
    1366         338 :     SwTxtSizeInfo aInf( this );
    1367         676 :     SwTxtMargin aLine( this, &aInf );
    1368         338 :     aLine.Bottom();
    1369         338 :     sal_Int32 nTmpLen = aLine.GetCurr()->GetLen();
    1370         962 :     while( nHave && aLine.PrevLine() )
    1371             :     {
    1372         286 :         if( nTmpLen )
    1373         286 :             --nHave;
    1374         286 :         nTmpLen = aLine.GetCurr()->GetLen();
    1375             :     }
    1376             :     // In dieser Ecke tummelten sich einige Bugs: 7513, 7606.
    1377             :     // Wenn feststeht, dass Zeilen abgegeben werden koennen,
    1378             :     // muss der Master darueber hinaus die Widow-Regel ueberpruefen.
    1379         338 :     if( !nHave )
    1380             :     {
    1381         286 :         bool bSplit = true;
    1382         286 :         if( !IsFollow() )   // only a master decides about orphans
    1383             :         {
    1384         274 :             const WidowsAndOrphans aWidOrp( this );
    1385         314 :             bSplit = ( aLine.GetLineNr() >= aWidOrp.GetOrphansLines() &&
    1386         314 :                        aLine.GetLineNr() >= aLine.GetDropLines() );
    1387             :         }
    1388             : 
    1389         286 :         if( bSplit )
    1390             :         {
    1391          52 :             GetFollow()->SetOfst( aLine.GetEnd() );
    1392          52 :             aLine.TruncLines( true );
    1393          52 :             if( pPara->IsFollowField() )
    1394           0 :                 GetFollow()->SetFieldFollow( true );
    1395             :         }
    1396             :     }
    1397         338 :     if ( bNotify )
    1398             :     {
    1399         338 :         _InvalidateSize();
    1400         338 :         InvalidatePage();
    1401             :     }
    1402             : 
    1403         676 :     UNDO_SWAP( this )
    1404             : }
    1405             : 
    1406          14 : static bool lcl_ErgoVadis( SwTxtFrm* pFrm, sal_Int32 &rPos, const PrepareHint ePrep )
    1407             : {
    1408          14 :     const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo();
    1409          14 :     if( ePrep == PREP_ERGOSUM )
    1410             :     {
    1411           2 :         if( rFtnInfo.aErgoSum.isEmpty() )
    1412           2 :             return false;
    1413           0 :         rPos = pFrm->GetOfst();
    1414             :     }
    1415             :     else
    1416             :     {
    1417          12 :         if( rFtnInfo.aQuoVadis.isEmpty() )
    1418          12 :             return false;
    1419           0 :         if( pFrm->HasFollow() )
    1420           0 :             rPos = pFrm->GetFollow()->GetOfst();
    1421             :         else
    1422           0 :             rPos = pFrm->GetTxt().getLength();
    1423           0 :         if( rPos )
    1424           0 :             --rPos; // our last character
    1425             :     }
    1426           0 :     return true;
    1427             : }
    1428             : 
    1429      352401 : void SwTxtFrm::Prepare( const PrepareHint ePrep, const void* pVoid,
    1430             :                         bool bNotify )
    1431             : {
    1432      352401 :     SwFrmSwapper aSwapper( this, false );
    1433             : 
    1434             : #if OSL_DEBUG_LEVEL > 1
    1435             :     const SwTwips nDbgY = Frm().Top();
    1436             :     (void)nDbgY;
    1437             : #endif
    1438             : 
    1439      352401 :     if ( IsEmpty() )
    1440             :     {
    1441       29188 :         switch ( ePrep )
    1442             :         {
    1443             :             case PREP_BOSS_CHGD:
    1444        3894 :                 SetInvalidVert( true );  // Test
    1445             :             case PREP_WIDOWS_ORPHANS:
    1446             :             case PREP_WIDOWS:
    1447        4082 :             case PREP_FTN_GONE :    return;
    1448             : 
    1449             :             case PREP_POS_CHGD :
    1450             :             {
    1451             :                 // Auch in (spaltigen) Bereichen ist ein InvalidateSize notwendig,
    1452             :                 // damit formatiert wird und ggf. das bUndersized gesetzt wird.
    1453        8000 :                 if( IsInFly() || IsInSct() )
    1454             :                 {
    1455         584 :                     SwTwips nTmpBottom = GetUpper()->Frm().Top() +
    1456         584 :                         GetUpper()->Prt().Bottom();
    1457         584 :                     if( nTmpBottom < Frm().Bottom() )
    1458         748 :                         break;
    1459             :                 }
    1460             :                 // are there any free-flying frames on this page?
    1461        7782 :                 SwTxtFly aTxtFly( this );
    1462        7782 :                 if( aTxtFly.IsOn() )
    1463             :                 {
    1464             :                     // does any free-flying frame overlap?
    1465         740 :                     if ( aTxtFly.Relax() || IsUndersized() )
    1466         304 :                         break;
    1467             :                 }
    1468        7478 :                 if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue())
    1469           0 :                     break;
    1470             : 
    1471        7478 :                 SwTextGridItem const*const pGrid(GetGridItem(FindPageFrm()));
    1472        7478 :                 if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() )
    1473           0 :                     break;
    1474             : 
    1475             :                 // #i28701# - consider anchored objects
    1476        7478 :                 if ( GetDrawObjs() )
    1477           8 :                     break;
    1478             : 
    1479        7470 :                 return;
    1480             :             }
    1481             :             default:
    1482       17106 :                 break;
    1483             :         }
    1484             :     }
    1485             : 
    1486      340849 :     if( !HasPara() && PREP_MUST_FIT != ePrep )
    1487             :     {
    1488      256457 :         SetInvalidVert( true );  // Test
    1489             :         OSL_ENSURE( !IsLocked(), "SwTxtFrm::Prepare: three of a perfect pair" );
    1490      256457 :         if ( bNotify )
    1491      187586 :             InvalidateSize();
    1492             :         else
    1493       68871 :             _InvalidateSize();
    1494      256457 :         return;
    1495             :     }
    1496             : 
    1497             :     // get object from cache while locking
    1498       84392 :     SwTxtLineAccess aAccess( this );
    1499       84392 :     SwParaPortion *pPara = aAccess.GetPara();
    1500             : 
    1501       84392 :     switch( ePrep )
    1502             :     {
    1503           0 :         case PREP_MOVEFTN :     Frm().Height(0);
    1504           0 :                                 Prt().Height(0);
    1505           0 :                                 _InvalidatePrt();
    1506           0 :                                 _InvalidateSize();
    1507             :             /* no break here */
    1508       17958 :         case PREP_ADJUST_FRM :  pPara->SetPrepAdjust();
    1509       35912 :                                 if( IsFtnNumFrm() != pPara->IsFtnNum() ||
    1510       17954 :                                     IsUndersized() )
    1511             :                                 {
    1512        4322 :                                     InvalidateRange( SwCharRange( 0, 1 ), 1);
    1513        4322 :                                     if( GetOfst() && !IsFollow() )
    1514           0 :                                         _SetOfst( 0 );
    1515             :                                 }
    1516       17958 :                                 break;
    1517         524 :         case PREP_MUST_FIT :        pPara->SetPrepMustFit();
    1518             :             /* no break here */
    1519        2411 :         case PREP_WIDOWS_ORPHANS :  pPara->SetPrepAdjust();
    1520        2411 :                                     break;
    1521             : 
    1522             :         case PREP_WIDOWS :
    1523             :             // MustFit is stronger than anything else
    1524         338 :             if( pPara->IsPrepMustFit() )
    1525           0 :                 return;
    1526             :             // see comment in WidowsAndOrphans::FindOrphans and CalcPreps()
    1527         338 :             PrepWidows( *(const sal_uInt16 *)pVoid, bNotify );
    1528         338 :             break;
    1529             : 
    1530             :         case PREP_FTN :
    1531             :         {
    1532         262 :             SwTxtFtn *pFtn = (SwTxtFtn *)pVoid;
    1533         262 :             if( IsInFtn() )
    1534             :             {
    1535             :                 // am I the first TxtFrm of a footnote?
    1536          56 :                 if( !GetPrev() )
    1537             :                     // Wir sind also ein TxtFrm der Fussnote, die
    1538             :                     // die Fussnotenzahl zur Anzeige bringen muss.
    1539             :                     // Oder den ErgoSum-Text...
    1540          52 :                     InvalidateRange( SwCharRange( 0, 1 ), 1);
    1541             : 
    1542          56 :                 if( !GetNext() )
    1543             :                 {
    1544             :                     // Wir sind der letzte Ftn, jetzt muessten die
    1545             :                     // QuoVadis-Texte geupdated werden.
    1546          54 :                     const SwFtnInfo &rFtnInfo = GetNode()->GetDoc()->GetFtnInfo();
    1547          54 :                     if( !pPara->UpdateQuoVadis( rFtnInfo.aQuoVadis ) )
    1548             :                     {
    1549          54 :                         sal_Int32 nPos = pPara->GetParLen();
    1550          54 :                         if( nPos )
    1551          12 :                             --nPos;
    1552          54 :                         InvalidateRange( SwCharRange( nPos, 1 ), 1);
    1553             :                     }
    1554             :                 }
    1555             :             }
    1556             :             else
    1557             :             {
    1558             :                 // we are the TxtFrm _with_ the footnote
    1559         206 :                 const sal_Int32 nPos = pFtn->GetStart();
    1560         206 :                 InvalidateRange( SwCharRange( nPos, 1 ), 1);
    1561             :             }
    1562         262 :             break;
    1563             :         }
    1564             :         case PREP_BOSS_CHGD :
    1565             :         {
    1566             :     // Test
    1567             :             {
    1568        8338 :                 SetInvalidVert( false );
    1569        8338 :                 bool bOld = IsVertical();
    1570        8338 :                 SetInvalidVert( true );
    1571        8338 :                 if( bOld != IsVertical() )
    1572           0 :                     InvalidateRange( SwCharRange( GetOfst(), COMPLETE_STRING ) );
    1573             :             }
    1574             : 
    1575        8338 :             if( HasFollow() )
    1576             :             {
    1577          46 :                 sal_Int32 nNxtOfst = GetFollow()->GetOfst();
    1578          46 :                 if( nNxtOfst )
    1579          46 :                     --nNxtOfst;
    1580          46 :                 InvalidateRange( SwCharRange( nNxtOfst, 1 ), 1);
    1581             :             }
    1582        8338 :             if( IsInFtn() )
    1583             :             {
    1584             :                 sal_Int32 nPos;
    1585           0 :                 if( lcl_ErgoVadis( this, nPos, PREP_QUOVADIS ) )
    1586           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1587           0 :                 if( lcl_ErgoVadis( this, nPos, PREP_ERGOSUM ) )
    1588           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1589             :             }
    1590             :             // 4739: if we have a page number field, we must invalidate those spots
    1591        8338 :             SwpHints *pHints = GetTxtNode()->GetpSwpHints();
    1592        8338 :             if( pHints )
    1593             :             {
    1594        6082 :                 const size_t nSize = pHints->Count();
    1595        6082 :                 const sal_Int32 nEnd = GetFollow() ?
    1596        6082 :                                     GetFollow()->GetOfst() : COMPLETE_STRING;
    1597       22810 :                 for ( size_t i = 0; i < nSize; ++i )
    1598             :                 {
    1599       16756 :                     const SwTxtAttr *pHt = (*pHints)[i];
    1600       16756 :                     const sal_Int32 nStart = pHt->GetStart();
    1601       16756 :                     if( nStart >= GetOfst() )
    1602             :                     {
    1603       16756 :                         if( nStart >= nEnd )
    1604          28 :                             break;
    1605             : 
    1606             :                 // 4029: wenn wir zurueckfliessen und eine Ftn besitzen, so
    1607             :                 // fliesst die Ftn in jedem Fall auch mit. Damit sie nicht im
    1608             :                 // Weg steht, schicken wir uns ein ADJUST_FRM.
    1609             :                 // pVoid != 0 bedeutet MoveBwd()
    1610       16728 :                         const sal_uInt16 nWhich = pHt->Which();
    1611       33460 :                         if( RES_TXTATR_FIELD == nWhich ||
    1612       16712 :                             (HasFtn() && pVoid && RES_TXTATR_FTN == nWhich))
    1613          26 :                         InvalidateRange( SwCharRange( nStart, 1 ), 1 );
    1614             :                     }
    1615             :                 }
    1616             :             }
    1617             :             // A new boss, a new chance for growing
    1618        8338 :             if( IsUndersized() )
    1619             :             {
    1620         348 :                 _InvalidateSize();
    1621         348 :                 InvalidateRange( SwCharRange( GetOfst(), 1 ), 1);
    1622             :             }
    1623        8338 :             break;
    1624             :         }
    1625             : 
    1626             :         case PREP_POS_CHGD :
    1627             :         {
    1628       25552 :             if ( GetValidPrtAreaFlag() )
    1629             :             {
    1630       24832 :                 SwTextGridItem const*const pGrid(GetGridItem(FindPageFrm()));
    1631       24832 :                 if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() )
    1632          12 :                     InvalidatePrt();
    1633             :             }
    1634             : 
    1635             :             // if we don't overlap with anybody:
    1636             :             // did any free-flying frame overlapped _before_ the position change?
    1637       25552 :             bool bFormat = pPara->HasFly();
    1638       25552 :             if( !bFormat )
    1639             :             {
    1640       25452 :                 if( IsInFly() )
    1641             :                 {
    1642         956 :                     SwTwips nTmpBottom = GetUpper()->Frm().Top() +
    1643         956 :                         GetUpper()->Prt().Bottom();
    1644         956 :                     if( nTmpBottom < Frm().Bottom() )
    1645           0 :                         bFormat = true;
    1646             :                 }
    1647       25452 :                 if( !bFormat )
    1648             :                 {
    1649       25452 :                     if ( GetDrawObjs() )
    1650             :                     {
    1651         438 :                         const size_t nCnt = GetDrawObjs()->size();
    1652        1100 :                         for ( size_t i = 0; i < nCnt; ++i )
    1653             :                         {
    1654         698 :                             SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
    1655             :                             // #i28701# - consider all
    1656             :                             // to-character anchored objects
    1657         698 :                             if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
    1658             :                                     == FLY_AT_CHAR )
    1659             :                             {
    1660          36 :                                 bFormat = true;
    1661          36 :                                 break;
    1662             :                             }
    1663             :                         }
    1664             :                     }
    1665       25452 :                     if( !bFormat )
    1666             :                     {
    1667             :                         // are there any free-flying frames on this page?
    1668       25416 :                         SwTxtFly aTxtFly( this );
    1669       25416 :                         if( aTxtFly.IsOn() )
    1670             :                         {
    1671             :                             // does any free-flying frame overlap?
    1672        6126 :                             bFormat = aTxtFly.Relax() || IsUndersized();
    1673       25416 :                         }
    1674             :                     }
    1675             :                 }
    1676             :             }
    1677             : 
    1678       25552 :             if( bFormat )
    1679             :             {
    1680        3942 :                 if( !IsLocked() )
    1681             :                 {
    1682        3942 :                     if( pPara->GetRepaint().HasArea() )
    1683        3942 :                         SetCompletePaint();
    1684        3942 :                     Init();
    1685        3942 :                     pPara = 0;
    1686        3942 :                     _InvalidateSize();
    1687             :                 }
    1688             :             }
    1689             :             else
    1690             :             {
    1691       21610 :                 if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
    1692           0 :                     Prepare( PREP_REGISTER, 0, bNotify );
    1693             :                 // Durch Positionsverschiebungen mit Ftns muessen die
    1694             :                 // Frames neu adjustiert werden.
    1695       21610 :                 else if( HasFtn() )
    1696             :                 {
    1697           8 :                     Prepare( PREP_ADJUST_FRM, 0, bNotify );
    1698           8 :                     _InvalidateSize();
    1699             :                 }
    1700             :                 else
    1701       21602 :                     return;     // damit kein SetPrep() erfolgt.
    1702             :             }
    1703        3950 :             break;
    1704             :         }
    1705             :         case PREP_REGISTER:
    1706           0 :             if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
    1707             :             {
    1708           0 :                 pPara->SetPrepAdjust();
    1709           0 :                 CalcLineSpace();
    1710             :                 // possible that pPara was deleted above; retrieve it again
    1711           0 :                 pPara = aAccess.GetPara();
    1712           0 :                 InvalidateSize();
    1713           0 :                 _InvalidatePrt();
    1714             :                 SwFrm* pNxt;
    1715           0 :                 if ( 0 != ( pNxt = GetIndNext() ) )
    1716             :                 {
    1717           0 :                     pNxt->_InvalidatePrt();
    1718           0 :                     if ( pNxt->IsLayoutFrm() )
    1719           0 :                         pNxt->InvalidatePage();
    1720             :                 }
    1721           0 :                 SetCompletePaint();
    1722             :             }
    1723           0 :             break;
    1724             :         case PREP_FTN_GONE :
    1725             :             {
    1726             :                 // Wenn ein Follow uns ruft, weil eine Fussnote geloescht wird, muss unsere
    1727             :                 // letzte Zeile formatiert werden, damit ggf. die erste Zeile des Follows
    1728             :                 // hochrutschen kann, die extra auf die naechste Seite gerutscht war, um mit
    1729             :                 // der Fussnote zusammen zu sein, insbesondere bei spaltigen Bereichen.
    1730             :                 OSL_ENSURE( GetFollow(), "PREP_FTN_GONE darf nur vom Follow gerufen werden" );
    1731           0 :                 sal_Int32 nPos = GetFollow()->GetOfst();
    1732           0 :                 if( IsFollow() && GetOfst() == nPos )       // falls wir gar keine Textmasse besitzen,
    1733           0 :                     FindMaster()->Prepare( PREP_FTN_GONE ); // rufen wir das Prepare unseres Masters
    1734           0 :                 if( nPos )
    1735           0 :                     --nPos; // das Zeichen vor unserem Follow
    1736           0 :                 InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1737           0 :                 return;
    1738             :             }
    1739             :         case PREP_ERGOSUM:
    1740             :         case PREP_QUOVADIS:
    1741             :             {
    1742             :                 sal_Int32 nPos;
    1743          14 :                 if( lcl_ErgoVadis( this, nPos, ePrep ) )
    1744           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1745             :             }
    1746          14 :             break;
    1747             :         case PREP_FLY_ATTR_CHG:
    1748             :         {
    1749         322 :             if( pVoid )
    1750             :             {
    1751         313 :                 sal_Int32 nWhere = CalcFlyPos( (SwFrmFmt*)pVoid );
    1752             :                 OSL_ENSURE( COMPLETE_STRING != nWhere, "Prepare: Why me?" );
    1753         313 :                 InvalidateRange( SwCharRange( nWhere, 1 ) );
    1754         313 :                 return;
    1755             :             }
    1756             :             // else: continue with default case block
    1757             :         }
    1758             :         case PREP_CLEAR:
    1759             :         default:
    1760             :         {
    1761       29206 :             if( IsLocked() )
    1762             :             {
    1763        6006 :                 if( PREP_FLY_ARRIVE == ePrep || PREP_FLY_LEAVE == ePrep )
    1764             :                 {
    1765        4668 :                     sal_Int32 nLen = ( GetFollow() ? GetFollow()->GetOfst() :
    1766        4668 :                                       COMPLETE_STRING ) - GetOfst();
    1767        4650 :                     InvalidateRange( SwCharRange( GetOfst(), nLen ), 0 );
    1768             :                 }
    1769             :             }
    1770             :             else
    1771             :             {
    1772       23200 :                 if( pPara->GetRepaint().HasArea() )
    1773       21728 :                     SetCompletePaint();
    1774       23200 :                 Init();
    1775       23200 :                 pPara = 0;
    1776       23200 :                 if( GetOfst() && !IsFollow() )
    1777          12 :                     _SetOfst( 0 );
    1778       23200 :                 if ( bNotify )
    1779       23140 :                     InvalidateSize();
    1780             :                 else
    1781          60 :                     _InvalidateSize();
    1782             :             }
    1783       29206 :             return;     // no SetPrep() happened
    1784             :         }
    1785             :     }
    1786       33271 :     if( pPara )
    1787       29329 :         pPara->SetPrep();
    1788             : }
    1789             : 
    1790             : // Small Helper class:
    1791             : // Prepares a test format.
    1792             : // The frame is changed in size and position, its SwParaPortion is moved aside
    1793             : // and a new one is created.
    1794             : // To achieve this, run formatting with bTestFormat flag set.
    1795             : // In the destructor the TxtFrm is reset to its original state.
    1796             : class SwTestFormat
    1797             : {
    1798             :     SwTxtFrm *pFrm;
    1799             :     SwParaPortion *pOldPara;
    1800             :     SwRect aOldFrm, aOldPrt;
    1801             : public:
    1802             :     SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPrv, SwTwips nMaxHeight );
    1803             :     ~SwTestFormat();
    1804             : };
    1805             : 
    1806         178 : SwTestFormat::SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPre, SwTwips nMaxHeight )
    1807         178 :     : pFrm( pTxtFrm )
    1808             : {
    1809         178 :     aOldFrm = pFrm->Frm();
    1810         178 :     aOldPrt = pFrm->Prt();
    1811             : 
    1812         178 :     SWRECTFN( pFrm )
    1813         178 :     SwTwips nLower = (pFrm->*fnRect->fnGetBottomMargin)();
    1814             : 
    1815         178 :     pFrm->Frm() = pFrm->GetUpper()->Prt();
    1816         178 :     pFrm->Frm() += pFrm->GetUpper()->Frm().Pos();
    1817             : 
    1818         178 :     (pFrm->Frm().*fnRect->fnSetHeight)( nMaxHeight );
    1819         178 :     if( pFrm->GetPrev() )
    1820         178 :         (pFrm->Frm().*fnRect->fnSetPosY)(
    1821         178 :                 (pFrm->GetPrev()->Frm().*fnRect->fnGetBottom)() -
    1822         356 :                 ( bVert ? nMaxHeight + 1 : 0 ) );
    1823             : 
    1824         178 :     SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
    1825         178 :     const SwBorderAttrs &rAttrs = *aAccess.Get();
    1826         178 :     (pFrm->Prt().*fnRect->fnSetPosX)( rAttrs.CalcLeft( pFrm ) );
    1827             : 
    1828         178 :     if( pPre )
    1829             :     {
    1830         178 :         SwTwips nUpper = pFrm->CalcUpperSpace( &rAttrs, pPre );
    1831         178 :         (pFrm->Prt().*fnRect->fnSetPosY)( nUpper );
    1832             :     }
    1833         178 :     (pFrm->Prt().*fnRect->fnSetHeight)(
    1834         356 :         std::max( 0L , (pFrm->Frm().*fnRect->fnGetHeight)() -
    1835         534 :                   (pFrm->Prt().*fnRect->fnGetTop)() - nLower ) );
    1836         178 :     (pFrm->Prt().*fnRect->fnSetWidth)(
    1837         178 :         (pFrm->Frm().*fnRect->fnGetWidth)() -
    1838         356 :         ( rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm ) ) );
    1839         178 :     pOldPara = pFrm->HasPara() ? pFrm->GetPara() : NULL;
    1840         178 :     pFrm->SetPara( new SwParaPortion(), false );
    1841             : 
    1842             :     OSL_ENSURE( ! pFrm->IsSwapped(), "A frame is swapped before _Format" );
    1843             : 
    1844         178 :     if ( pFrm->IsVertical() )
    1845           0 :         pFrm->SwapWidthAndHeight();
    1846             : 
    1847         356 :     SwTxtFormatInfo aInf( pFrm, false, true, true );
    1848         356 :     SwTxtFormatter  aLine( pFrm, &aInf );
    1849             : 
    1850         178 :     pFrm->_Format( aLine, aInf );
    1851             : 
    1852         178 :     if ( pFrm->IsVertical() )
    1853           0 :         pFrm->SwapWidthAndHeight();
    1854             : 
    1855         178 :     OSL_ENSURE( ! pFrm->IsSwapped(), "A frame is swapped after _Format" );
    1856         178 : }
    1857             : 
    1858         178 : SwTestFormat::~SwTestFormat()
    1859             : {
    1860         178 :     pFrm->Frm() = aOldFrm;
    1861         178 :     pFrm->Prt() = aOldPrt;
    1862         178 :     pFrm->SetPara( pOldPara );
    1863         178 : }
    1864             : 
    1865         178 : bool SwTxtFrm::TestFormat( const SwFrm* pPrv, SwTwips &rMaxHeight, bool &bSplit )
    1866             : {
    1867             :     PROTOCOL_ENTER( this, PROT_TESTFORMAT, 0, 0 )
    1868             : 
    1869         178 :     if( IsLocked() && GetUpper()->Prt().Width() <= 0 )
    1870           0 :         return false;
    1871             : 
    1872         178 :     SwTestFormat aSave( this, pPrv, rMaxHeight );
    1873             : 
    1874         178 :     return SwTxtFrm::WouldFit( rMaxHeight, bSplit, true );
    1875             : }
    1876             : 
    1877             : /* SwTxtFrm::WouldFit()
    1878             :  * true: wenn ich aufspalten kann.
    1879             :  * Es soll und braucht nicht neu formatiert werden.
    1880             :  * Wir gehen davon aus, dass bereits formatiert wurde und dass
    1881             :  * die Formatierungsdaten noch aktuell sind.
    1882             :  * Wir gehen davon aus, dass die Framebreiten des evtl. Masters und
    1883             :  * Follows gleich sind. Deswegen wird kein FindBreak() mit FindOrphans()
    1884             :  * gerufen.
    1885             :  * Die benoetigte Hoehe wird von nMaxHeight abgezogen!
    1886             :  */
    1887             : 
    1888        5730 : bool SwTxtFrm::WouldFit( SwTwips &rMaxHeight, bool &bSplit, bool bTst )
    1889             : {
    1890             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
    1891             :             "SwTxtFrm::WouldFit with swapped frame" );
    1892        5730 :     SWRECTFN( this );
    1893             : 
    1894        5730 :     if( IsLocked() )
    1895           0 :         return false;
    1896             : 
    1897             :     // it can happen that the IdleCollector removed the cached information
    1898        5730 :     if( !IsEmpty() )
    1899        2302 :         GetFormatted();
    1900             : 
    1901             :     // OD 2004-05-24 #i27801# - correction: 'short cut' for empty paragraph
    1902             :     // can *not* be applied, if test format is in progress. The test format doesn't
    1903             :     // adjust the frame and the printing area - see method <SwTxtFrm::_Format(..)>,
    1904             :     // which is called in <SwTxtFrm::TestFormat(..)>
    1905        5730 :     if ( IsEmpty() && !bTst )
    1906             :     {
    1907        3420 :         bSplit = false;
    1908        3420 :         SwTwips nHeight = bVert ? Prt().SSize().Width() : Prt().SSize().Height();
    1909        3420 :         if( rMaxHeight < nHeight )
    1910          20 :             return false;
    1911             :         else
    1912             :         {
    1913        3400 :             rMaxHeight -= nHeight;
    1914        3400 :             return true;
    1915             :         }
    1916             :     }
    1917             : 
    1918             :     // In sehr unguenstigen Faellen kann GetPara immer noch 0 sein.
    1919             :     // Dann returnen wir true, um auf der neuen Seite noch einmal
    1920             :     // anformatiert zu werden.
    1921             :     OSL_ENSURE( HasPara() || IsHiddenNow(), "WouldFit: GetFormatted() and then !HasPara()" );
    1922        2310 :     if( !HasPara() || ( !(Frm().*fnRect->fnGetHeight)() && IsHiddenNow() ) )
    1923           0 :         return true;
    1924             : 
    1925             :     // Da das Orphan-Flag nur sehr fluechtig existiert, wird als zweite
    1926             :     // Bedingung  ueberprueft, ob die Rahmengroesse durch CalcPreps
    1927             :     // auf riesengross gesetzt wird, um ein MoveFwd zu erzwingen.
    1928        4620 :     if( IsWidow() || ( bVert ?
    1929           0 :                        ( 0 == Frm().Left() ) :
    1930        2310 :                        ( LONG_MAX - 20000 < Frm().Bottom() ) ) )
    1931             :     {
    1932           6 :         SetWidow(false);
    1933           6 :         if ( GetFollow() )
    1934             :         {
    1935             :             // Wenn wir hier durch eine Widow-Anforderung unseres Follows gelandet
    1936             :             // sind, wird ueberprueft, ob es ueberhaupt einen Follow mit einer
    1937             :             // echten Hoehe gibt, andernfalls (z.B. in neu angelegten SctFrms)
    1938             :             // ignorieren wir das IsWidow() und pruefen doch noch, ob wir
    1939             :             // genung Platz finden.
    1940          18 :             if( ( ( ! bVert && LONG_MAX - 20000 >= Frm().Bottom() ) ||
    1941           6 :                   (   bVert && 0 < Frm().Left() ) ) &&
    1942           0 :                   ( GetFollow()->IsVertical() ?
    1943           0 :                     !GetFollow()->Frm().Width() :
    1944           0 :                     !GetFollow()->Frm().Height() ) )
    1945             :             {
    1946           0 :                 SwTxtFrm* pFoll = GetFollow()->GetFollow();
    1947           0 :                 while( pFoll &&
    1948           0 :                         ( pFoll->IsVertical() ?
    1949           0 :                          !pFoll->Frm().Width() :
    1950           0 :                          !pFoll->Frm().Height() ) )
    1951           0 :                     pFoll = pFoll->GetFollow();
    1952           0 :                 if( pFoll )
    1953           0 :                     return false;
    1954             :             }
    1955             :             else
    1956           6 :                 return false;
    1957             :         }
    1958             :     }
    1959             : 
    1960        2304 :     SWAP_IF_NOT_SWAPPED( this );
    1961             : 
    1962        2304 :     SwTxtSizeInfo aInf( this );
    1963        4608 :     SwTxtMargin aLine( this, &aInf );
    1964             : 
    1965        2304 :     WidowsAndOrphans aFrmBreak( this, rMaxHeight, bSplit );
    1966             : 
    1967        2304 :     bool bRet = true;
    1968             : 
    1969        2304 :     aLine.Bottom();
    1970             :     // is breaking necessary?
    1971        2304 :     bSplit = !aFrmBreak.IsInside( aLine );
    1972        2304 :     if ( bSplit )
    1973         232 :         bRet = !aFrmBreak.IsKeepAlways() && aFrmBreak.WouldFit( aLine, rMaxHeight, bTst );
    1974             :     else
    1975             :     {
    1976             :         // we need the total height including the current line
    1977        2072 :         aLine.Top();
    1978        2450 :         do
    1979             :         {
    1980        2450 :             rMaxHeight -= aLine.GetLineHeight();
    1981        2450 :         } while ( aLine.Next() );
    1982             :     }
    1983             : 
    1984        2304 :     UNDO_SWAP( this )
    1985             : 
    1986        4608 :     return bRet;
    1987             : }
    1988             : 
    1989        6702 : sal_uInt16 SwTxtFrm::GetParHeight() const
    1990             : {
    1991             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
    1992             :             "SwTxtFrm::GetParHeight with swapped frame" );
    1993             : 
    1994        6702 :     if( !HasPara() )
    1995             :     {   // Fuer nichtleere Absaetze ist dies ein Sonderfall, da koennen wir
    1996             :         // bei UnderSized ruhig nur 1 Twip mehr anfordern.
    1997        1886 :         sal_uInt16 nRet = (sal_uInt16)Prt().SSize().Height();
    1998        1886 :         if( IsUndersized() )
    1999             :         {
    2000        1886 :             if( IsEmpty() || GetTxt().isEmpty() )
    2001        1680 :                 nRet = (sal_uInt16)EmptyHeight();
    2002             :             else
    2003         206 :                 ++nRet;
    2004             :         }
    2005        1886 :         return nRet;
    2006             :     }
    2007             : 
    2008             :     // FME, OD 08.01.2004 #i11859# - refactoring and improve code
    2009        4816 :     const SwLineLayout* pLineLayout = GetPara();
    2010        4816 :     sal_uInt16 nHeight = pLineLayout ? pLineLayout->GetRealHeight() : 0;
    2011        4816 :     if( GetOfst() && !IsFollow() )  // Ist dieser Absatz gescrollt? Dann ist unsere
    2012           0 :         nHeight *= 2;               // bisherige Hoehe mind. eine Zeilenhoehe zu gering
    2013             :     // OD 2004-03-04 #115793#
    2014       11666 :     while ( pLineLayout && pLineLayout->GetNext() )
    2015             :     {
    2016        2034 :         pLineLayout = pLineLayout->GetNext();
    2017        2034 :         nHeight = nHeight + pLineLayout->GetRealHeight();
    2018             :     }
    2019             : 
    2020        4816 :     return nHeight;
    2021             : }
    2022             : 
    2023             : // returns this _always_ in the formated state!
    2024      157232 : SwTxtFrm* SwTxtFrm::GetFormatted( bool bForceQuickFormat )
    2025             : {
    2026      157232 :     SWAP_IF_SWAPPED( this )
    2027             : 
    2028             :     // Kann gut sein, dass mir der IdleCollector mir die gecachten
    2029             :     // Informationen entzogen hat. Calc() ruft unser Format.
    2030             :                       // Nicht bei leeren Absaetzen!
    2031      157232 :     if( !HasPara() && !(IsValid() && IsEmpty()) )
    2032             :     {
    2033             :         // Calc() must be called, because frame position can be wrong
    2034         306 :         const bool bFormat = GetValidSizeFlag();
    2035         306 :         Calc();
    2036             :         // Es kann durchaus sein, dass Calc() das Format()
    2037             :         // nicht anstiess (weil wir einst vom Idle-Zerstoerer
    2038             :         // aufgefordert wurden unsere Formatinformationen wegzuschmeissen).
    2039             :         // 6995: Optimierung mit FormatQuick()
    2040         306 :         if( bFormat && !FormatQuick( bForceQuickFormat ) )
    2041           0 :             Format();
    2042             :     }
    2043             : 
    2044      157232 :     UNDO_SWAP( this )
    2045             : 
    2046      157232 :     return this;
    2047             : }
    2048             : 
    2049        1084 : SwTwips SwTxtFrm::CalcFitToContent()
    2050             : {
    2051             :     // #i31490#
    2052             :     // If we are currently locked, we better return with a
    2053             :     // fairly reasonable value:
    2054        1084 :     if ( IsLocked() )
    2055           0 :         return Prt().Width();
    2056             : 
    2057        1084 :     SwParaPortion* pOldPara = GetPara();
    2058        1084 :     SwParaPortion *pDummy = new SwParaPortion();
    2059        1084 :     SetPara( pDummy, false );
    2060        1084 :     const SwPageFrm* pPage = FindPageFrm();
    2061             : 
    2062        1084 :     const Point   aOldFrmPos   = Frm().Pos();
    2063        1084 :     const SwTwips nOldFrmWidth = Frm().Width();
    2064        1084 :     const SwTwips nOldPrtWidth = Prt().Width();
    2065        1084 :     const SwTwips nPageWidth = GetUpper()->IsVertical() ?
    2066           0 :                                pPage->Prt().Height() :
    2067        1084 :                                pPage->Prt().Width();
    2068             : 
    2069        1084 :     Frm().Width( nPageWidth );
    2070        1084 :     Prt().Width( nPageWidth );
    2071             : 
    2072             :     // #i25422# objects anchored as character in RTL
    2073        1084 :     if ( IsRightToLeft() )
    2074           0 :         Frm().Pos().X() += nOldFrmWidth - nPageWidth;
    2075             : 
    2076             :     // #i31490#
    2077        1084 :     SwTxtFrmLocker aLock( this );
    2078             : 
    2079        2168 :     SwTxtFormatInfo aInf( this, false, true, true );
    2080        1084 :     aInf.SetIgnoreFly( true );
    2081        2168 :     SwTxtFormatter  aLine( this, &aInf );
    2082        2168 :     SwHookOut aHook( aInf );
    2083             : 
    2084             :     // #i54031# - assure mininum of MINLAY twips.
    2085             :     const SwTwips nMax = std::max( (SwTwips)MINLAY,
    2086        1084 :                               aLine._CalcFitToContent() + 1 );
    2087             : 
    2088        1084 :     Frm().Width( nOldFrmWidth );
    2089        1084 :     Prt().Width( nOldPrtWidth );
    2090             : 
    2091             :     // #i25422# objects anchored as character in RTL
    2092        1084 :     if ( IsRightToLeft() )
    2093           0 :         Frm().Pos() = aOldFrmPos;
    2094             : 
    2095        1084 :     SetPara( pOldPara );
    2096             : 
    2097        2168 :     return nMax;
    2098             : }
    2099             : 
    2100             : /** simulate format for a list item paragraph, whose list level attributes
    2101             :     are in LABEL_ALIGNMENT mode, in order to determine additional first
    2102             :     line offset for the real text formatting due to the value of label
    2103             :     adjustment attribute of the list level.
    2104             : */
    2105      131507 : void SwTxtFrm::CalcAdditionalFirstLineOffset()
    2106             : {
    2107      131507 :     if ( IsLocked() )
    2108      131507 :         return;
    2109             : 
    2110             :     // reset additional first line offset
    2111      131507 :     mnAdditionalFirstLineOffset = 0;
    2112             : 
    2113      131507 :     const SwTxtNode* pTxtNode( GetTxtNode() );
    2114      136263 :     if ( pTxtNode && pTxtNode->IsNumbered() && pTxtNode->IsCountedInList() &&
    2115        4756 :          pTxtNode->GetNumRule() )
    2116             :     {
    2117        4756 :         int nListLevel = pTxtNode->GetActualListLevel();
    2118             : 
    2119        4756 :         if (nListLevel < 0)
    2120           0 :             nListLevel = 0;
    2121             : 
    2122        4756 :         if (nListLevel >= MAXLEVEL)
    2123           0 :             nListLevel = MAXLEVEL - 1;
    2124             : 
    2125             :         const SwNumFmt& rNumFmt =
    2126        4756 :                 pTxtNode->GetNumRule()->Get( static_cast<sal_uInt16>(nListLevel) );
    2127        4756 :         if ( rNumFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
    2128             :         {
    2129             :             // keep current paragraph portion and apply dummy paragraph portion
    2130        4296 :             SwParaPortion* pOldPara = GetPara();
    2131        4296 :             SwParaPortion *pDummy = new SwParaPortion();
    2132        4296 :             SetPara( pDummy, false );
    2133             : 
    2134             :             // lock paragraph
    2135        4296 :             SwTxtFrmLocker aLock( this );
    2136             : 
    2137             :             // simulate text formatting
    2138        8592 :             SwTxtFormatInfo aInf( this, false, true, true );
    2139        4296 :             aInf.SetIgnoreFly( true );
    2140        8592 :             SwTxtFormatter aLine( this, &aInf );
    2141        8592 :             SwHookOut aHook( aInf );
    2142        4296 :             aLine._CalcFitToContent();
    2143             : 
    2144             :             // determine additional first line offset
    2145        4296 :             const SwLinePortion* pFirstPortion = aLine.GetCurr()->GetFirstPortion();
    2146        4296 :             if ( pFirstPortion->InNumberGrp() && !pFirstPortion->IsFtnNumPortion() )
    2147             :             {
    2148        4264 :                 SwTwips nNumberPortionWidth( pFirstPortion->Width() );
    2149             : 
    2150        4264 :                 const SwLinePortion* pPortion = pFirstPortion->GetPortion();
    2151       12828 :                 while ( pPortion &&
    2152        4300 :                         pPortion->InNumberGrp() && !pPortion->IsFtnNumPortion())
    2153             :                 {
    2154          18 :                     nNumberPortionWidth += pPortion->Width();
    2155          18 :                     pPortion = pPortion->GetPortion();
    2156             :                 }
    2157             : 
    2158        8528 :                 if ( ( IsRightToLeft() &&
    2159        8530 :                        rNumFmt.GetNumAdjust() == SVX_ADJUST_LEFT ) ||
    2160        8528 :                      ( !IsRightToLeft() &&
    2161        4264 :                        rNumFmt.GetNumAdjust() == SVX_ADJUST_RIGHT ) )
    2162             :                 {
    2163           2 :                     mnAdditionalFirstLineOffset = -nNumberPortionWidth;
    2164             :                 }
    2165        4262 :                 else if ( rNumFmt.GetNumAdjust() == SVX_ADJUST_CENTER )
    2166             :                 {
    2167           0 :                     mnAdditionalFirstLineOffset = -(nNumberPortionWidth/2);
    2168             :                 }
    2169             :             }
    2170             : 
    2171             :             // restore paragraph portion
    2172        8592 :             SetPara( pOldPara );
    2173             :         }
    2174             :     }
    2175             : }
    2176             : 
    2177             : /** determine height of last line for the calculation of the proportional line
    2178             :     spacing
    2179             : 
    2180             :     OD 08.01.2004 #i11859#
    2181             :     OD 2004-03-17 #i11860# - method <GetHeightOfLastLineForPropLineSpacing()>
    2182             :     replace by method <_CalcHeightOfLastLine()>. Height of last line will be
    2183             :     stored in new member <mnHeightOfLastLine> and can be accessed via method
    2184             :     <GetHeightOfLastLine()>
    2185             :     OD 2005-05-20 #i47162# - introduce new optional parameter <_bUseFont>
    2186             :     in order to force the usage of the former algorithm to determine the
    2187             :     height of the last line, which uses the font.
    2188             : */
    2189      134807 : void SwTxtFrm::_CalcHeightOfLastLine( const bool _bUseFont )
    2190             : {
    2191             :     // #i71281#
    2192             :     // invalidate printing area, if height of last line changes
    2193      134807 :     const SwTwips mnOldHeightOfLastLine( mnHeightOfLastLine );
    2194             :     // determine output device
    2195      134807 :     SwViewShell* pVsh = getRootFrm()->GetCurrShell();
    2196             :     OSL_ENSURE( pVsh, "<SwTxtFrm::_GetHeightOfLastLineForPropLineSpacing()> - no SwViewShell" );
    2197             :     // #i78921# - make code robust, according to provided patch
    2198             :     // There could be no <SwViewShell> instance in the case of loading a binary
    2199             :     // StarOffice file format containing an embedded Writer document.
    2200      134807 :     if ( !pVsh )
    2201             :     {
    2202           0 :         return;
    2203             :     }
    2204      134807 :     OutputDevice* pOut = pVsh->GetOut();
    2205      134807 :     const IDocumentSettingAccess* pIDSA = GetTxtNode()->getIDocumentSettingAccess();
    2206      134891 :     if ( !pVsh->GetViewOptions()->getBrowseMode() ||
    2207          84 :           pVsh->GetViewOptions()->IsPrtFormat() )
    2208             :     {
    2209      134723 :         pOut = GetTxtNode()->getIDocumentDeviceAccess()->getReferenceDevice( true );
    2210             :     }
    2211             :     OSL_ENSURE( pOut, "<SwTxtFrm::_GetHeightOfLastLineForPropLineSpacing()> - no OutputDevice" );
    2212             :     // #i78921# - make code robust, according to provided patch
    2213      134807 :     if ( !pOut )
    2214             :     {
    2215           0 :         return;
    2216             :     }
    2217             : 
    2218             :     // determine height of last line
    2219             : 
    2220      134807 :     if ( _bUseFont || pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING ) )
    2221             :     {
    2222             :         // former determination of last line height for proprotional line
    2223             :         // spacing - take height of font set at the paragraph
    2224        4496 :         SwFont aFont( GetAttrSet(), pIDSA );
    2225             : 
    2226             :         // we must ensure that the font is restored correctly on the OutputDevice
    2227             :         // otherwise Last!=Owner could occur
    2228        4496 :         if ( pLastFont )
    2229             :         {
    2230        4496 :             SwFntObj *pOldFont = pLastFont;
    2231        4496 :             pLastFont = NULL;
    2232        4496 :             aFont.SetFntChg( true );
    2233        4496 :             aFont.ChgPhysFnt( pVsh, *pOut );
    2234        4496 :             mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
    2235        4496 :             pLastFont->Unlock();
    2236        4496 :             pLastFont = pOldFont;
    2237        4496 :             pLastFont->SetDevFont( pVsh, *pOut );
    2238             :         }
    2239             :         else
    2240             :         {
    2241           0 :             vcl::Font aOldFont = pOut->GetFont();
    2242           0 :             aFont.SetFntChg( true );
    2243           0 :             aFont.ChgPhysFnt( pVsh, *pOut );
    2244           0 :             mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
    2245           0 :             pLastFont->Unlock();
    2246           0 :             pLastFont = NULL;
    2247           0 :             pOut->SetFont( aOldFont );
    2248        4496 :         }
    2249             :     }
    2250             :     else
    2251             :     {
    2252             :         // new determination of last line height - take actually height of last line
    2253             :         // #i89000#
    2254             :         // assure same results, if paragraph is undersized
    2255      130311 :         if ( IsUndersized() )
    2256             :         {
    2257       10072 :             mnHeightOfLastLine = 0;
    2258             :         }
    2259             :         else
    2260             :         {
    2261      120239 :             bool bCalcHeightOfLastLine = true;
    2262      120239 :             if ( ( !HasPara() && IsEmpty( ) ) || GetTxt().isEmpty() )
    2263             :             {
    2264       49027 :                 mnHeightOfLastLine = EmptyHeight();
    2265       49027 :                 bCalcHeightOfLastLine = false;
    2266             :             }
    2267             : 
    2268      120239 :             if ( bCalcHeightOfLastLine )
    2269             :             {
    2270             :                 OSL_ENSURE( HasPara(),
    2271             :                         "<SwTxtFrm::_CalcHeightOfLastLine()> - missing paragraph portions." );
    2272       71212 :                 const SwLineLayout* pLineLayout = GetPara();
    2273      246174 :                 while ( pLineLayout && pLineLayout->GetNext() )
    2274             :                 {
    2275             :                     // iteration to last line
    2276      103750 :                     pLineLayout = pLineLayout->GetNext();
    2277             :                 }
    2278       71212 :                 if ( pLineLayout )
    2279             :                 {
    2280             :                     SwTwips nAscent, nDescent, nDummy1, nDummy2;
    2281             :                     // #i47162# - suppress consideration of
    2282             :                     // fly content portions and the line portion.
    2283             :                     pLineLayout->MaxAscentDescent( nAscent, nDescent,
    2284             :                                                    nDummy1, nDummy2,
    2285       71212 :                                                    0, true );
    2286             :                     // #i71281#
    2287             :                     // Suppress wrong invalidation of printing area, if method is
    2288             :                     // called recursive.
    2289             :                     // Thus, member <mnHeightOfLastLine> is only set directly, if
    2290             :                     // no recursive call is needed.
    2291       71212 :                     const SwTwips nNewHeightOfLastLine = nAscent + nDescent;
    2292             :                     // #i47162# - if last line only contains
    2293             :                     // fly content portions, <mnHeightOfLastLine> is zero.
    2294             :                     // In this case determine height of last line by the font
    2295       71212 :                     if ( nNewHeightOfLastLine == 0 )
    2296             :                     {
    2297        4446 :                         _CalcHeightOfLastLine( true );
    2298             :                     }
    2299             :                     else
    2300             :                     {
    2301       66766 :                         mnHeightOfLastLine = nNewHeightOfLastLine;
    2302             :                     }
    2303             :                 }
    2304             :             }
    2305             :         }
    2306             :     }
    2307             :     // #i71281#
    2308             :     // invalidate printing area, if height of last line changes
    2309      134807 :     if ( mnHeightOfLastLine != mnOldHeightOfLastLine )
    2310             :     {
    2311       60837 :         InvalidatePrt();
    2312             :     }
    2313             : }
    2314             : 
    2315             : // OD 07.01.2004 #i11859# - change return data type
    2316             : //      add default parameter <_bNoPropLineSpacing> to control, if the
    2317             : //      value of a proportional line spacing is returned or not
    2318             : // OD 07.01.2004 - trying to describe purpose of method:
    2319             : //      Method returns the value of the inter line spacing for a text frame.
    2320             : //      Such a value exists for proportional line spacings ("1,5 Lines",
    2321             : //      "Double", "Proportional" and for leading line spacing ("Leading").
    2322             : //      By parameter <_bNoPropLineSpace> (default value false) it can be
    2323             : //      controlled, if the value of a proportional line spacing is returned.
    2324      166938 : long SwTxtFrm::GetLineSpace( const bool _bNoPropLineSpace ) const
    2325             : {
    2326      166938 :     long nRet = 0;
    2327             : 
    2328      166938 :     const SwAttrSet* pSet = GetAttrSet();
    2329      166938 :     const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
    2330             : 
    2331      166938 :     switch( rSpace.GetInterLineSpaceRule() )
    2332             :     {
    2333             :         case SVX_INTER_LINE_SPACE_PROP:
    2334             :         {
    2335             :             // OD 07.01.2004 #i11859#
    2336       54230 :             if ( _bNoPropLineSpace )
    2337             :             {
    2338       33738 :                 break;
    2339             :             }
    2340             : 
    2341             :             // OD 2004-03-17 #i11860# - use method <GetHeightOfLastLine()>
    2342       20492 :             nRet = GetHeightOfLastLine();
    2343             : 
    2344       20492 :             long nTmp = nRet;
    2345       20492 :             nTmp *= rSpace.GetPropLineSpace();
    2346       20492 :             nTmp /= 100;
    2347       20492 :             nTmp -= nRet;
    2348       20492 :             if ( nTmp > 0 )
    2349       19816 :                 nRet = nTmp;
    2350             :             else
    2351         676 :                 nRet = 0;
    2352             :         }
    2353       20492 :             break;
    2354             :         case SVX_INTER_LINE_SPACE_FIX:
    2355             :         {
    2356           0 :             if ( rSpace.GetInterLineSpace() > 0 )
    2357           0 :                 nRet = rSpace.GetInterLineSpace();
    2358             :         }
    2359           0 :             break;
    2360             :         default:
    2361      112708 :             break;
    2362             :     }
    2363      166938 :     return nRet;
    2364             : }
    2365             : 
    2366        2720 : sal_uInt16 SwTxtFrm::FirstLineHeight() const
    2367             : {
    2368        2720 :     if ( !HasPara() )
    2369             :     {
    2370         274 :         if( IsEmpty() && IsValid() )
    2371         272 :             return IsVertical() ? (sal_uInt16)Prt().Width() : (sal_uInt16)Prt().Height();
    2372           2 :         return USHRT_MAX;
    2373             :     }
    2374        2446 :     const SwParaPortion *pPara = GetPara();
    2375        2446 :     if ( !pPara )
    2376           0 :         return USHRT_MAX;
    2377             : 
    2378        2446 :     return pPara->Height();
    2379             : }
    2380             : 
    2381          38 : sal_uInt16 SwTxtFrm::GetLineCount( sal_Int32 nPos )
    2382             : {
    2383          38 :     sal_uInt16 nRet = 0;
    2384          38 :     SwTxtFrm *pFrm = this;
    2385          38 :     do
    2386             :     {
    2387          38 :         pFrm->GetFormatted();
    2388          38 :         if( !pFrm->HasPara() )
    2389           0 :             break;
    2390          38 :         SwTxtSizeInfo aInf( pFrm );
    2391          76 :         SwTxtMargin aLine( pFrm, &aInf );
    2392          38 :         if( COMPLETE_STRING == nPos )
    2393          38 :             aLine.Bottom();
    2394             :         else
    2395           0 :             aLine.CharToLine( nPos );
    2396          38 :         nRet = nRet + aLine.GetLineNr();
    2397          76 :         pFrm = pFrm->GetFollow();
    2398          38 :     } while ( pFrm && pFrm->GetOfst() <= nPos );
    2399          38 :     return nRet;
    2400             : }
    2401             : 
    2402      131155 : void SwTxtFrm::ChgThisLines()
    2403             : {
    2404             :     // not necessary to format here (GerFormatted etc.), because we have to come from there!
    2405      131155 :     sal_uLong nNew = 0;
    2406      131155 :     const SwLineNumberInfo &rInf = GetNode()->GetDoc()->GetLineNumberInfo();
    2407      131155 :     if ( !GetTxt().isEmpty() && HasPara() )
    2408             :     {
    2409       75652 :         SwTxtSizeInfo aInf( this );
    2410      151304 :         SwTxtMargin aLine( this, &aInf );
    2411       75652 :         if ( rInf.IsCountBlankLines() )
    2412             :         {
    2413       75652 :             aLine.Bottom();
    2414       75652 :             nNew = (sal_uLong)aLine.GetLineNr();
    2415             :         }
    2416             :         else
    2417             :         {
    2418           0 :             do
    2419             :             {
    2420           0 :                 if( aLine.GetCurr()->HasCntnt() )
    2421           0 :                     ++nNew;
    2422           0 :             } while ( aLine.NextLine() );
    2423       75652 :         }
    2424             :     }
    2425       55503 :     else if ( rInf.IsCountBlankLines() )
    2426       55503 :         nNew = 1;
    2427             : 
    2428      131155 :     if ( nNew != nThisLines )
    2429             :     {
    2430       60419 :         if ( !IsInTab() && GetAttrSet()->GetLineNumber().IsCount() )
    2431             :         {
    2432       43061 :             nAllLines -= nThisLines;
    2433       43061 :             nThisLines = nNew;
    2434       43061 :             nAllLines  += nThisLines;
    2435       43061 :             SwFrm *pNxt = GetNextCntntFrm();
    2436       86616 :             while( pNxt && pNxt->IsInTab() )
    2437             :             {
    2438         494 :                 if( 0 != (pNxt = pNxt->FindTabFrm()) )
    2439         494 :                     pNxt = pNxt->FindNextCnt();
    2440             :             }
    2441       43061 :             if( pNxt )
    2442       33564 :                 pNxt->InvalidateLineNum();
    2443             : 
    2444             :             // Extend repaint to the bottom.
    2445       43061 :             if ( HasPara() )
    2446             :             {
    2447       31163 :                 SwRepaint& rRepaint = GetPara()->GetRepaint();
    2448       31163 :                 rRepaint.Bottom( std::max( rRepaint.Bottom(),
    2449       62326 :                                        Frm().Top()+Prt().Bottom()));
    2450             :             }
    2451             :         }
    2452             :         else // Paragraphs which are not counted should not manipulate the AllLines.
    2453       17358 :             nThisLines = nNew;
    2454             :     }
    2455      131155 : }
    2456             : 
    2457       62548 : void SwTxtFrm::RecalcAllLines()
    2458             : {
    2459       62548 :     ValidateLineNum();
    2460             : 
    2461       62548 :     const SwAttrSet *pAttrSet = GetAttrSet();
    2462             : 
    2463       62548 :     if ( !IsInTab() )
    2464             :     {
    2465       43802 :         const sal_uLong nOld = GetAllLines();
    2466       43802 :         const SwFmtLineNumber &rLineNum = pAttrSet->GetLineNumber();
    2467             :         sal_uLong nNewNum;
    2468       43802 :         const bool bRestart = GetTxtNode()->GetDoc()->GetLineNumberInfo().IsRestartEachPage();
    2469             : 
    2470       43802 :         if ( !IsFollow() && rLineNum.GetStartValue() && rLineNum.IsCount() )
    2471           6 :             nNewNum = rLineNum.GetStartValue() - 1;
    2472             :         // If it is a follow or not has not be considered if it is a restart at each page; the
    2473             :         // restart should also take affekt at follows.
    2474       43796 :         else if ( bRestart && FindPageFrm()->FindFirstBodyCntnt() == this )
    2475             :         {
    2476           0 :             nNewNum = 0;
    2477             :         }
    2478             :         else
    2479             :         {
    2480       43796 :             SwCntntFrm *pPrv = GetPrevCntntFrm();
    2481      223450 :             while ( pPrv &&
    2482      116980 :                     (pPrv->IsInTab() || pPrv->IsInDocBody() != IsInDocBody()) )
    2483       33590 :                 pPrv = pPrv->GetPrevCntntFrm();
    2484             : 
    2485             :             // #i78254# Restart line numbering at page change
    2486             :             // First body content may be in table!
    2487       43796 :             if ( bRestart && pPrv && pPrv->FindPageFrm() != FindPageFrm() )
    2488           0 :                 pPrv = 0;
    2489             : 
    2490       43796 :             nNewNum = pPrv ? ((SwTxtFrm*)pPrv)->GetAllLines() : 0;
    2491             :         }
    2492       43802 :         if ( rLineNum.IsCount() )
    2493       43454 :             nNewNum += GetThisLines();
    2494             : 
    2495       43802 :         if ( nOld != nNewNum )
    2496             :         {
    2497       34540 :             nAllLines = nNewNum;
    2498       34540 :             SwCntntFrm *pNxt = GetNextCntntFrm();
    2499      575006 :             while ( pNxt &&
    2500      371334 :                     (pNxt->IsInTab() || pNxt->IsInDocBody() != IsInDocBody()) )
    2501      158272 :                 pNxt = pNxt->GetNextCntntFrm();
    2502       34540 :             if ( pNxt )
    2503             :             {
    2504       31110 :                 if ( pNxt->GetUpper() != GetUpper() )
    2505       13849 :                     pNxt->InvalidateLineNum();
    2506             :                 else
    2507       17261 :                     pNxt->_InvalidateLineNum();
    2508             :             }
    2509             :         }
    2510             :     }
    2511       62548 : }
    2512             : 
    2513        1800 : void SwTxtFrm::VisitPortions( SwPortionHandler& rPH ) const
    2514             : {
    2515        1800 :     const SwParaPortion* pPara = IsValid() ? GetPara() : NULL;
    2516             : 
    2517        1800 :     if (pPara)
    2518             :     {
    2519        1006 :         if ( IsFollow() )
    2520           0 :             rPH.Skip( GetOfst() );
    2521             : 
    2522        1006 :         const SwLineLayout* pLine = pPara;
    2523        3070 :         while ( pLine )
    2524             :         {
    2525        1058 :             const SwLinePortion* pPor = pLine->GetFirstPortion();
    2526        3550 :             while ( pPor )
    2527             :             {
    2528        1434 :                 pPor->HandlePortion( rPH );
    2529        1434 :                 pPor = pPor->GetPortion();
    2530             :             }
    2531             : 
    2532        1058 :             rPH.LineBreak(pLine->Width());
    2533        1058 :             pLine = pLine->GetNext();
    2534             :         }
    2535             :     }
    2536             : 
    2537        1800 :     rPH.Finish();
    2538        1800 : }
    2539             : 
    2540      159299 : const SwScriptInfo* SwTxtFrm::GetScriptInfo() const
    2541             : {
    2542      159299 :     const SwParaPortion* pPara = GetPara();
    2543      159299 :     return pPara ? &pPara->GetScriptInfo() : 0;
    2544             : }
    2545             : 
    2546             : // Helper function for SwTxtFrm::CalcBasePosForFly()
    2547      206368 : static SwTwips lcl_CalcFlyBasePos( const SwTxtFrm& rFrm, SwRect aFlyRect,
    2548             :                             SwTxtFly& rTxtFly )
    2549             : {
    2550      206368 :     SWRECTFN( (&rFrm) )
    2551      206368 :     SwTwips nRet = rFrm.IsRightToLeft() ?
    2552         276 :                    (rFrm.Frm().*fnRect->fnGetRight)() :
    2553      206644 :                    (rFrm.Frm().*fnRect->fnGetLeft)();
    2554             : 
    2555         218 :     do
    2556             :     {
    2557      206544 :         SwRect aRect = rTxtFly.GetFrm( aFlyRect );
    2558      206544 :         if ( 0 != (aRect.*fnRect->fnGetWidth)() )
    2559             :         {
    2560         704 :             if ( rFrm.IsRightToLeft() )
    2561             :             {
    2562           0 :                 if ( (aRect.*fnRect->fnGetRight)() -
    2563           0 :                      (aFlyRect.*fnRect->fnGetRight)() >= 0 )
    2564             :                 {
    2565             :                     (aFlyRect.*fnRect->fnSetRight)(
    2566           0 :                         (aRect.*fnRect->fnGetLeft)() );
    2567           0 :                     nRet = (aRect.*fnRect->fnGetLeft)();
    2568             :                 }
    2569             :                 else
    2570      206326 :                     break;
    2571             :             }
    2572             :             else
    2573             :             {
    2574        1408 :                 if ( (aFlyRect.*fnRect->fnGetLeft)() -
    2575         704 :                      (aRect.*fnRect->fnGetLeft)() >= 0 )
    2576             :                 {
    2577             :                     (aFlyRect.*fnRect->fnSetLeft)(
    2578         218 :                         (aRect.*fnRect->fnGetRight)() + 1 );
    2579         218 :                     nRet = (aRect.*fnRect->fnGetRight)();
    2580             :                 }
    2581             :                 else
    2582         486 :                     break;
    2583             :             }
    2584             :         }
    2585             :         else
    2586      205840 :             break;
    2587             :     }
    2588         218 :     while ( (aFlyRect.*fnRect->fnGetWidth)() > 0 );
    2589             : 
    2590      206368 :     return nRet;
    2591             : }
    2592             : 
    2593      130361 : void SwTxtFrm::CalcBaseOfstForFly()
    2594             : {
    2595             :     OSL_ENSURE( !IsVertical() || !IsSwapped(),
    2596             :             "SwTxtFrm::CalcBasePosForFly with swapped frame!" );
    2597             : 
    2598      130361 :     const SwNode* pNode = GetTxtNode();
    2599      130361 :     if ( !pNode->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_FLY_OFFSETS) )
    2600      157538 :         return;
    2601             : 
    2602      103184 :     SWRECTFN( this )
    2603             : 
    2604      103184 :     SwRect aFlyRect( Frm().Pos() + Prt().Pos(), Prt().SSize() );
    2605             : 
    2606             :     // Get first 'real' line and adjust position and height of line rectangle
    2607             :     // OD 08.09.2003 #110978#, #108749#, #110354# - correct behaviour,
    2608             :     // if no 'real' line exists (empty paragraph with and without a dummy portion)
    2609             :     {
    2610      103184 :         SwTwips nTop = (aFlyRect.*fnRect->fnGetTop)();
    2611      103184 :         const SwLineLayout* pLay = GetPara();
    2612      103184 :         SwTwips nLineHeight = 200;
    2613      206484 :         while( pLay && pLay->IsDummy() && pLay->GetNext() )
    2614             :         {
    2615         116 :             nTop += pLay->Height();
    2616         116 :             pLay = pLay->GetNext();
    2617             :         }
    2618      103184 :         if ( pLay )
    2619             :         {
    2620       79496 :             nLineHeight = pLay->Height();
    2621             :         }
    2622      103184 :         (aFlyRect.*fnRect->fnSetTopAndHeight)( nTop, nLineHeight );
    2623             :     }
    2624             : 
    2625      103184 :     SwTxtFly aTxtFly( this );
    2626      103184 :     aTxtFly.SetIgnoreCurrentFrame( true );
    2627      103184 :     aTxtFly.SetIgnoreContour( true );
    2628             :     // #118809# - ignore objects in page header|footer for
    2629             :     // text frames not in page header|footer
    2630      103184 :     aTxtFly.SetIgnoreObjsInHeaderFooter( true );
    2631      103184 :     SwTwips nRet1 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly );
    2632      103184 :     aTxtFly.SetIgnoreCurrentFrame( false );
    2633      103184 :     SwTwips nRet2 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly );
    2634             : 
    2635             :     // make values relative to frame start position
    2636      103184 :     SwTwips nLeft = IsRightToLeft() ?
    2637         138 :                     (Frm().*fnRect->fnGetRight)() :
    2638      103322 :                     (Frm().*fnRect->fnGetLeft)();
    2639             : 
    2640      103184 :     mnFlyAnchorOfst = nRet1 - nLeft;
    2641      103184 :     mnFlyAnchorOfstNoWrap = nRet2 - nLeft;
    2642             : }
    2643             : 
    2644             : /* repaint all text frames of the given text node */
    2645           0 : void SwTxtFrm::repaintTextFrames( const SwTxtNode& rNode )
    2646             : {
    2647           0 :     SwIterator<SwTxtFrm,SwTxtNode> aIter( rNode );
    2648           0 :     for( const SwTxtFrm *pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
    2649             :     {
    2650           0 :         SwRect aRec( pFrm->PaintArea() );
    2651           0 :         const SwRootFrm *pRootFrm = pFrm->getRootFrm();
    2652           0 :         SwViewShell *pCurShell = pRootFrm ? pRootFrm->GetCurrShell() : NULL;
    2653           0 :         if( pCurShell )
    2654           0 :             pCurShell->InvalidateWindows( aRec );
    2655           0 :     }
    2656         270 : }
    2657             : 
    2658             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10