LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/text - txtfrm.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 759 1265 60.0 %
Date: 2013-07-09 Functions: 50 68 73.5 %
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>      // GetDoc()
      34             : #include "rootfrm.hxx"
      35             : #include <pagefrm.hxx>  // InvalidateSpelling
      36             : #include <rootfrm.hxx>
      37             : #include <viewsh.hxx>   // ViewShell
      38             : #include <pam.hxx>      // SwPosition
      39             : #include <ndtxt.hxx>        // SwTxtNode
      40             : #include <txtatr.hxx>
      41             : #include <paratr.hxx>
      42             : #include <viewopt.hxx>
      43             : #include <dflyobj.hxx>
      44             : #include <flyfrm.hxx>
      45             : #include <tabfrm.hxx>
      46             : #include <frmtool.hxx>
      47             : #include <pagedesc.hxx> // SwPageDesc
      48             : #include <tgrditem.hxx>
      49             : #include <dbg_lay.hxx>
      50             : #include <fmtfld.hxx>
      51             : #include <fmtftn.hxx>
      52             : #include <txtfld.hxx>
      53             : #include <txtftn.hxx>
      54             : #include <charatr.hxx>
      55             : #include <ftninfo.hxx>
      56             : #include <fmtline.hxx>
      57             : #include <txtfrm.hxx>       // SwTxtFrm
      58             : #include <sectfrm.hxx>      // SwSectFrm
      59             : #include <itrform2.hxx>       // Iteratoren
      60             : #include <widorp.hxx>       // SwFrmBreak
      61             : #include <txtcache.hxx>
      62             : #include <fntcache.hxx>     // GetLineSpace benutzt pLastFont
      63             : #include <SwGrammarMarkUp.hxx>
      64             : #include <lineinfo.hxx>
      65             : #include <SwPortionHandler.hxx>
      66             : #include <dcontact.hxx>
      67             : #include <sortedobjs.hxx>
      68             : #include <txtflcnt.hxx>     // SwTxtFlyCnt
      69             : #include <fmtflcnt.hxx>     // SwFmtFlyCnt
      70             : #include <fmtcntnt.hxx>     // SwFmtCntnt
      71             : #include <numrule.hxx>
      72             : #include <swtable.hxx>
      73             : #include <fldupde.hxx>
      74             : #include <IGrammarContact.hxx>
      75             : #include <switerator.hxx>
      76             : 
      77             : 
      78     1660164 : TYPEINIT1( SwTxtFrm, SwCntntFrm );
      79             : 
      80             : // Switches width and height of the text frame
      81          60 : void SwTxtFrm::SwapWidthAndHeight()
      82             : {
      83          60 :     if ( ! bIsSwapped )
      84             :     {
      85          30 :         const long nPrtOfstX = Prt().Pos().X();
      86          30 :         Prt().Pos().X() = Prt().Pos().Y();
      87             :         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
      88          30 :         if( IsVertLR() )
      89           0 :             Prt().Pos().Y() = nPrtOfstX;
      90             :         else
      91          30 :             Prt().Pos().Y() = Frm().Width() - ( nPrtOfstX + Prt().Width() );
      92             : 
      93             :     }
      94             :     else
      95             :     {
      96          30 :         const long nPrtOfstY = Prt().Pos().Y();
      97          30 :         Prt().Pos().Y() = Prt().Pos().X();
      98             :         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
      99          30 :         if( IsVertLR() )
     100           0 :             Prt().Pos().X() = nPrtOfstY;
     101             :         else
     102          30 :             Prt().Pos().X() = Frm().Height() - ( nPrtOfstY + Prt().Height() );
     103             :     }
     104             : 
     105          60 :     const long nFrmWidth = Frm().Width();
     106          60 :     Frm().Width( Frm().Height() );
     107          60 :     Frm().Height( nFrmWidth );
     108          60 :     const long nPrtWidth = Prt().Width();
     109          60 :     Prt().Width( Prt().Height() );
     110          60 :     Prt().Height( nPrtWidth );
     111             : 
     112          60 :     bIsSwapped = ! bIsSwapped;
     113          60 : }
     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             :     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     121             :     long nOfstX, nOfstY;
     122           0 :     if ( IsVertLR() )
     123             :     {
     124           0 :         nOfstX = rRect.Left() - Frm().Left();
     125           0 :         nOfstY = rRect.Top() - Frm().Top();
     126             :     }
     127             :     else
     128             :     {
     129           0 :         nOfstX = rRect.Left() - Frm().Left();
     130           0 :         nOfstY = rRect.Top() + rRect.Height() - Frm().Top();
     131             :     }
     132             : 
     133           0 :     const long nWidth = rRect.Width();
     134           0 :     const long nHeight = rRect.Height();
     135             : 
     136             :     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     137           0 :     if ( IsVertLR() )
     138           0 :         rRect.Left(Frm().Left() + nOfstY);
     139             :     else
     140             :     {
     141           0 :         if ( bIsSwapped )
     142           0 :             rRect.Left( Frm().Left() + Frm().Height() - nOfstY );
     143             :         else
     144             :             // frame is rotated
     145           0 :             rRect.Left( Frm().Left() + Frm().Width() - nOfstY );
     146             :     }
     147             : 
     148           0 :     rRect.Top( Frm().Top() + nOfstX );
     149           0 :     rRect.Width( nHeight );
     150           0 :     rRect.Height( nWidth );
     151           0 : }
     152             : 
     153             : // Calculates the coordinates of a point when switching from
     154             : // horizontal to vertical layout.
     155          24 : void SwTxtFrm::SwitchHorizontalToVertical( Point& rPoint ) const
     156             : {
     157             :     // calc offset inside frame
     158          24 :     const long nOfstX = rPoint.X() - Frm().Left();
     159          24 :     const long nOfstY = rPoint.Y() - Frm().Top();
     160             :     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     161          24 :     if ( IsVertLR() )
     162           0 :         rPoint.X() = Frm().Left() + nOfstY;
     163             :     else
     164             :     {
     165          24 :         if ( bIsSwapped )
     166          24 :             rPoint.X() = Frm().Left() + Frm().Height() - nOfstY;
     167             :         else
     168             :             // calc rotated coords
     169           0 :             rPoint.X() = Frm().Left() + Frm().Width() - nOfstY;
     170             :     }
     171             : 
     172          24 :     rPoint.Y() = Frm().Top() + nOfstX;
     173          24 : }
     174             : 
     175             : // Calculates the a limit value when switching from
     176             : // horizontal to vertical layout.
     177           0 : long SwTxtFrm::SwitchHorizontalToVertical( long nLimit ) const
     178             : {
     179           0 :     Point aTmp( 0, nLimit );
     180           0 :     SwitchHorizontalToVertical( aTmp );
     181           0 :     return aTmp.X();
     182             : }
     183             : 
     184             : // Calculates the coordinates of a rectangle when switching from
     185             : // vertical to horizontal layout.
     186           0 : void SwTxtFrm::SwitchVerticalToHorizontal( SwRect& rRect ) const
     187             : {
     188             :     long nOfstX;
     189             : 
     190             :     // calc offset inside frame
     191             : 
     192             :     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     193           0 :     if ( IsVertLR() )
     194           0 :         nOfstX = rRect.Left() - Frm().Left();
     195             :     else
     196             :     {
     197           0 :         if ( bIsSwapped )
     198           0 :             nOfstX = Frm().Left() + Frm().Height() - ( rRect.Left() + rRect.Width() );
     199             :         else
     200           0 :             nOfstX = Frm().Left() + Frm().Width() - ( rRect.Left() + rRect.Width() );
     201             :     }
     202             : 
     203           0 :     const long nOfstY = rRect.Top() - Frm().Top();
     204           0 :     const long nWidth = rRect.Height();
     205           0 :     const long nHeight = rRect.Width();
     206             : 
     207             :     // calc rotated coords
     208           0 :     rRect.Left( Frm().Left() + nOfstY );
     209           0 :     rRect.Top( Frm().Top() + nOfstX );
     210           0 :     rRect.Width( nWidth );
     211           0 :     rRect.Height( nHeight );
     212           0 : }
     213             : 
     214             : // Calculates the coordinates of a point when switching from
     215             : // vertical to horizontal layout.
     216           0 : void SwTxtFrm::SwitchVerticalToHorizontal( Point& rPoint ) const
     217             : {
     218             :     long nOfstX;
     219             : 
     220             :     // calc offset inside frame
     221             : 
     222             :     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     223           0 :     if ( IsVertLR() )
     224           0 :         nOfstX = rPoint.X() - Frm().Left();
     225             :     else
     226             :     {
     227           0 :         if ( bIsSwapped )
     228           0 :             nOfstX = Frm().Left() + Frm().Height() - rPoint.X();
     229             :         else
     230           0 :             nOfstX = Frm().Left() + Frm().Width() - rPoint.X();
     231             :     }
     232             : 
     233           0 :     const long nOfstY = rPoint.Y() - Frm().Top();
     234             : 
     235             :     // calc rotated coords
     236           0 :     rPoint.X() = Frm().Left() + nOfstY;
     237           0 :     rPoint.Y() = Frm().Top() + nOfstX;
     238           0 : }
     239             : 
     240             : // Calculates the a limit value when switching from
     241             : // vertical to horizontal layout.
     242           0 : long SwTxtFrm::SwitchVerticalToHorizontal( long nLimit ) const
     243             : {
     244           0 :     Point aTmp( nLimit, 0 );
     245           0 :     SwitchVerticalToHorizontal( aTmp );
     246           0 :     return aTmp.Y();
     247             : }
     248             : 
     249      188452 : SwFrmSwapper::SwFrmSwapper( const SwTxtFrm* pTxtFrm, sal_Bool bSwapIfNotSwapped )
     250      188452 :     : pFrm( pTxtFrm ), bUndo( sal_False )
     251             : {
     252      188464 :     if ( pFrm->IsVertical() &&
     253          12 :         ( (   bSwapIfNotSwapped && ! pFrm->IsSwapped() ) ||
     254          11 :           ( ! bSwapIfNotSwapped && pFrm->IsSwapped() ) ) )
     255             :     {
     256          12 :         bUndo = sal_True;
     257          12 :         ((SwTxtFrm*)pFrm)->SwapWidthAndHeight();
     258             :     }
     259      188452 : }
     260             : 
     261      188452 : SwFrmSwapper::~SwFrmSwapper()
     262             : {
     263      188452 :     if ( bUndo )
     264          12 :         ((SwTxtFrm*)pFrm)->SwapWidthAndHeight();
     265      188452 : }
     266             : 
     267          38 : void SwTxtFrm::SwitchLTRtoRTL( SwRect& rRect ) const
     268             : {
     269          38 :     SWAP_IF_NOT_SWAPPED( this )
     270             : 
     271          38 :     long nWidth = rRect.Width();
     272          76 :     rRect.Left( 2 * ( Frm().Left() + Prt().Left() ) +
     273          76 :                 Prt().Width() - rRect.Right() - 1 );
     274             : 
     275          38 :     rRect.Width( nWidth );
     276             : 
     277          38 :     UNDO_SWAP( this )
     278          38 : }
     279             : 
     280           0 : void SwTxtFrm::SwitchLTRtoRTL( Point& rPoint ) const
     281             : {
     282           0 :     SWAP_IF_NOT_SWAPPED( this )
     283             : 
     284           0 :     rPoint.X() = 2 * ( Frm().Left() + Prt().Left() ) + Prt().Width() - rPoint.X() - 1;
     285             : 
     286           0 :     UNDO_SWAP( this )
     287           0 : }
     288             : 
     289        2584 : SwLayoutModeModifier::SwLayoutModeModifier( const OutputDevice& rOutp ) :
     290        2584 :         rOut( rOutp ), nOldLayoutMode( rOutp.GetLayoutMode() )
     291             : {
     292        2584 : }
     293             : 
     294        2584 : SwLayoutModeModifier::~SwLayoutModeModifier()
     295             : {
     296        2584 :     ((OutputDevice&)rOut).SetLayoutMode( nOldLayoutMode );
     297        2584 : }
     298             : 
     299         143 : void SwLayoutModeModifier::Modify( sal_Bool bChgToRTL )
     300             : {
     301             :     ((OutputDevice&)rOut).SetLayoutMode( bChgToRTL ?
     302             :                                          TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL :
     303         143 :                                          TEXT_LAYOUT_BIDI_STRONG );
     304         143 : }
     305             : 
     306        1875 : void SwLayoutModeModifier::SetAuto()
     307             : {
     308        1875 :     const sal_uLong nNewLayoutMode = nOldLayoutMode & ~TEXT_LAYOUT_BIDI_STRONG;
     309        1875 :     ((OutputDevice&)rOut).SetLayoutMode( nNewLayoutMode );
     310        1875 : }
     311             : 
     312       36323 : SwDigitModeModifier::SwDigitModeModifier( const OutputDevice& rOutp, LanguageType eCurLang ) :
     313       36323 :         rOut( rOutp ), nOldLanguageType( rOutp.GetDigitLanguage() )
     314             : {
     315       36323 :     LanguageType eLang = eCurLang;
     316       36323 :     const SvtCTLOptions::TextNumerals nTextNumerals = SW_MOD()->GetCTLOptions().GetCTLTextNumerals();
     317             : 
     318       36323 :     if ( SvtCTLOptions::NUMERALS_HINDI == nTextNumerals )
     319           0 :         eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
     320       36323 :     else if ( SvtCTLOptions::NUMERALS_ARABIC == nTextNumerals )
     321       36323 :         eLang = LANGUAGE_ENGLISH;
     322           0 :     else if ( SvtCTLOptions::NUMERALS_SYSTEM == nTextNumerals )
     323           0 :         eLang = ::GetAppLanguage();
     324             : 
     325       36323 :     ((OutputDevice&)rOut).SetDigitLanguage( eLang );
     326       36323 : }
     327             : 
     328       36323 : SwDigitModeModifier::~SwDigitModeModifier()
     329             : {
     330       36323 :     ((OutputDevice&)rOut).SetDigitLanguage( nOldLanguageType );
     331       36323 : }
     332             : 
     333             : /*************************************************************************
     334             :  *                      SwTxtFrm::Init()
     335             :  *************************************************************************/
     336             : 
     337        1210 : void SwTxtFrm::Init()
     338             : {
     339             :     OSL_ENSURE( !IsLocked(), "+SwTxtFrm::Init: this ist locked." );
     340        1210 :     if( !IsLocked() )
     341             :     {
     342        1210 :         ClearPara();
     343        1210 :         ResetBlinkPor();
     344             :         //Die Flags direkt setzen um ResetPreps und damit ein unnuetzes GetPara
     345             :         //einzusparen.
     346             :         // Nicht bOrphan, bLocked oder bWait auf sal_False setzen !
     347             :         // bOrphan = bFlag7 = bFlag8 = sal_False;
     348             :     }
     349        1210 : }
     350             : 
     351             : /*************************************************************************
     352             :  *                      SwTxtFrm::SwTxtFrm()
     353             :  *************************************************************************/
     354        4202 : SwTxtFrm::SwTxtFrm(SwTxtNode * const pNode, SwFrm* pSib )
     355             :     : SwCntntFrm( pNode, pSib )
     356             :     , nAllLines( 0 )
     357             :     , nThisLines( 0 )
     358             :     , mnFlyAnchorOfst( 0 )
     359             :     , mnFlyAnchorOfstNoWrap( 0 )
     360             :     , mnFtnLine( 0 )
     361             :     , mnHeightOfLastLine( 0 ) // OD 2004-03-17 #i11860#
     362             :     , mnAdditionalFirstLineOffset( 0 )
     363             :     , nOfst( 0 )
     364             :     , nCacheIdx( MSHRT_MAX )
     365             :     , bLocked( false )
     366             :     , bFormatted( false )
     367             :     , bWidow( false )
     368             :     , bJustWidow( false )
     369             :     , bEmpty( false )
     370             :     , bInFtnConnect( false )
     371             :     , bFtn( false )
     372             :     , bRepaint( false )
     373             :     , bBlinkPor( false )
     374             :     , bFieldFollow( false )
     375             :     , bHasAnimation( false )
     376             :     , bIsSwapped( false )
     377        4202 :     , mbFollowFormatAllowed( true ) // OD 14.03.2003 #i11760#
     378             : {
     379        4202 :     mnType = FRMC_TXT;
     380        4202 : }
     381             : 
     382             : /*************************************************************************
     383             :  *                      SwTxtFrm::~SwTxtFrm()
     384             :  *************************************************************************/
     385       12492 : SwTxtFrm::~SwTxtFrm()
     386             : {
     387             :     // Remove associated SwParaPortion from pTxtCache
     388        4164 :     ClearPara();
     389        8328 : }
     390             : 
     391       30602 : const XubString& SwTxtFrm::GetTxt() const
     392             : {
     393       30602 :     return reinterpret_cast<const XubString&>(GetTxtNode()->GetTxt()); //FIXME
     394             : }
     395             : 
     396        4502 : void SwTxtFrm::ResetPreps()
     397             : {
     398        4502 :     if ( GetCacheIdx() != MSHRT_MAX )
     399             :     {
     400             :         SwParaPortion *pPara;
     401        4502 :         if( 0 != (pPara = GetPara()) )
     402        4502 :             pPara->ResetPreps();
     403             :     }
     404        4502 : }
     405             : 
     406             : /*************************************************************************
     407             :  *                        SwTxtFrm::IsHiddenNow()
     408             :  *************************************************************************/
     409      137877 : sal_Bool SwTxtFrm::IsHiddenNow() const
     410             : {
     411      137877 :     SwFrmSwapper aSwapper( this, sal_True );
     412             : 
     413      137877 :     if( !Frm().Width() && IsValid() && GetUpper()->IsValid() )
     414             :                                        //bei Stackueberlauf (StackHack) invalid!
     415             :     {
     416             : //        OSL_FAIL( "SwTxtFrm::IsHiddenNow: thin frame" );
     417           8 :         return sal_True;
     418             :     }
     419             : 
     420      137869 :     const bool bHiddenCharsHidePara = GetTxtNode()->HasHiddenCharAttribute( true );
     421      137869 :     const bool bHiddenParaField = GetTxtNode()->HasHiddenParaField();
     422      137869 :     const ViewShell* pVsh = getRootFrm()->GetCurrShell();
     423             : 
     424      137869 :     if ( pVsh && ( bHiddenCharsHidePara || bHiddenParaField ) )
     425             :     {
     426         447 :         if (
     427           0 :              ( bHiddenParaField &&
     428           0 :                ( !pVsh->GetViewOptions()->IsShowHiddenPara() &&
     429        1341 :                  !pVsh->GetViewOptions()->IsFldName() ) ) ||
     430         447 :              ( bHiddenCharsHidePara &&
     431         447 :                !pVsh->GetViewOptions()->IsShowHiddenChar() ) )
     432             :         {
     433         447 :             return sal_True;
     434             :         }
     435             :     }
     436             : 
     437      137422 :     return sal_False;
     438             : }
     439             : 
     440             : 
     441             : /*************************************************************************
     442             :  *                        SwTxtFrm::HideHidden()
     443             :  *************************************************************************/
     444             : // Entfernt die Anhaengsel des Textfrms wenn dieser hidden ist
     445             : 
     446          23 : void SwTxtFrm::HideHidden()
     447             : {
     448             :     OSL_ENSURE( !GetFollow() && IsHiddenNow(),
     449             :             "HideHidden on visible frame of hidden frame has follow" );
     450             : 
     451          23 :     const xub_StrLen nEnd = STRING_LEN;
     452          23 :     HideFootnotes( GetOfst(), nEnd );
     453             :     // OD 2004-01-15 #110582#
     454          23 :     HideAndShowObjects();
     455             : 
     456             :     //Die Formatinfos sind jetzt obsolete
     457          23 :     ClearPara();
     458          23 : }
     459             : 
     460             : /*************************************************************************
     461             :  *                        SwTxtFrm::HideFootnotes()
     462             :  *************************************************************************/
     463          23 : void SwTxtFrm::HideFootnotes( xub_StrLen nStart, xub_StrLen nEnd )
     464             : {
     465          23 :     const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
     466          23 :     if( pHints )
     467             :     {
     468          23 :         const sal_uInt16 nSize = pHints->Count();
     469          23 :         SwPageFrm *pPage = 0;
     470          52 :         for ( sal_uInt16 i = 0; i < nSize; ++i )
     471             :         {
     472          29 :             const SwTxtAttr *pHt = (*pHints)[i];
     473          29 :             if ( pHt->Which() == RES_TXTATR_FTN )
     474             :             {
     475           0 :                 const xub_StrLen 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          23 : }
     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 xub_StrLen _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             :  *                        SwTxtFrm::HideAndShowObjects()
     548             :  *************************************************************************/
     549             : /** method to hide/show objects
     550             : 
     551             :     OD 2004-01-15 #110582#
     552             :     method hides respectively shows objects, which are anchored at paragraph,
     553             :     at/as a character of the paragraph, corresponding to the paragraph and
     554             :     paragraph portion visibility.
     555             : 
     556             :     - is called from HideHidden() - should hide objects in hidden paragraphs and
     557             :     - from _Format() - should hide/show objects in partly visible paragraphs
     558             : */
     559       12024 : void SwTxtFrm::HideAndShowObjects()
     560             : {
     561       12024 :     if ( GetDrawObjs() )
     562             :     {
     563         619 :         if ( IsHiddenNow() )
     564             :         {
     565             :             // complete paragraph is hidden. Thus, hide all objects
     566           0 :             for ( sal_uInt32 i = 0; i < GetDrawObjs()->Count(); ++i )
     567             :             {
     568           0 :                 SdrObject* pObj = (*GetDrawObjs())[i]->DrawObj();
     569           0 :                 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
     570             :                 // #120729# - hotfix
     571             :                 // under certain conditions
     572           0 :                 const RndStdIds eAnchorType( pContact->GetAnchorId() );
     573           0 :                 const xub_StrLen nObjAnchorPos = pContact->GetCntntAnchorIndex().GetIndex();
     574           0 :                 if ((eAnchorType != FLY_AT_CHAR) ||
     575             :                     sw_HideObj( *this, eAnchorType, nObjAnchorPos,
     576           0 :                                  (*GetDrawObjs())[i] ))
     577             :                 {
     578           0 :                     pContact->MoveObjToInvisibleLayer( pObj );
     579             :                 }
     580             :             }
     581             :         }
     582             :         else
     583             :         {
     584             :             // paragraph is visible, but can contain hidden text portion.
     585             :             // first we check if objects are allowed to be hidden:
     586         619 :             const SwTxtNode& rNode = *GetTxtNode();
     587         619 :             const ViewShell* pVsh = getRootFrm()->GetCurrShell();
     588        1238 :             const bool bShouldBeHidden = !pVsh || !pVsh->GetWin() ||
     589        1238 :                                          !pVsh->GetViewOptions()->IsShowHiddenChar();
     590             : 
     591             :             // Thus, show all objects, which are anchored at paragraph and
     592             :             // hide/show objects, which are anchored at/as character, according
     593             :             // to the visibility of the anchor character.
     594        1469 :             for ( sal_uInt32 i = 0; i < GetDrawObjs()->Count(); ++i )
     595             :             {
     596         850 :                 SdrObject* pObj = (*GetDrawObjs())[i]->DrawObj();
     597         850 :                 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
     598             :                 // #120729# - determine anchor type only once
     599         850 :                 const RndStdIds eAnchorType( pContact->GetAnchorId() );
     600             : 
     601         850 :                 if (eAnchorType == FLY_AT_PARA)
     602             :                 {
     603         233 :                     pContact->MoveObjToVisibleLayer( pObj );
     604             :                 }
     605         617 :                 else if ((eAnchorType == FLY_AT_CHAR) ||
     606             :                          (eAnchorType == FLY_AS_CHAR))
     607             :                 {
     608             :                     xub_StrLen nHiddenStart;
     609             :                     xub_StrLen nHiddenEnd;
     610         617 :                     xub_StrLen nObjAnchorPos = pContact->GetCntntAnchorIndex().GetIndex();
     611         617 :                     SwScriptInfo::GetBoundsOfHiddenRange( rNode, nObjAnchorPos, nHiddenStart, nHiddenEnd, 0 );
     612             :                     // #120729# - hotfix
     613             :                     // under certain conditions
     614         617 :                     if ( nHiddenStart != STRING_LEN && bShouldBeHidden &&
     615           0 :                          sw_HideObj( *this, eAnchorType, nObjAnchorPos, (*GetDrawObjs())[i] ) )
     616           0 :                         pContact->MoveObjToInvisibleLayer( pObj );
     617             :                     else
     618         617 :                         pContact->MoveObjToVisibleLayer( pObj );
     619             :                 }
     620             :                 else
     621             :                 {
     622             :                     OSL_FAIL( "<SwTxtFrm::HideAndShowObjects()> - object not anchored at/inside paragraph!?" );
     623             :                 }
     624             :             }
     625             :         }
     626             :     }
     627             : 
     628       12024 :     if (IsFollow())
     629             :     {
     630        1186 :         SwTxtFrm *pMaster = FindMaster();
     631             :         OSL_ENSURE(pMaster, "SwTxtFrm without master");
     632        1186 :         if (pMaster)
     633        1186 :             pMaster->HideAndShowObjects();
     634             :     }
     635       12024 : }
     636             : 
     637             : /*************************************************************************
     638             :  *                      SwTxtFrm::FindBrk()
     639             :  *
     640             :  * Liefert die erste Trennmoeglichkeit in der aktuellen Zeile zurueck.
     641             :  * Die Methode wird in SwTxtFrm::Format() benutzt, um festzustellen, ob
     642             :  * die Vorgaengerzeile mitformatiert werden muss.
     643             :  * nFound ist <= nEndLine.
     644             :  *************************************************************************/
     645             : 
     646        1403 : xub_StrLen SwTxtFrm::FindBrk( const XubString &rTxt,
     647             :                               const xub_StrLen nStart,
     648             :                               const xub_StrLen nEnd ) const
     649             : {
     650             :     // #i104291# - applying patch to avoid overflow.
     651        1403 :     unsigned long nFound = nStart;
     652        1403 :     const xub_StrLen nEndLine = std::min( nEnd, rTxt.Len() );
     653             : 
     654             :     // Wir ueberlesen erst alle Blanks am Anfang der Zeile (vgl. Bug 2235).
     655        4209 :     while( nFound <= nEndLine &&
     656        1403 :            ' ' == rTxt.GetChar( static_cast<xub_StrLen>(nFound) ) )
     657             :     {
     658           0 :          nFound++;
     659             :     }
     660             : 
     661             :     // Eine knifflige Sache mit den TxtAttr-Dummy-Zeichen (hier "$"):
     662             :     // "Dr.$Meyer" am Anfang der zweiten Zeile. Dahinter ein Blank eingegeben
     663             :     // und das Wort rutscht nicht in die erste Zeile, obwohl es ginge.
     664             :     // Aus diesem Grund nehmen wir das Dummy-Zeichen noch mit.
     665       67319 :     while( nFound <= nEndLine &&
     666       32671 :            ' ' != rTxt.GetChar( static_cast<xub_StrLen>(nFound) ) )
     667             :     {
     668       31842 :         nFound++;
     669             :     }
     670             : 
     671             :     return nFound <= STRING_LEN
     672             :            ? static_cast<xub_StrLen>(nFound)
     673        1403 :            : STRING_LEN;
     674             : }
     675             : 
     676             : /*************************************************************************
     677             :  *                      SwTxtFrm::IsIdxInside()
     678             :  *************************************************************************/
     679             : 
     680        7931 : sal_Bool SwTxtFrm::IsIdxInside( const xub_StrLen nPos, const xub_StrLen nLen ) const
     681             : {
     682        7931 :     if( GetOfst() > nPos + nLen ) // d.h., der Bereich liegt komplett vor uns.
     683         189 :         return sal_False;
     684             : 
     685        7742 :     if( !GetFollow() )         // der Bereich liegt nicht komplett vor uns,
     686        6817 :         return sal_True;           // nach uns kommt niemand mehr.
     687             : 
     688         925 :     const xub_StrLen nMax = GetFollow()->GetOfst();
     689             : 
     690             :     // der Bereich liegt nicht komplett hinter uns bzw.
     691             :     // unser Text ist geloescht worden.
     692         925 :     if( nMax > nPos || nMax > GetTxt().Len() )
     693         223 :         return sal_True;
     694             : 
     695             :     // changes made in the first line of a follow can modify the master
     696         702 :     const SwParaPortion* pPara = GetFollow()->GetPara();
     697         702 :     return pPara && ( nPos <= nMax + pPara->GetLen() );
     698             : }
     699             : 
     700             : /*************************************************************************
     701             :  *                      SwTxtFrm::InvalidateRange()
     702             :  *************************************************************************/
     703        1432 : inline void SwTxtFrm::InvalidateRange(const SwCharRange &aRange, const long nD)
     704             : {
     705        1432 :     if ( IsIdxInside( aRange.Start(), aRange.Len() ) )
     706        1411 :         _InvalidateRange( aRange, nD );
     707        1432 : }
     708             : 
     709             : /*************************************************************************
     710             :  *                      SwTxtFrm::_InvalidateRange()
     711             :  *************************************************************************/
     712             : 
     713        6483 : void SwTxtFrm::_InvalidateRange( const SwCharRange &aRange, const long nD)
     714             : {
     715        6483 :     if ( !HasPara() )
     716        1451 :     {   InvalidateSize();
     717        7934 :         return;
     718             :     }
     719             : 
     720        5032 :     SetWidow( sal_False );
     721        5032 :     SwParaPortion *pPara = GetPara();
     722             : 
     723        5032 :     bool bInv = false;
     724        5032 :     if( 0 != nD )
     725             :     {
     726             :         //Auf nDelta werden die Differenzen zwischen alter und
     727             :         //neuer Zeilenlaenge aufaddiert, deshalb ist es negativ,
     728             :         //wenn Zeichen eingefuegt wurden, positiv, wenn Zeichen
     729             :         //geloescht wurden.
     730        3892 :         *(pPara->GetDelta()) += nD;
     731        3892 :         bInv = true;
     732             :     }
     733        5032 :     SwCharRange &rReformat = *(pPara->GetReformat());
     734        5032 :     if(aRange != rReformat) {
     735        4308 :         if( STRING_LEN == rReformat.Len() )
     736           0 :             rReformat = aRange;
     737             :         else
     738        4308 :             rReformat += aRange;
     739        4308 :         bInv = true;
     740             :     }
     741        5032 :     if(bInv)
     742             :     {
     743        4472 :         InvalidateSize();
     744             :     }
     745             : }
     746             : 
     747             : /*************************************************************************
     748             :  *                      SwTxtFrm::CalcLineSpace()
     749             :  *************************************************************************/
     750             : 
     751           0 : void SwTxtFrm::CalcLineSpace()
     752             : {
     753             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
     754             :             "SwTxtFrm::CalcLineSpace with swapped frame!" );
     755             : 
     756           0 :     if( IsLocked() || !HasPara() )
     757           0 :         return;
     758             : 
     759             :     SwParaPortion *pPara;
     760           0 :     if( GetDrawObjs() ||
     761           0 :         GetTxtNode()->GetSwAttrSet().GetLRSpace().IsAutoFirst() ||
     762           0 :         ( pPara = GetPara() )->IsFixLineHeight() )
     763             :     {
     764           0 :         Init();
     765           0 :         return;
     766             :     }
     767             : 
     768           0 :     Size aNewSize( Prt().SSize() );
     769             : 
     770           0 :     SwTxtFormatInfo aInf( this );
     771           0 :     SwTxtFormatter aLine( this, &aInf );
     772           0 :     if( aLine.GetDropLines() )
     773             :     {
     774           0 :         Init();
     775           0 :         return;
     776             :     }
     777             : 
     778           0 :     aLine.Top();
     779           0 :     aLine.RecalcRealHeight();
     780             : 
     781           0 :     aNewSize.Height() = (aLine.Y() - Frm().Top()) + aLine.GetLineHeight();
     782             : 
     783           0 :     SwTwips nDelta = aNewSize.Height() - Prt().Height();
     784             :     // 4291: Unterlauf bei Flys
     785           0 :     if( aInf.GetTxtFly()->IsOn() )
     786             :     {
     787           0 :         SwRect aTmpFrm( Frm() );
     788           0 :         if( nDelta < 0 )
     789           0 :             aTmpFrm.Height( Prt().Height() );
     790             :         else
     791           0 :             aTmpFrm.Height( aNewSize.Height() );
     792           0 :         if( aInf.GetTxtFly()->Relax( aTmpFrm ) )
     793             :         {
     794           0 :             Init();
     795           0 :             return;
     796             :         }
     797             :     }
     798             : 
     799           0 :     if( nDelta )
     800             :     {
     801           0 :         SwTxtFrmBreak aBreak( this );
     802           0 :         if( GetFollow() || aBreak.IsBreakNow( aLine ) )
     803             :         {
     804             :             // Wenn es einen Follow() gibt, oder wenn wir an dieser
     805             :             // Stelle aufbrechen muessen, so wird neu formatiert.
     806           0 :             Init();
     807             :         }
     808             :         else
     809             :         {
     810             :             // Alles nimmt seinen gewohnten Gang ...
     811           0 :             pPara->SetPrepAdjust();
     812           0 :             pPara->SetPrep();
     813             :         }
     814           0 :     }
     815             : }
     816             : 
     817             : //
     818             : // SET_WRONG( nPos, nCnt, bMove )
     819             : //
     820             : #define SET_WRONG( nPos, nCnt, bMove ) \
     821             : { \
     822             :     lcl_SetWrong( *this, nPos, nCnt, bMove ); \
     823             : }
     824             : 
     825        6142 : static void lcl_SetWrong( SwTxtFrm& rFrm, xub_StrLen nPos, long nCnt, bool bMove )
     826             : {
     827        6142 :     if ( !rFrm.IsFollow() )
     828             :     {
     829        5258 :         SwTxtNode* pTxtNode = rFrm.GetTxtNode();
     830        5258 :         IGrammarContact* pGrammarContact = getGrammarContact( *pTxtNode );
     831             :         SwGrammarMarkUp* pWrongGrammar = pGrammarContact ?
     832        5258 :             pGrammarContact->getGrammarCheck( *pTxtNode, false ) :
     833       10516 :             pTxtNode->GetGrammarCheck();
     834        5258 :         bool bGrammarProxy = pWrongGrammar != pTxtNode->GetGrammarCheck();
     835        5258 :         if( bMove )
     836             :         {
     837        4879 :             if( pTxtNode->GetWrong() )
     838        2879 :                 pTxtNode->GetWrong()->Move( nPos, nCnt );
     839        4879 :             if( pWrongGrammar )
     840           0 :                 pWrongGrammar->MoveGrammar( nPos, nCnt );
     841        4879 :             if( bGrammarProxy && pTxtNode->GetGrammarCheck() )
     842           0 :                 pTxtNode->GetGrammarCheck()->MoveGrammar( nPos, nCnt );
     843        4879 :             if( pTxtNode->GetSmartTags() )
     844           0 :                 pTxtNode->GetSmartTags()->Move( nPos, nCnt );
     845             :         }
     846             :         else
     847             :         {
     848         379 :             xub_StrLen nLen = (xub_StrLen)nCnt;
     849         379 :             if( pTxtNode->GetWrong() )
     850         247 :                 pTxtNode->GetWrong()->Invalidate( nPos, nLen );
     851         379 :             if( pWrongGrammar )
     852           0 :                 pWrongGrammar->Invalidate( nPos, nLen );
     853         379 :             if( pTxtNode->GetSmartTags() )
     854           0 :                 pTxtNode->GetSmartTags()->Invalidate( nPos, nLen );
     855             :         }
     856        5258 :         if ( !pTxtNode->GetWrong() && !pTxtNode->IsWrongDirty() )
     857             :         {
     858         350 :             pTxtNode->SetWrong( new SwWrongList( WRONGLIST_SPELL ) );
     859         350 :             pTxtNode->GetWrong()->SetInvalid( nPos, nPos + (sal_uInt16)( nCnt > 0 ? nCnt : 1 ) );
     860             :         }
     861        5258 :         if ( !pTxtNode->GetSmartTags() && !pTxtNode->IsSmartTagDirty() )
     862             :         {
     863             :             // SMARTTAGS
     864           0 :             pTxtNode->SetSmartTags( new SwWrongList( WRONGLIST_SMARTTAG ) );
     865           0 :             pTxtNode->GetSmartTags()->SetInvalid( nPos, nPos + (sal_uInt16)( nCnt > 0 ? nCnt : 1 ) );
     866             :         }
     867        5258 :         pTxtNode->SetWrongDirty( true );
     868        5258 :         pTxtNode->SetGrammarCheckDirty( true );
     869        5258 :         pTxtNode->SetWordCountDirty( true );
     870        5258 :         pTxtNode->SetAutoCompleteWordDirty( true );
     871             :         // SMARTTAGS
     872        5258 :         pTxtNode->SetSmartTagDirty( true );
     873             :     }
     874             : 
     875        6142 :     SwRootFrm *pRootFrm = rFrm.getRootFrm();
     876        6142 :     if (pRootFrm)
     877             :     {
     878        6142 :         pRootFrm->SetNeedGrammarCheck( sal_True );
     879             :     }
     880             : 
     881        6142 :     SwPageFrm *pPage = rFrm.FindPageFrm();
     882        6142 :     if( pPage )
     883             :     {
     884        6142 :         pPage->InvalidateSpelling();
     885        6142 :         pPage->InvalidateAutoCompleteWords();
     886        6142 :         pPage->InvalidateWordCount();
     887        6142 :         pPage->InvalidateSmartTags();
     888             :     }
     889        6142 : }
     890             : 
     891             : //
     892             : // SET_SCRIPT_INVAL( nPos )
     893             : //
     894             : 
     895             : #define SET_SCRIPT_INVAL( nPos )\
     896             :     lcl_SetScriptInval( *this, nPos );
     897             : 
     898        6346 : static void lcl_SetScriptInval( SwTxtFrm& rFrm, xub_StrLen nPos )
     899             : {
     900        6346 :     if( rFrm.GetPara() )
     901        4810 :         rFrm.GetPara()->GetScriptInfo().SetInvalidity( nPos );
     902        6346 : }
     903             : 
     904         884 : static void lcl_ModifyOfst( SwTxtFrm* pFrm, xub_StrLen nPos, xub_StrLen nLen )
     905             : {
     906        3462 :     while( pFrm && pFrm->GetOfst() <= nPos )
     907        1694 :         pFrm = pFrm->GetFollow();
     908        2213 :     while( pFrm )
     909             :     {
     910         445 :         pFrm->ManipOfst( pFrm->GetOfst() + nLen );
     911         445 :         pFrm = pFrm->GetFollow();
     912             :     }
     913         884 : }
     914             : 
     915             : //Related: fdo#56031 filter out attribute changes that don't matter for
     916             : //humans/a11y to stop flooding the destination mortal with useless noise
     917        1502 : static bool isA11yRelevantAttribute(MSHORT nWhich)
     918             : {
     919        1502 :     return nWhich != RES_CHRATR_RSID;
     920             : }
     921             : 
     922             : /*************************************************************************
     923             :  *                      SwTxtFrm::Modify()
     924             :  *************************************************************************/
     925             : 
     926        8268 : void SwTxtFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
     927             : {
     928        8268 :     const MSHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
     929             : 
     930             :     //Wuensche die FrmAttribute betreffen werden von der Basisklasse
     931             :     //verarbeitet.
     932        8268 :     if( IsInRange( aFrmFmtSetRange, nWhich ) || RES_FMT_CHG == nWhich )
     933             :     {
     934          73 :         SwCntntFrm::Modify( pOld, pNew );
     935          73 :         if( nWhich == RES_FMT_CHG && getRootFrm()->GetCurrShell() )
     936             :         {
     937             :             // Collection hat sich geaendert
     938          31 :             Prepare( PREP_CLEAR );
     939          31 :             _InvalidatePrt();
     940          31 :             SET_WRONG( 0, STRING_LEN, false );
     941          31 :             SetDerivedR2L( sal_False );
     942          31 :             CheckDirChange();
     943             :             // OD 09.12.2002 #105576# - Force complete paint due to existing
     944             :             // indents.
     945          31 :             SetCompletePaint();
     946          31 :             InvalidateLineNum();
     947             :         }
     948          73 :         return;
     949             :     }
     950             : 
     951             :     // Im gelockten Zustand werden keine Bestellungen angenommen.
     952        8195 :     if( IsLocked() )
     953           0 :         return;
     954             : 
     955             :     // Dies spart Stack, man muss nur aufpassen,
     956             :     // dass sie Variablen gesetzt werden.
     957             :     xub_StrLen nPos, nLen;
     958        8195 :     bool bSetFldsDirty = false;
     959        8195 :     bool bRecalcFtnFlag = false;
     960             : 
     961        8195 :     switch( nWhich )
     962             :     {
     963             :         case RES_LINENUMBER:
     964             :         {
     965           0 :             InvalidateLineNum();
     966             :         }
     967           0 :         break;
     968             :         case RES_INS_TXT:
     969             :         {
     970        4692 :             nPos = ((SwInsTxt*)pNew)->nPos;
     971        4692 :             nLen = ((SwInsTxt*)pNew)->nLen;
     972        4692 :             if( IsIdxInside( nPos, nLen ) )
     973             :             {
     974        4208 :                 if( !nLen )
     975             :                 {
     976             :                     // 6969: Aktualisierung der NumPortions auch bei leeren Zeilen!
     977           0 :                     if( nPos )
     978           0 :                         InvalidateSize();
     979             :                     else
     980           0 :                         Prepare( PREP_CLEAR );
     981             :                 }
     982             :                 else
     983        4208 :                     _InvalidateRange( SwCharRange( nPos, nLen ), nLen );
     984             :             }
     985        4692 :             SET_WRONG( nPos, nLen, true )
     986        4692 :             SET_SCRIPT_INVAL( nPos )
     987        4692 :             bSetFldsDirty = true;
     988        4692 :             if( HasFollow() )
     989         497 :                 lcl_ModifyOfst( this, nPos, nLen );
     990             :         }
     991        4692 :         break;
     992             :         case RES_DEL_CHR:
     993             :         {
     994         162 :             nPos = ((SwDelChr*)pNew)->nPos;
     995         162 :             InvalidateRange( SwCharRange( nPos, 1 ), -1 );
     996         162 :             SET_WRONG( nPos, -1, true )
     997         162 :             SET_SCRIPT_INVAL( nPos )
     998         162 :             bSetFldsDirty = bRecalcFtnFlag = true;
     999         162 :             if( HasFollow() )
    1000          22 :                 lcl_ModifyOfst( this, nPos, STRING_LEN );
    1001             :         }
    1002         162 :         break;
    1003             :         case RES_DEL_TXT:
    1004             :         {
    1005         909 :             nPos = ((SwDelTxt*)pNew)->nStart;
    1006         909 :             nLen = ((SwDelTxt*)pNew)->nLen;
    1007         909 :             long m = nLen;
    1008         909 :             m *= -1;
    1009         909 :             if( IsIdxInside( nPos, nLen ) )
    1010             :             {
    1011         549 :                 if( !nLen )
    1012           6 :                     InvalidateSize();
    1013             :                 else
    1014         543 :                     InvalidateRange( SwCharRange( nPos, 1 ), m );
    1015             :             }
    1016         909 :             SET_WRONG( nPos, m, true )
    1017         909 :             SET_SCRIPT_INVAL( nPos )
    1018         909 :             bSetFldsDirty = bRecalcFtnFlag = true;
    1019         909 :             if( HasFollow() )
    1020         365 :                 lcl_ModifyOfst( this, nPos, nLen );
    1021             :         }
    1022         909 :         break;
    1023             :         case RES_UPDATE_ATTR:
    1024             :         {
    1025         834 :             nPos = ((SwUpdateAttr*)pNew)->nStart;
    1026         834 :             nLen = ((SwUpdateAttr*)pNew)->nEnd - nPos;
    1027         834 :             if( IsIdxInside( nPos, nLen ) )
    1028             :             {
    1029             :                 // Es muss in jedem Fall neu formatiert werden,
    1030             :                 // auch wenn der invalidierte Bereich null ist.
    1031             :                 // Beispiel: leere Zeile, 14Pt einstellen !
    1032             :                 // if( !nLen ) nLen = 1;
    1033             : 
    1034             :                 // 6680: FtnNummern muessen formatiert werden.
    1035         834 :                 if( !nLen )
    1036         480 :                     nLen = 1;
    1037             : 
    1038         834 :                 _InvalidateRange( SwCharRange( nPos, nLen) );
    1039         834 :                 MSHORT nTmp = ((SwUpdateAttr*)pNew)->nWhichAttr;
    1040             : 
    1041         834 :                 if( ! nTmp || RES_TXTATR_CHARFMT == nTmp || RES_TXTATR_AUTOFMT == nTmp ||
    1042         709 :                     RES_FMT_CHG == nTmp || RES_ATTRSET_CHG == nTmp )
    1043             :                 {
    1044         238 :                     SET_WRONG( nPos, nPos + nLen, false )
    1045         238 :                     SET_SCRIPT_INVAL( nPos )
    1046             :                 }
    1047             :             }
    1048             : 
    1049             :             // #i104008#
    1050         834 :             ViewShell* pViewSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
    1051         834 :             if ( pViewSh  )
    1052             :             {
    1053         834 :                 pViewSh->InvalidateAccessibleParaAttrs( *this );
    1054             :             }
    1055             :         }
    1056         834 :         break;
    1057             :         case RES_OBJECTDYING:
    1058           0 :         break;
    1059             : 
    1060             :         case RES_PARATR_LINESPACING:
    1061             :             {
    1062           0 :                 CalcLineSpace();
    1063           0 :                 InvalidateSize();
    1064           0 :                 _InvalidatePrt();
    1065           0 :                 if( IsInSct() && !GetPrev() )
    1066             :                 {
    1067           0 :                     SwSectionFrm *pSect = FindSctFrm();
    1068           0 :                     if( pSect->ContainsAny() == this )
    1069           0 :                         pSect->InvalidatePrt();
    1070             :                 }
    1071             : 
    1072             :                 // OD 09.01.2004 #i11859# - correction:
    1073             :                 //  (1) Also invalidate next frame on next page/column.
    1074             :                 //  (2) Skip empty sections and hidden paragraphs
    1075             :                 //  Thus, use method <InvalidateNextPrtArea()>
    1076           0 :                 InvalidateNextPrtArea();
    1077             : 
    1078           0 :                 SetCompletePaint();
    1079             :             }
    1080           0 :             break;
    1081             :         case RES_TXTATR_FIELD:
    1082             :         {
    1083          27 :             nPos = *((SwFmtFld*)pNew)->GetTxtFld()->GetStart();
    1084          27 :             if( IsIdxInside( nPos, 1 ) )
    1085             :             {
    1086          27 :                 if( pNew == pOld )
    1087             :                 {
    1088             :                     // Nur repainten
    1089             :                     // opt: invalidate aufs Window ?
    1090           0 :                     InvalidatePage();
    1091           0 :                     SetCompletePaint();
    1092             :                 }
    1093             :                 else
    1094          27 :                     _InvalidateRange( SwCharRange( nPos, 1 ) );
    1095             :             }
    1096          27 :             bSetFldsDirty = true;
    1097             :             // ST2
    1098          27 :             if ( SwSmartTagMgr::Get().IsSmartTagsEnabled() )
    1099           0 :                 SET_WRONG( nPos, nPos + 1, false )
    1100             :         }
    1101          27 :         break;
    1102             :         case RES_TXTATR_FTN :
    1103             :         {
    1104          63 :             nPos = *((SwFmtFtn*)pNew)->GetTxtFtn()->GetStart();
    1105          63 :             if( IsInFtn() || IsIdxInside( nPos, 1 ) )
    1106          63 :                 Prepare( PREP_FTN, ((SwFmtFtn*)pNew)->GetTxtFtn() );
    1107          63 :             break;
    1108             :         }
    1109             : 
    1110             :         case RES_ATTRSET_CHG:
    1111             :         {
    1112        1502 :             InvalidateLineNum();
    1113             : 
    1114        1502 :             SwAttrSet& rNewSet = *((SwAttrSetChg*)pNew)->GetChgSet();
    1115             :             const SfxPoolItem* pItem;
    1116        1502 :             int nClear = 0;
    1117        1502 :             MSHORT nCount = rNewSet.Count();
    1118             : 
    1119        1502 :             if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FTN,
    1120        1502 :                 sal_False, &pItem ))
    1121             :             {
    1122           0 :                 nPos = *((SwFmtFtn*)pItem)->GetTxtFtn()->GetStart();
    1123           0 :                 if( IsIdxInside( nPos, 1 ) )
    1124           0 :                     Prepare( PREP_FTN, pNew );
    1125           0 :                 nClear = 0x01;
    1126           0 :                 --nCount;
    1127             :             }
    1128             : 
    1129        1502 :             if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FIELD,
    1130        1502 :                 sal_False, &pItem ))
    1131             :             {
    1132           0 :                 nPos = *((SwFmtFld*)pItem)->GetTxtFld()->GetStart();
    1133           0 :                 if( IsIdxInside( nPos, 1 ) )
    1134             :                 {
    1135             :                     const SfxPoolItem& rOldItem = ((SwAttrSetChg*)pOld)->
    1136           0 :                                         GetChgSet()->Get( RES_TXTATR_FIELD );
    1137           0 :                     if( pItem == &rOldItem )
    1138             :                     {
    1139             :                         // Nur repainten
    1140             :                         // opt: invalidate aufs Window ?
    1141           0 :                         InvalidatePage();
    1142           0 :                         SetCompletePaint();
    1143             :                     }
    1144             :                     else
    1145           0 :                         _InvalidateRange( SwCharRange( nPos, 1 ) );
    1146             :                 }
    1147           0 :                 nClear |= 0x02;
    1148           0 :                 --nCount;
    1149             :             }
    1150             :             bool bLineSpace = SFX_ITEM_SET == rNewSet.GetItemState(
    1151        1502 :                                             RES_PARATR_LINESPACING, sal_False ),
    1152             :                      bRegister  = SFX_ITEM_SET == rNewSet.GetItemState(
    1153        1502 :                                             RES_PARATR_REGISTER, sal_False );
    1154        1502 :             if ( bLineSpace || bRegister )
    1155             :             {
    1156           0 :                 Prepare( bRegister ? PREP_REGISTER : PREP_ADJUST_FRM );
    1157           0 :                 CalcLineSpace();
    1158           0 :                 InvalidateSize();
    1159           0 :                 _InvalidatePrt();
    1160             : 
    1161             :                 // OD 09.01.2004 #i11859# - correction:
    1162             :                 //  (1) Also invalidate next frame on next page/column.
    1163             :                 //  (2) Skip empty sections and hidden paragraphs
    1164             :                 //  Thus, use method <InvalidateNextPrtArea()>
    1165           0 :                 InvalidateNextPrtArea();
    1166             : 
    1167           0 :                 SetCompletePaint();
    1168           0 :                 nClear |= 0x04;
    1169           0 :                 if ( bLineSpace )
    1170             :                 {
    1171           0 :                     --nCount;
    1172           0 :                     if( IsInSct() && !GetPrev() )
    1173             :                     {
    1174           0 :                         SwSectionFrm *pSect = FindSctFrm();
    1175           0 :                         if( pSect->ContainsAny() == this )
    1176           0 :                             pSect->InvalidatePrt();
    1177             :                     }
    1178             :                 }
    1179           0 :                 if ( bRegister )
    1180           0 :                     --nCount;
    1181             :             }
    1182        1502 :             if ( SFX_ITEM_SET == rNewSet.GetItemState( RES_PARATR_SPLIT,
    1183        1502 :                                                        sal_False ))
    1184             :             {
    1185           0 :                 if ( GetPrev() )
    1186           0 :                     CheckKeep();
    1187           0 :                 Prepare( PREP_CLEAR );
    1188           0 :                 InvalidateSize();
    1189           0 :                 nClear |= 0x08;
    1190           0 :                 --nCount;
    1191             :             }
    1192             : 
    1193        3004 :             if( SFX_ITEM_SET == rNewSet.GetItemState( RES_BACKGROUND, sal_False)
    1194        1502 :                 && !IsFollow() && GetDrawObjs() )
    1195             :             {
    1196           0 :                 SwSortedObjs *pObjs = GetDrawObjs();
    1197           0 :                 for ( int i = 0; GetDrawObjs() && i < int(pObjs->Count()); ++i )
    1198             :                 {
    1199           0 :                     SwAnchoredObject* pAnchoredObj = (*pObjs)[MSHORT(i)];
    1200           0 :                     if ( pAnchoredObj->ISA(SwFlyFrm) )
    1201             :                     {
    1202           0 :                         SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
    1203           0 :                         if( !pFly->IsFlyInCntFrm() )
    1204             :                         {
    1205             :                             const SvxBrushItem &rBack =
    1206           0 :                                 pFly->GetAttrSet()->GetBackground();
    1207             :                             // OD 20.08.2002 #99657# #GetTransChg#
    1208             :                             //     following condition determines, if the fly frame
    1209             :                             //     "inherites" the background color of text frame.
    1210             :                             //     This is the case, if fly frame background
    1211             :                             //     color is "no fill"/"auto fill" and if the fly frame
    1212             :                             //     has no background graphic.
    1213             :                             //     Thus, check complete fly frame background
    1214             :                             //     color and *not* only its transparency value
    1215           0 :                             if ( (rBack.GetColor() == COL_TRANSPARENT)  &&
    1216           0 :                                 rBack.GetGraphicPos() == GPOS_NONE )
    1217             :                             {
    1218           0 :                                 pFly->SetCompletePaint();
    1219           0 :                                 pFly->InvalidatePage();
    1220             :                             }
    1221             :                         }
    1222             :                     }
    1223             :                 }
    1224             :             }
    1225             : 
    1226        1502 :             if ( SFX_ITEM_SET ==
    1227        1502 :                  rNewSet.GetItemState( RES_TXTATR_CHARFMT, sal_False ) )
    1228             :             {
    1229           0 :                 SET_WRONG( 0, STRING_LEN, false )
    1230           0 :                 SET_SCRIPT_INVAL( 0 )
    1231             :             }
    1232        1502 :             else if ( SFX_ITEM_SET ==
    1233        2940 :                       rNewSet.GetItemState( RES_CHRATR_LANGUAGE, sal_False ) ||
    1234             :                       SFX_ITEM_SET ==
    1235        2917 :                       rNewSet.GetItemState( RES_CHRATR_CJK_LANGUAGE, sal_False ) ||
    1236             :                       SFX_ITEM_SET ==
    1237        1415 :                       rNewSet.GetItemState( RES_CHRATR_CTL_LANGUAGE, sal_False ) )
    1238         110 :                 SET_WRONG( 0, STRING_LEN, false )
    1239        1392 :             else if ( SFX_ITEM_SET ==
    1240        2669 :                       rNewSet.GetItemState( RES_CHRATR_FONT, sal_False ) ||
    1241             :                       SFX_ITEM_SET ==
    1242        2554 :                       rNewSet.GetItemState( RES_CHRATR_CJK_FONT, sal_False ) ||
    1243             :                       SFX_ITEM_SET ==
    1244        1162 :                       rNewSet.GetItemState( RES_CHRATR_CTL_FONT, sal_False ) )
    1245         345 :                 SET_SCRIPT_INVAL( 0 )
    1246        1047 :             else if ( SFX_ITEM_SET ==
    1247        1047 :                       rNewSet.GetItemState( RES_FRAMEDIR, sal_False ) )
    1248             :             {
    1249          25 :                 SetDerivedR2L( sal_False );
    1250          25 :                 CheckDirChange();
    1251             :                 // OD 09.12.2002 #105576# - Force complete paint due to existing
    1252             :                 // indents.
    1253          25 :                 SetCompletePaint();
    1254             :             }
    1255             : 
    1256             : 
    1257        1502 :             if( nCount )
    1258             :             {
    1259        1502 :                 if( getRootFrm()->GetCurrShell() )
    1260             :                 {
    1261        1502 :                     Prepare( PREP_CLEAR );
    1262        1502 :                     _InvalidatePrt();
    1263             :                 }
    1264             : 
    1265        1502 :                 if( nClear )
    1266             :                 {
    1267           0 :                     SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
    1268           0 :                     SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
    1269             : 
    1270           0 :                     if( 0x01 & nClear )
    1271             :                     {
    1272           0 :                         aOldSet.ClearItem( RES_TXTATR_FTN );
    1273           0 :                         aNewSet.ClearItem( RES_TXTATR_FTN );
    1274             :                     }
    1275           0 :                     if( 0x02 & nClear )
    1276             :                     {
    1277           0 :                         aOldSet.ClearItem( RES_TXTATR_FIELD );
    1278           0 :                         aNewSet.ClearItem( RES_TXTATR_FIELD );
    1279             :                     }
    1280           0 :                     if ( 0x04 & nClear )
    1281             :                     {
    1282           0 :                         if ( bLineSpace )
    1283             :                         {
    1284           0 :                             aOldSet.ClearItem( RES_PARATR_LINESPACING );
    1285           0 :                             aNewSet.ClearItem( RES_PARATR_LINESPACING );
    1286             :                         }
    1287           0 :                         if ( bRegister )
    1288             :                         {
    1289           0 :                             aOldSet.ClearItem( RES_PARATR_REGISTER );
    1290           0 :                             aNewSet.ClearItem( RES_PARATR_REGISTER );
    1291             :                         }
    1292             :                     }
    1293           0 :                     if ( 0x08 & nClear )
    1294             :                     {
    1295           0 :                         aOldSet.ClearItem( RES_PARATR_SPLIT );
    1296           0 :                         aNewSet.ClearItem( RES_PARATR_SPLIT );
    1297             :                     }
    1298           0 :                     SwCntntFrm::Modify( &aOldSet, &aNewSet );
    1299             :                 }
    1300             :                 else
    1301        1502 :                     SwCntntFrm::Modify( pOld, pNew );
    1302             :             }
    1303             : 
    1304        1502 :             if (isA11yRelevantAttribute(nWhich))
    1305             :             {
    1306             :                 // #i88069#
    1307        1502 :                 ViewShell* pViewSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
    1308        1502 :                 if ( pViewSh  )
    1309             :                 {
    1310        1502 :                     pViewSh->InvalidateAccessibleParaAttrs( *this );
    1311             :                 }
    1312             :             }
    1313             :         }
    1314        1502 :         break;
    1315             : 
    1316             :         // 6870: SwDocPosUpdate auswerten.
    1317             :         case RES_DOCPOS_UPDATE:
    1318             :         {
    1319           6 :             if( pOld && pNew )
    1320             :             {
    1321           6 :                 const SwDocPosUpdate *pDocPos = (const SwDocPosUpdate*)pOld;
    1322           6 :                 if( pDocPos->nDocPos <= maFrm.Top() )
    1323             :                 {
    1324           5 :                     const SwFmtFld *pFld = (const SwFmtFld *)pNew;
    1325             :                     InvalidateRange(
    1326           5 :                         SwCharRange( *pFld->GetTxtFld()->GetStart(), 1 ) );
    1327             :                 }
    1328             :             }
    1329           6 :             break;
    1330             :         }
    1331             :         case RES_PARATR_SPLIT:
    1332           0 :             if ( GetPrev() )
    1333           0 :                 CheckKeep();
    1334           0 :             Prepare( PREP_CLEAR );
    1335           0 :             bSetFldsDirty = true;
    1336           0 :             break;
    1337             :         case RES_FRAMEDIR :
    1338           0 :             SetDerivedR2L( sal_False );
    1339           0 :             CheckDirChange();
    1340           0 :             break;
    1341             :         default:
    1342             :         {
    1343           0 :             Prepare( PREP_CLEAR );
    1344           0 :             _InvalidatePrt();
    1345           0 :             if ( !nWhich )
    1346             :             {
    1347             :                 //Wird z.B. bei HiddenPara mit 0 gerufen.
    1348             :                 SwFrm *pNxt;
    1349           0 :                 if ( 0 != (pNxt = FindNext()) )
    1350           0 :                     pNxt->InvalidatePrt();
    1351             :             }
    1352             :         }
    1353             :     } // switch
    1354             : 
    1355        8195 :     if( bSetFldsDirty )
    1356        5790 :         GetNode()->getIDocumentFieldsAccess()->SetFieldsDirty( true, GetNode(), 1 );
    1357             : 
    1358        8195 :     if ( bRecalcFtnFlag )
    1359        1071 :         CalcFtnFlag();
    1360             : }
    1361             : 
    1362           0 : bool SwTxtFrm::GetInfo( SfxPoolItem &rHnt ) const
    1363             : {
    1364           0 :     if ( RES_VIRTPAGENUM_INFO == rHnt.Which() && IsInDocBody() && ! IsFollow() )
    1365             :     {
    1366           0 :         SwVirtPageNumInfo &rInfo = (SwVirtPageNumInfo&)rHnt;
    1367           0 :         const SwPageFrm *pPage = FindPageFrm();
    1368           0 :         if ( pPage )
    1369             :         {
    1370           0 :             if ( pPage == rInfo.GetOrigPage() && !GetPrev() )
    1371             :             {
    1372             :                 //Das sollte er sein (kann allenfalls temporaer anders sein,
    1373             :                 //                    sollte uns das beunruhigen?)
    1374           0 :                 rInfo.SetInfo( pPage, this );
    1375           0 :                 return false;
    1376             :             }
    1377           0 :             if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() &&
    1378           0 :                  (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum()))
    1379             :             {
    1380             :                 //Das koennte er sein.
    1381           0 :                 rInfo.SetInfo( pPage, this );
    1382             :             }
    1383             :         }
    1384             :     }
    1385           0 :     return true;
    1386             : }
    1387             : 
    1388             : /*************************************************************************
    1389             :  *                      SwTxtFrm::PrepWidows()
    1390             :  *************************************************************************/
    1391             : 
    1392           0 : void SwTxtFrm::PrepWidows( const MSHORT nNeed, sal_Bool bNotify )
    1393             : {
    1394             :     OSL_ENSURE(GetFollow() && nNeed, "+SwTxtFrm::Prepare: lost all friends");
    1395             : 
    1396           0 :     SwParaPortion *pPara = GetPara();
    1397           0 :     if ( !pPara )
    1398           0 :         return;
    1399           0 :     pPara->SetPrepWidows( sal_True );
    1400             : 
    1401           0 :     MSHORT nHave = nNeed;
    1402             : 
    1403             :     // Wir geben ein paar Zeilen ab und schrumpfen im CalcPreps()
    1404           0 :     SWAP_IF_NOT_SWAPPED( this )
    1405             : 
    1406           0 :     SwTxtSizeInfo aInf( this );
    1407           0 :     SwTxtMargin aLine( this, &aInf );
    1408           0 :     aLine.Bottom();
    1409           0 :     xub_StrLen nTmpLen = aLine.GetCurr()->GetLen();
    1410           0 :     while( nHave && aLine.PrevLine() )
    1411             :     {
    1412           0 :         if( nTmpLen )
    1413           0 :             --nHave;
    1414           0 :         nTmpLen = aLine.GetCurr()->GetLen();
    1415             :     }
    1416             :     // In dieser Ecke tummelten sich einige Bugs: 7513, 7606.
    1417             :     // Wenn feststeht, dass Zeilen abgegeben werden koennen,
    1418             :     // muss der Master darueber hinaus die Widow-Regel ueberpruefen.
    1419           0 :     if( !nHave )
    1420             :     {
    1421             :         bool bSplit;
    1422           0 :         if( !IsFollow() )   //Nur ein Master entscheidet ueber Orphans
    1423             :         {
    1424           0 :             const WidowsAndOrphans aWidOrp( this );
    1425           0 :             bSplit = ( aLine.GetLineNr() >= aWidOrp.GetOrphansLines() &&
    1426           0 :                        aLine.GetLineNr() >= aLine.GetDropLines() );
    1427             :         }
    1428             :         else
    1429           0 :             bSplit = true;
    1430             : 
    1431           0 :         if( bSplit )
    1432             :         {
    1433           0 :             GetFollow()->SetOfst( aLine.GetEnd() );
    1434           0 :             aLine.TruncLines( true );
    1435           0 :             if( pPara->IsFollowField() )
    1436           0 :                 GetFollow()->SetFieldFollow( sal_True );
    1437             :         }
    1438             :     }
    1439           0 :     if ( bNotify )
    1440             :     {
    1441           0 :         _InvalidateSize();
    1442           0 :         InvalidatePage();
    1443             :     }
    1444             : 
    1445           0 :     UNDO_SWAP( this )
    1446             : }
    1447             : 
    1448             : /*************************************************************************
    1449             :  *                      SwTxtFrm::Prepare
    1450             :  *************************************************************************/
    1451             : 
    1452           9 : static bool lcl_ErgoVadis( SwTxtFrm* pFrm, xub_StrLen &rPos, const PrepareHint ePrep )
    1453             : {
    1454           9 :     const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo();
    1455           9 :     if( ePrep == PREP_ERGOSUM )
    1456             :     {
    1457           1 :         if( !rFtnInfo.aErgoSum.Len() )
    1458           1 :             return false;;
    1459           0 :         rPos = pFrm->GetOfst();
    1460             :     }
    1461             :     else
    1462             :     {
    1463           8 :         if( !rFtnInfo.aQuoVadis.Len() )
    1464           8 :             return false;
    1465           0 :         if( pFrm->HasFollow() )
    1466           0 :             rPos = pFrm->GetFollow()->GetOfst();
    1467             :         else
    1468           0 :             rPos = pFrm->GetTxt().Len();
    1469           0 :         if( rPos )
    1470           0 :             --rPos; // unser letztes Zeichen
    1471             :     }
    1472           0 :     return true;
    1473             : }
    1474             : 
    1475       20916 : void SwTxtFrm::Prepare( const PrepareHint ePrep, const void* pVoid,
    1476             :                         sal_Bool bNotify )
    1477             : {
    1478       20916 :     SwFrmSwapper aSwapper( this, sal_False );
    1479             : 
    1480             : #if OSL_DEBUG_LEVEL > 1
    1481             :     const SwTwips nDbgY = Frm().Top();
    1482             :     (void)nDbgY;
    1483             : #endif
    1484             : 
    1485       20916 :     if ( IsEmpty() )
    1486             :     {
    1487        2465 :         switch ( ePrep )
    1488             :         {
    1489             :             case PREP_BOSS_CHGD:
    1490          49 :                 SetInvalidVert( sal_True );  // Test
    1491             :             case PREP_WIDOWS_ORPHANS:
    1492             :             case PREP_WIDOWS:
    1493          89 :             case PREP_FTN_GONE :    return;
    1494             : 
    1495             :             case PREP_POS_CHGD :
    1496             :             {
    1497             :                 // Auch in (spaltigen) Bereichen ist ein InvalidateSize notwendig,
    1498             :                 // damit formatiert wird und ggf. das bUndersized gesetzt wird.
    1499         777 :                 if( IsInFly() || IsInSct() )
    1500             :                 {
    1501          59 :                     SwTwips nTmpBottom = GetUpper()->Frm().Top() +
    1502          59 :                         GetUpper()->Prt().Bottom();
    1503          59 :                     if( nTmpBottom < Frm().Bottom() )
    1504          82 :                         break;
    1505             :                 }
    1506             :                 // Gibt es ueberhaupt Flys auf der Seite ?
    1507         739 :                 SwTxtFly aTxtFly( this );
    1508         739 :                 if( aTxtFly.IsOn() )
    1509             :                 {
    1510             :                     // Ueberlappt irgendein Fly ?
    1511          92 :                     aTxtFly.Relax();
    1512          92 :                     if ( aTxtFly.IsOn() || IsUndersized() )
    1513           5 :                         break;
    1514             :                 }
    1515         734 :                 if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue())
    1516           0 :                     break;
    1517             : 
    1518         734 :                 GETGRID( FindPageFrm() )
    1519         734 :                 if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() )
    1520           0 :                     break;
    1521             : 
    1522             :                 // #i28701# - consider anchored objects
    1523         734 :                 if ( GetDrawObjs() )
    1524           1 :                     break;
    1525             : 
    1526         733 :                 return;
    1527             :             }
    1528             :             default:
    1529        1599 :                 break;
    1530             :         }
    1531             :     }
    1532             : 
    1533       20094 :     if( !HasPara() && PREP_MUST_FIT != ePrep )
    1534             :     {
    1535       16645 :         SetInvalidVert( sal_True );  // Test
    1536             :         OSL_ENSURE( !IsLocked(), "SwTxtFrm::Prepare: three of a perfect pair" );
    1537       16645 :         if ( bNotify )
    1538       12603 :             InvalidateSize();
    1539             :         else
    1540        4042 :             _InvalidateSize();
    1541       16645 :         return;
    1542             :     }
    1543             : 
    1544             :     //Objekt mit Locking aus dem Cache holen.
    1545        3449 :     SwTxtLineAccess aAccess( this );
    1546        3449 :     SwParaPortion *pPara = aAccess.GetPara();
    1547             : 
    1548        3449 :     switch( ePrep )
    1549             :     {
    1550           0 :         case PREP_MOVEFTN :     Frm().Height(0);
    1551           0 :                                 Prt().Height(0);
    1552           0 :                                 _InvalidatePrt();
    1553           0 :                                 _InvalidateSize();
    1554             :                                 // KEIN break
    1555         354 :         case PREP_ADJUST_FRM :  pPara->SetPrepAdjust( sal_True );
    1556         706 :                                 if( IsFtnNumFrm() != pPara->IsFtnNum() ||
    1557         352 :                                     IsUndersized() )
    1558             :                                 {
    1559          97 :                                     InvalidateRange( SwCharRange( 0, 1 ), 1);
    1560          97 :                                     if( GetOfst() && !IsFollow() )
    1561           0 :                                         _SetOfst( 0 );
    1562             :                                 }
    1563         354 :                                 break;
    1564          14 :         case PREP_MUST_FIT :        pPara->SetPrepMustFit( sal_True );
    1565             :             /* no break here */
    1566         343 :         case PREP_WIDOWS_ORPHANS :  pPara->SetPrepAdjust( sal_True );
    1567         343 :                                     break;
    1568             : 
    1569             :         case PREP_WIDOWS :
    1570             :             // MustFit ist staerker als alles anderes
    1571           0 :             if( pPara->IsPrepMustFit() )
    1572           0 :                 return;
    1573             :             // Siehe Kommentar in WidowsAndOrphans::FindOrphans und CalcPreps()
    1574           0 :             PrepWidows( *(const MSHORT *)pVoid, bNotify );
    1575           0 :             break;
    1576             : 
    1577             :         case PREP_FTN :
    1578             :         {
    1579          81 :             SwTxtFtn *pFtn = (SwTxtFtn *)pVoid;
    1580          81 :             if( IsInFtn() )
    1581             :             {
    1582             :                 // Bin ich der erste TxtFrm einer Fussnote ?
    1583          28 :                 if( !GetPrev() )
    1584             :                     // Wir sind also ein TxtFrm der Fussnote, die
    1585             :                     // die Fussnotenzahl zur Anzeige bringen muss.
    1586             :                     // Oder den ErgoSum-Text...
    1587          26 :                     InvalidateRange( SwCharRange( 0, 1 ), 1);
    1588             : 
    1589          28 :                 if( !GetNext() )
    1590             :                 {
    1591             :                     // Wir sind der letzte Ftn, jetzt muessten die
    1592             :                     // QuoVadis-Texte geupdated werden.
    1593          27 :                     const SwFtnInfo &rFtnInfo = GetNode()->GetDoc()->GetFtnInfo();
    1594          27 :                     if( !pPara->UpdateQuoVadis( rFtnInfo.aQuoVadis ) )
    1595             :                     {
    1596          27 :                         xub_StrLen nPos = pPara->GetParLen();
    1597          27 :                         if( nPos )
    1598           6 :                             --nPos;
    1599          27 :                         InvalidateRange( SwCharRange( nPos, 1 ), 1);
    1600             :                     }
    1601             :                 }
    1602             :             }
    1603             :             else
    1604             :             {
    1605             :                 // Wir sind also der TxtFrm _mit_ der Fussnote
    1606          53 :                 const xub_StrLen nPos = *pFtn->GetStart();
    1607          53 :                 InvalidateRange( SwCharRange( nPos, 1 ), 1);
    1608             :             }
    1609          81 :             break;
    1610             :         }
    1611             :         case PREP_BOSS_CHGD :
    1612             :         {
    1613             :     // Test
    1614             :             {
    1615          29 :                 SetInvalidVert( sal_False );
    1616          29 :                 sal_Bool bOld = IsVertical();
    1617          29 :                 SetInvalidVert( sal_True );
    1618          29 :                 if( bOld != IsVertical() )
    1619           0 :                     InvalidateRange( SwCharRange( GetOfst(), STRING_LEN ) );
    1620             :             }
    1621             : 
    1622          29 :             if( HasFollow() )
    1623             :             {
    1624           3 :                 xub_StrLen nNxtOfst = GetFollow()->GetOfst();
    1625           3 :                 if( nNxtOfst )
    1626           3 :                     --nNxtOfst;
    1627           3 :                 InvalidateRange( SwCharRange( nNxtOfst, 1 ), 1);
    1628             :             }
    1629          29 :             if( IsInFtn() )
    1630             :             {
    1631             :                 xub_StrLen nPos;
    1632           0 :                 if( lcl_ErgoVadis( this, nPos, PREP_QUOVADIS ) )
    1633           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1634           0 :                 if( lcl_ErgoVadis( this, nPos, PREP_ERGOSUM ) )
    1635           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1636             :             }
    1637             :             // 4739: Wenn wir ein Seitennummernfeld besitzen, muessen wir
    1638             :             // die Stellen invalidieren.
    1639          29 :             SwpHints *pHints = GetTxtNode()->GetpSwpHints();
    1640          29 :             if( pHints )
    1641             :             {
    1642           0 :                 const sal_uInt16 nSize = pHints->Count();
    1643           0 :                 const xub_StrLen nEnd = GetFollow() ?
    1644           0 :                                     GetFollow()->GetOfst() : STRING_LEN;
    1645           0 :                 for ( sal_uInt16 i = 0; i < nSize; ++i )
    1646             :                 {
    1647           0 :                     const SwTxtAttr *pHt = (*pHints)[i];
    1648           0 :                     const xub_StrLen nStart = *pHt->GetStart();
    1649           0 :                     if( nStart >= GetOfst() )
    1650             :                     {
    1651           0 :                         if( nStart >= nEnd )
    1652           0 :                             i = nSize;          // fuehrt das Ende herbei
    1653             :                         else
    1654             :                         {
    1655             :                 // 4029: wenn wir zurueckfliessen und eine Ftn besitzen, so
    1656             :                 // fliesst die Ftn in jedem Fall auch mit. Damit sie nicht im
    1657             :                 // Weg steht, schicken wir uns ein ADJUST_FRM.
    1658             :                 // pVoid != 0 bedeutet MoveBwd()
    1659           0 :                             const MSHORT nWhich = pHt->Which();
    1660           0 :                             if( RES_TXTATR_FIELD == nWhich ||
    1661           0 :                                 (HasFtn() && pVoid && RES_TXTATR_FTN == nWhich))
    1662           0 :                             InvalidateRange( SwCharRange( nStart, 1 ), 1 );
    1663             :                         }
    1664             :                     }
    1665             :                 }
    1666             :             }
    1667             :             // A new boss, a new chance for growing
    1668          29 :             if( IsUndersized() )
    1669             :             {
    1670          13 :                 _InvalidateSize();
    1671          13 :                 InvalidateRange( SwCharRange( GetOfst(), 1 ), 1);
    1672             :             }
    1673          29 :             break;
    1674             :         }
    1675             : 
    1676             :         case PREP_POS_CHGD :
    1677             :         {
    1678         926 :             if ( GetValidPrtAreaFlag() )
    1679             :             {
    1680         870 :                 GETGRID( FindPageFrm() )
    1681         870 :                 if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() )
    1682           0 :                     InvalidatePrt();
    1683             :             }
    1684             : 
    1685             :             // Falls wir mit niemandem ueberlappen:
    1686             :             // Ueberlappte irgendein Fly _vor_ der Positionsaenderung ?
    1687         926 :             sal_Bool bFormat = pPara->HasFly();
    1688         926 :             if( !bFormat )
    1689             :             {
    1690         926 :                 if( IsInFly() )
    1691             :                 {
    1692          42 :                     SwTwips nTmpBottom = GetUpper()->Frm().Top() +
    1693          42 :                         GetUpper()->Prt().Bottom();
    1694          42 :                     if( nTmpBottom < Frm().Bottom() )
    1695           0 :                         bFormat = sal_True;
    1696             :                 }
    1697         926 :                 if( !bFormat )
    1698             :                 {
    1699         926 :                     if ( GetDrawObjs() )
    1700             :                     {
    1701           4 :                         const sal_uInt32 nCnt = GetDrawObjs()->Count();
    1702           8 :                         for ( MSHORT i = 0; i < nCnt; ++i )
    1703             :                         {
    1704           4 :                             SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
    1705             :                             // #i28701# - consider all
    1706             :                             // to-character anchored objects
    1707           4 :                             if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
    1708             :                                     == FLY_AT_CHAR )
    1709             :                             {
    1710           0 :                                 bFormat = sal_True;
    1711           0 :                                 break;
    1712             :                             }
    1713             :                         }
    1714             :                     }
    1715         926 :                     if( !bFormat )
    1716             :                     {
    1717             :                         // Gibt es ueberhaupt Flys auf der Seite ?
    1718         926 :                         SwTxtFly aTxtFly( this );
    1719         926 :                         if( aTxtFly.IsOn() )
    1720             :                         {
    1721             :                             // Ueberlappt irgendein Fly ?
    1722         157 :                             aTxtFly.Relax();
    1723         157 :                             bFormat = aTxtFly.IsOn() || IsUndersized();
    1724         926 :                         }
    1725             :                     }
    1726             :                 }
    1727             :             }
    1728             : 
    1729         926 :             if( bFormat )
    1730             :             {
    1731           9 :                 if( !IsLocked() )
    1732             :                 {
    1733           9 :                     if( pPara->GetRepaint()->HasArea() )
    1734           9 :                         SetCompletePaint();
    1735           9 :                     Init();
    1736           9 :                     pPara = 0;
    1737           9 :                     _InvalidateSize();
    1738             :                 }
    1739             :             }
    1740             :             else
    1741             :             {
    1742         917 :                 if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
    1743           0 :                     Prepare( PREP_REGISTER, 0, bNotify );
    1744             :                 // Durch Positionsverschiebungen mit Ftns muessen die
    1745             :                 // Frames neu adjustiert werden.
    1746         917 :                 else if( HasFtn() )
    1747             :                 {
    1748           0 :                     Prepare( PREP_ADJUST_FRM, 0, bNotify );
    1749           0 :                     _InvalidateSize();
    1750             :                 }
    1751             :                 else
    1752         917 :                     return;     // damit kein SetPrep() erfolgt.
    1753             :             }
    1754           9 :             break;
    1755             :         }
    1756             :         case PREP_REGISTER:
    1757           0 :             if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
    1758             :             {
    1759           0 :                 pPara->SetPrepAdjust( sal_True );
    1760           0 :                 CalcLineSpace();
    1761           0 :                 InvalidateSize();
    1762           0 :                 _InvalidatePrt();
    1763             :                 SwFrm* pNxt;
    1764           0 :                 if ( 0 != ( pNxt = GetIndNext() ) )
    1765             :                 {
    1766           0 :                     pNxt->_InvalidatePrt();
    1767           0 :                     if ( pNxt->IsLayoutFrm() )
    1768           0 :                         pNxt->InvalidatePage();
    1769             :                 }
    1770           0 :                 SetCompletePaint();
    1771             :             }
    1772           0 :             break;
    1773             :         case PREP_FTN_GONE :
    1774             :             {
    1775             :                 // Wenn ein Follow uns ruft, weil eine Fussnote geloescht wird, muss unsere
    1776             :                 // letzte Zeile formatiert werden, damit ggf. die erste Zeile des Follows
    1777             :                 // hochrutschen kann, die extra auf die naechste Seite gerutscht war, um mit
    1778             :                 // der Fussnote zusammen zu sein, insbesondere bei spaltigen Bereichen.
    1779             :                 OSL_ENSURE( GetFollow(), "PREP_FTN_GONE darf nur vom Follow gerufen werden" );
    1780           0 :                 xub_StrLen nPos = GetFollow()->GetOfst();
    1781           0 :                 if( IsFollow() && GetOfst() == nPos )       // falls wir gar keine Textmasse besitzen,
    1782           0 :                     FindMaster()->Prepare( PREP_FTN_GONE ); // rufen wir das Prepare unseres Masters
    1783           0 :                 if( nPos )
    1784           0 :                     --nPos; // das Zeichen vor unserem Follow
    1785           0 :                 InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1786           0 :                 return;
    1787             :             }
    1788             :         case PREP_ERGOSUM:
    1789             :         case PREP_QUOVADIS:
    1790             :             {
    1791             :                 xub_StrLen nPos;
    1792           9 :                 if( lcl_ErgoVadis( this, nPos, ePrep ) )
    1793           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1794             :             }
    1795           9 :             break;
    1796             :         case PREP_FLY_ATTR_CHG:
    1797             :         {
    1798          41 :             if( pVoid )
    1799             :             {
    1800          35 :                 xub_StrLen nWhere = CalcFlyPos( (SwFrmFmt*)pVoid );
    1801             :                 OSL_ENSURE( STRING_LEN != nWhere, "Prepare: Why me?" );
    1802          35 :                 InvalidateRange( SwCharRange( nWhere, 1 ) );
    1803          35 :                 return;
    1804             :             }
    1805             :             // else ... Laufe in den Default-Switch
    1806             :         }
    1807             :         case PREP_CLEAR:
    1808             :         default:
    1809             :         {
    1810        1672 :             if( IsLocked() )
    1811             :             {
    1812         505 :                 if( PREP_FLY_ARRIVE == ePrep || PREP_FLY_LEAVE == ePrep )
    1813             :                 {
    1814         468 :                     xub_StrLen nLen = ( GetFollow() ? GetFollow()->GetOfst() :
    1815         468 :                                       STRING_LEN ) - GetOfst();
    1816         468 :                     InvalidateRange( SwCharRange( GetOfst(), nLen ), 0 );
    1817             :                 }
    1818             :             }
    1819             :             else
    1820             :             {
    1821        1167 :                 if( pPara->GetRepaint()->HasArea() )
    1822         525 :                     SetCompletePaint();
    1823        1167 :                 Init();
    1824        1167 :                 pPara = 0;
    1825        1167 :                 if( GetOfst() && !IsFollow() )
    1826           0 :                     _SetOfst( 0 );
    1827        1167 :                 if ( bNotify )
    1828        1162 :                     InvalidateSize();
    1829             :                 else
    1830           5 :                     _InvalidateSize();
    1831             :             }
    1832        1672 :             return;     // damit kein SetPrep() erfolgt.
    1833             :         }
    1834             :     }
    1835         825 :     if( pPara )
    1836         816 :         pPara->SetPrep( sal_True );
    1837             : }
    1838             : 
    1839             : /* --------------------------------------------------
    1840             :  * Kleine Hilfsklasse mit folgender Funktion:
    1841             :  * Sie soll eine Probeformatierung vorbereiten.
    1842             :  * Der Frame wird in Groesse und Position angepasst, sein SwParaPortion zur Seite
    1843             :  * gestellt und eine neue erzeugt, dazu wird formatiert mit gesetztem bTestFormat.
    1844             :  * Im Dtor wird der TxtFrm wieder in seinen alten Zustand zurueckversetzt.
    1845             :  *
    1846             :  * --------------------------------------------------*/
    1847             : 
    1848             : class SwTestFormat
    1849             : {
    1850             :     SwTxtFrm *pFrm;
    1851             :     SwParaPortion *pOldPara;
    1852             :     SwRect aOldFrm, aOldPrt;
    1853             : public:
    1854             :     SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPrv, SwTwips nMaxHeight );
    1855             :     ~SwTestFormat();
    1856             : };
    1857             : 
    1858           0 : SwTestFormat::SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPre, SwTwips nMaxHeight )
    1859           0 :     : pFrm( pTxtFrm )
    1860             : {
    1861           0 :     aOldFrm = pFrm->Frm();
    1862           0 :     aOldPrt = pFrm->Prt();
    1863             : 
    1864           0 :     SWRECTFN( pFrm )
    1865           0 :     SwTwips nLower = (pFrm->*fnRect->fnGetBottomMargin)();
    1866             : 
    1867           0 :     pFrm->Frm() = pFrm->GetUpper()->Prt();
    1868           0 :     pFrm->Frm() += pFrm->GetUpper()->Frm().Pos();
    1869             : 
    1870           0 :     (pFrm->Frm().*fnRect->fnSetHeight)( nMaxHeight );
    1871           0 :     if( pFrm->GetPrev() )
    1872           0 :         (pFrm->Frm().*fnRect->fnSetPosY)(
    1873           0 :                 (pFrm->GetPrev()->Frm().*fnRect->fnGetBottom)() -
    1874           0 :                 ( bVert ? nMaxHeight + 1 : 0 ) );
    1875             : 
    1876           0 :     SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
    1877           0 :     const SwBorderAttrs &rAttrs = *aAccess.Get();
    1878           0 :     (pFrm->Prt().*fnRect->fnSetPosX)( rAttrs.CalcLeft( pFrm ) );
    1879             : 
    1880           0 :     if( pPre )
    1881             :     {
    1882           0 :         SwTwips nUpper = pFrm->CalcUpperSpace( &rAttrs, pPre );
    1883           0 :         (pFrm->Prt().*fnRect->fnSetPosY)( nUpper );
    1884             :     }
    1885           0 :     (pFrm->Prt().*fnRect->fnSetHeight)(
    1886           0 :         std::max( 0L , (pFrm->Frm().*fnRect->fnGetHeight)() -
    1887           0 :                   (pFrm->Prt().*fnRect->fnGetTop)() - nLower ) );
    1888           0 :     (pFrm->Prt().*fnRect->fnSetWidth)(
    1889           0 :         (pFrm->Frm().*fnRect->fnGetWidth)() -
    1890           0 :         ( rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm ) ) );
    1891           0 :     pOldPara = pFrm->HasPara() ? pFrm->GetPara() : NULL;
    1892           0 :     pFrm->SetPara( new SwParaPortion(), sal_False );
    1893             : 
    1894             :     OSL_ENSURE( ! pFrm->IsSwapped(), "A frame is swapped before _Format" );
    1895             : 
    1896           0 :     if ( pFrm->IsVertical() )
    1897           0 :         pFrm->SwapWidthAndHeight();
    1898             : 
    1899           0 :     SwTxtFormatInfo aInf( pFrm, sal_False, sal_True, sal_True );
    1900           0 :     SwTxtFormatter  aLine( pFrm, &aInf );
    1901             : 
    1902           0 :     pFrm->_Format( aLine, aInf );
    1903             : 
    1904           0 :     if ( pFrm->IsVertical() )
    1905           0 :         pFrm->SwapWidthAndHeight();
    1906             : 
    1907           0 :     OSL_ENSURE( ! pFrm->IsSwapped(), "A frame is swapped after _Format" );
    1908           0 : }
    1909             : 
    1910           0 : SwTestFormat::~SwTestFormat()
    1911             : {
    1912           0 :     pFrm->Frm() = aOldFrm;
    1913           0 :     pFrm->Prt() = aOldPrt;
    1914           0 :     pFrm->SetPara( pOldPara );
    1915           0 : }
    1916             : 
    1917           0 : sal_Bool SwTxtFrm::TestFormat( const SwFrm* pPrv, SwTwips &rMaxHeight, sal_Bool &bSplit )
    1918             : {
    1919             :     PROTOCOL_ENTER( this, PROT_TESTFORMAT, 0, 0 )
    1920             : 
    1921           0 :     if( IsLocked() && GetUpper()->Prt().Width() <= 0 )
    1922           0 :         return sal_False;
    1923             : 
    1924           0 :     SwTestFormat aSave( this, pPrv, rMaxHeight );
    1925             : 
    1926           0 :     return SwTxtFrm::WouldFit( rMaxHeight, bSplit, sal_True );
    1927             : }
    1928             : 
    1929             : 
    1930             : /*************************************************************************
    1931             :  *                      SwTxtFrm::WouldFit()
    1932             :  *************************************************************************/
    1933             : 
    1934             : /* SwTxtFrm::WouldFit()
    1935             :  * sal_True: wenn ich aufspalten kann.
    1936             :  * Es soll und braucht nicht neu formatiert werden.
    1937             :  * Wir gehen davon aus, dass bereits formatiert wurde und dass
    1938             :  * die Formatierungsdaten noch aktuell sind.
    1939             :  * Wir gehen davon aus, dass die Framebreiten des evtl. Masters und
    1940             :  * Follows gleich sind. Deswegen wird kein FindBreak() mit FindOrphans()
    1941             :  * gerufen.
    1942             :  * Die benoetigte Hoehe wird von nMaxHeight abgezogen!
    1943             :  */
    1944             : 
    1945          27 : sal_Bool SwTxtFrm::WouldFit( SwTwips &rMaxHeight, sal_Bool &bSplit, sal_Bool bTst )
    1946             : {
    1947             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
    1948             :             "SwTxtFrm::WouldFit with swapped frame" );
    1949          27 :     SWRECTFN( this );
    1950             : 
    1951          27 :     if( IsLocked() )
    1952           0 :         return sal_False;
    1953             : 
    1954             :     //Kann gut sein, dass mir der IdleCollector mir die gecachten
    1955             :     //Informationen entzogen hat.
    1956          27 :     if( !IsEmpty() )
    1957          16 :         GetFormatted();
    1958             : 
    1959             :     // OD 2004-05-24 #i27801# - correction: 'short cut' for empty paragraph
    1960             :     // can *not* be applied, if test format is in progress. The test format doesn't
    1961             :     // adjust the frame and the printing area - see method <SwTxtFrm::_Format(..)>,
    1962             :     // which is called in <SwTxtFrm::TestFormat(..)>
    1963          27 :     if ( IsEmpty() && !bTst )
    1964             :     {
    1965          11 :         bSplit = sal_False;
    1966          11 :         SwTwips nHeight = bVert ? Prt().SSize().Width() : Prt().SSize().Height();
    1967          11 :         if( rMaxHeight < nHeight )
    1968           2 :             return sal_False;
    1969             :         else
    1970             :         {
    1971           9 :             rMaxHeight -= nHeight;
    1972           9 :             return sal_True;
    1973             :         }
    1974             :     }
    1975             : 
    1976             :     // In sehr unguenstigen Faellen kann GetPara immer noch 0 sein.
    1977             :     // Dann returnen wir sal_True, um auf der neuen Seite noch einmal
    1978             :     // anformatiert zu werden.
    1979             :     OSL_ENSURE( HasPara() || IsHiddenNow(), "WouldFit: GetFormatted() and then !HasPara()" );
    1980          16 :     if( !HasPara() || ( !(Frm().*fnRect->fnGetHeight)() && IsHiddenNow() ) )
    1981           0 :         return sal_True;
    1982             : 
    1983             :     // Da das Orphan-Flag nur sehr fluechtig existiert, wird als zweite
    1984             :     // Bedingung  ueberprueft, ob die Rahmengroesse durch CalcPreps
    1985             :     // auf riesengross gesetzt wird, um ein MoveFwd zu erzwingen.
    1986          32 :     if( IsWidow() || ( bVert ?
    1987           0 :                        ( 0 == Frm().Left() ) :
    1988          16 :                        ( LONG_MAX - 20000 < Frm().Bottom() ) ) )
    1989             :     {
    1990           0 :         SetWidow(sal_False);
    1991           0 :         if ( GetFollow() )
    1992             :         {
    1993             :             // Wenn wir hier durch eine Widow-Anforderung unseres Follows gelandet
    1994             :             // sind, wird ueberprueft, ob es ueberhaupt einen Follow mit einer
    1995             :             // echten Hoehe gibt, andernfalls (z.B. in neu angelegten SctFrms)
    1996             :             // ignorieren wir das IsWidow() und pruefen doch noch, ob wir
    1997             :             // genung Platz finden.
    1998           0 :             if( ( ( ! bVert && LONG_MAX - 20000 >= Frm().Bottom() ) ||
    1999           0 :                   (   bVert && 0 < Frm().Left() ) ) &&
    2000           0 :                   ( GetFollow()->IsVertical() ?
    2001           0 :                     !GetFollow()->Frm().Width() :
    2002           0 :                     !GetFollow()->Frm().Height() ) )
    2003             :             {
    2004           0 :                 SwTxtFrm* pFoll = GetFollow()->GetFollow();
    2005           0 :                 while( pFoll &&
    2006           0 :                         ( pFoll->IsVertical() ?
    2007           0 :                          !pFoll->Frm().Width() :
    2008           0 :                          !pFoll->Frm().Height() ) )
    2009           0 :                     pFoll = pFoll->GetFollow();
    2010           0 :                 if( pFoll )
    2011           0 :                     return sal_False;
    2012             :             }
    2013             :             else
    2014           0 :                 return sal_False;
    2015             :         }
    2016             :     }
    2017             : 
    2018          16 :     SWAP_IF_NOT_SWAPPED( this );
    2019             : 
    2020          16 :     SwTxtSizeInfo aInf( this );
    2021          32 :     SwTxtMargin aLine( this, &aInf );
    2022             : 
    2023          16 :     WidowsAndOrphans aFrmBreak( this, rMaxHeight, bSplit );
    2024             : 
    2025          16 :     sal_Bool bRet = sal_True;
    2026             : 
    2027          16 :     aLine.Bottom();
    2028             :     // Ist Aufspalten ueberhaupt notwendig?
    2029          16 :     if ( 0 != ( bSplit = !aFrmBreak.IsInside( aLine ) ) )
    2030           5 :         bRet = !aFrmBreak.IsKeepAlways() && aFrmBreak.WouldFit( aLine, rMaxHeight, bTst );
    2031             :     else
    2032             :     {
    2033             :         //Wir brauchen die Gesamthoehe inklusive der aktuellen Zeile
    2034          11 :         aLine.Top();
    2035          11 :         do
    2036             :         {
    2037          11 :             rMaxHeight -= aLine.GetLineHeight();
    2038          11 :         } while ( aLine.Next() );
    2039             :     }
    2040             : 
    2041          16 :     UNDO_SWAP( this )
    2042             : 
    2043          32 :     return bRet;
    2044             : }
    2045             : 
    2046             : 
    2047             : /*************************************************************************
    2048             :  *                      SwTxtFrm::GetParHeight()
    2049             :  *************************************************************************/
    2050             : 
    2051         145 : KSHORT SwTxtFrm::GetParHeight() const
    2052             : {
    2053             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
    2054             :             "SwTxtFrm::GetParHeight with swapped frame" );
    2055             : 
    2056         145 :     if( !HasPara() )
    2057             :     {   // Fuer nichtleere Absaetze ist dies ein Sonderfall, da koennen wir
    2058             :         // bei UnderSized ruhig nur 1 Twip mehr anfordern.
    2059          40 :         KSHORT nRet = (KSHORT)Prt().SSize().Height();
    2060          40 :         if( IsUndersized() )
    2061             :         {
    2062          40 :             if( IsEmpty() || GetTxt().Len() == 0 )
    2063          39 :                 nRet = (KSHORT)EmptyHeight();
    2064             :             else
    2065           1 :                 ++nRet;
    2066             :         }
    2067          40 :         return nRet;
    2068             :     }
    2069             : 
    2070             :     // FME, OD 08.01.2004 #i11859# - refactoring and improve code
    2071         105 :     const SwLineLayout* pLineLayout = GetPara();
    2072         105 :     KSHORT nHeight = pLineLayout->GetRealHeight();
    2073         105 :     if( GetOfst() && !IsFollow() )  // Ist dieser Absatz gescrollt? Dann ist unsere
    2074           0 :         nHeight *= 2;               // bisherige Hoehe mind. eine Zeilenhoehe zu gering
    2075             :     // OD 2004-03-04 #115793#
    2076         951 :     while ( pLineLayout && pLineLayout->GetNext() )
    2077             :     {
    2078         741 :         pLineLayout = pLineLayout->GetNext();
    2079         741 :         nHeight = nHeight + pLineLayout->GetRealHeight();
    2080             :     }
    2081             : 
    2082         105 :     return nHeight;
    2083             : }
    2084             : 
    2085             : 
    2086             : /*************************************************************************
    2087             :  *                      SwTxtFrm::GetFormatted()
    2088             :  *************************************************************************/
    2089             : 
    2090             : // returnt this _immer_ im formatierten Zustand!
    2091       37699 : SwTxtFrm* SwTxtFrm::GetFormatted( bool bForceQuickFormat )
    2092             : {
    2093       37699 :     SWAP_IF_SWAPPED( this )
    2094             : 
    2095             :     //Kann gut sein, dass mir der IdleCollector mir die gecachten
    2096             :     //Informationen entzogen hat. Calc() ruft unser Format.
    2097             :                       //Nicht bei leeren Absaetzen!
    2098       37699 :     if( !HasPara() && !(IsValid() && IsEmpty()) )
    2099             :     {
    2100             :         // Calc() muss gerufen werden, weil unsere Frameposition
    2101             :         // nicht stimmen muss.
    2102         191 :         const sal_Bool bFormat = GetValidSizeFlag();
    2103         191 :         Calc();
    2104             :         // Es kann durchaus sein, dass Calc() das Format()
    2105             :         // nicht anstiess (weil wir einst vom Idle-Zerstoerer
    2106             :         // aufgefordert wurden unsere Formatinformationen wegzuschmeissen).
    2107             :         // 6995: Optimierung mit FormatQuick()
    2108         191 :         if( bFormat && !FormatQuick( bForceQuickFormat ) )
    2109           0 :             Format();
    2110             :     }
    2111             : 
    2112       37699 :     UNDO_SWAP( this )
    2113             : 
    2114       37699 :     return this;
    2115             : }
    2116             : 
    2117             : /*************************************************************************
    2118             :  *                      SwTxtFrm::CalcFitToContent()
    2119             :  *************************************************************************/
    2120             : 
    2121           0 : SwTwips SwTxtFrm::CalcFitToContent()
    2122             : {
    2123             :     // #i31490#
    2124             :     // If we are currently locked, we better return with a
    2125             :     // fairly reasonable value:
    2126           0 :     if ( IsLocked() )
    2127           0 :         return Prt().Width();
    2128             : 
    2129           0 :     SwParaPortion* pOldPara = GetPara();
    2130           0 :     SwParaPortion *pDummy = new SwParaPortion();
    2131           0 :     SetPara( pDummy, false );
    2132           0 :     const SwPageFrm* pPage = FindPageFrm();
    2133             : 
    2134           0 :     const Point   aOldFrmPos   = Frm().Pos();
    2135           0 :     const SwTwips nOldFrmWidth = Frm().Width();
    2136           0 :     const SwTwips nOldPrtWidth = Prt().Width();
    2137           0 :     const SwTwips nPageWidth = GetUpper()->IsVertical() ?
    2138           0 :                                pPage->Prt().Height() :
    2139           0 :                                pPage->Prt().Width();
    2140             : 
    2141           0 :     Frm().Width( nPageWidth );
    2142           0 :     Prt().Width( nPageWidth );
    2143             : 
    2144             :     // #i25422# objects anchored as character in RTL
    2145           0 :     if ( IsRightToLeft() )
    2146           0 :         Frm().Pos().X() += nOldFrmWidth - nPageWidth;
    2147             : 
    2148             :     // #i31490#
    2149           0 :     SwTxtFrmLocker aLock( this );
    2150             : 
    2151           0 :     SwTxtFormatInfo aInf( this, sal_False, sal_True, sal_True );
    2152           0 :     aInf.SetIgnoreFly( sal_True );
    2153           0 :     SwTxtFormatter  aLine( this, &aInf );
    2154           0 :     SwHookOut aHook( aInf );
    2155             : 
    2156             :     // #i54031# - assure mininum of MINLAY twips.
    2157             :     const SwTwips nMax = std::max( (SwTwips)MINLAY,
    2158           0 :                               aLine._CalcFitToContent() + 1 );
    2159             : 
    2160           0 :     Frm().Width( nOldFrmWidth );
    2161           0 :     Prt().Width( nOldPrtWidth );
    2162             : 
    2163             :     // #i25422# objects anchored as character in RTL
    2164           0 :     if ( IsRightToLeft() )
    2165           0 :         Frm().Pos() = aOldFrmPos;
    2166             : 
    2167             : 
    2168           0 :     SetPara( pOldPara );
    2169             : 
    2170           0 :     return nMax;
    2171             : }
    2172             : 
    2173             : /** simulate format for a list item paragraph, whose list level attributes
    2174             :     are in LABEL_ALIGNMENT mode, in order to determine additional first
    2175             :     line offset for the real text formatting due to the value of label
    2176             :     adjustment attribute of the list level.
    2177             : */
    2178       11280 : void SwTxtFrm::CalcAdditionalFirstLineOffset()
    2179             : {
    2180       11280 :     if ( IsLocked() )
    2181       11280 :         return;
    2182             : 
    2183             :     // reset additional first line offset
    2184       11280 :     mnAdditionalFirstLineOffset = 0;
    2185             : 
    2186       11280 :     const SwTxtNode* pTxtNode( GetTxtNode() );
    2187       11389 :     if ( pTxtNode && pTxtNode->IsNumbered() && pTxtNode->IsCountedInList() &&
    2188         109 :          pTxtNode->GetNumRule() )
    2189             :     {
    2190             :         const SwNumFmt& rNumFmt =
    2191         109 :                 pTxtNode->GetNumRule()->Get( static_cast<sal_uInt16>(pTxtNode->GetActualListLevel()) );
    2192         109 :         if ( rNumFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
    2193             :         {
    2194             :             // keep current paragraph portion and apply dummy paragraph portion
    2195          77 :             SwParaPortion* pOldPara = GetPara();
    2196          77 :             SwParaPortion *pDummy = new SwParaPortion();
    2197          77 :             SetPara( pDummy, false );
    2198             : 
    2199             :             // lock paragraph
    2200          77 :             SwTxtFrmLocker aLock( this );
    2201             : 
    2202             :             // simulate text formatting
    2203         154 :             SwTxtFormatInfo aInf( this, sal_False, sal_True, sal_True );
    2204          77 :             aInf.SetIgnoreFly( sal_True );
    2205         154 :             SwTxtFormatter aLine( this, &aInf );
    2206         154 :             SwHookOut aHook( aInf );
    2207          77 :             aLine._CalcFitToContent();
    2208             : 
    2209             :             // determine additional first line offset
    2210          77 :             const SwLinePortion* pFirstPortion = aLine.GetCurr()->GetFirstPortion();
    2211          77 :             if ( pFirstPortion->InNumberGrp() && !pFirstPortion->IsFtnNumPortion() )
    2212             :             {
    2213          68 :                 SwTwips nNumberPortionWidth( pFirstPortion->Width() );
    2214             : 
    2215          68 :                 const SwLinePortion* pPortion = pFirstPortion->GetPortion();
    2216         204 :                 while ( pPortion &&
    2217          68 :                         pPortion->InNumberGrp() && !pPortion->IsFtnNumPortion())
    2218             :                 {
    2219           0 :                     nNumberPortionWidth += pPortion->Width();
    2220           0 :                     pPortion = pPortion->GetPortion();
    2221             :                 }
    2222             : 
    2223         136 :                 if ( ( IsRightToLeft() &&
    2224         136 :                        rNumFmt.GetNumAdjust() == SVX_ADJUST_LEFT ) ||
    2225         136 :                      ( !IsRightToLeft() &&
    2226          68 :                        rNumFmt.GetNumAdjust() == SVX_ADJUST_RIGHT ) )
    2227             :                 {
    2228           0 :                     mnAdditionalFirstLineOffset = -nNumberPortionWidth;
    2229             :                 }
    2230          68 :                 else if ( rNumFmt.GetNumAdjust() == SVX_ADJUST_CENTER )
    2231             :                 {
    2232           0 :                     mnAdditionalFirstLineOffset = -(nNumberPortionWidth/2);
    2233             :                 }
    2234             :             }
    2235             : 
    2236             :             // restore paragraph portion
    2237         154 :             SetPara( pOldPara );
    2238             :         }
    2239             :     }
    2240             : }
    2241             : 
    2242             : /** determine height of last line for the calculation of the proportional line
    2243             :     spacing
    2244             : 
    2245             :     OD 08.01.2004 #i11859#
    2246             :     OD 2004-03-17 #i11860# - method <GetHeightOfLastLineForPropLineSpacing()>
    2247             :     replace by method <_CalcHeightOfLastLine()>. Height of last line will be
    2248             :     stored in new member <mnHeightOfLastLine> and can be accessed via method
    2249             :     <GetHeightOfLastLine()>
    2250             :     OD 2005-05-20 #i47162# - introduce new optional parameter <_bUseFont>
    2251             :     in order to force the usage of the former algorithm to determine the
    2252             :     height of the last line, which uses the font.
    2253             : */
    2254       11587 : void SwTxtFrm::_CalcHeightOfLastLine( const bool _bUseFont )
    2255             : {
    2256             :     // #i71281#
    2257             :     // invalidate printing area, if height of last line changes
    2258       11587 :     const SwTwips mnOldHeightOfLastLine( mnHeightOfLastLine );
    2259             :     // determine output device
    2260       11587 :     ViewShell* pVsh = getRootFrm()->GetCurrShell();
    2261             :     OSL_ENSURE( pVsh, "<SwTxtFrm::_GetHeightOfLastLineForPropLineSpacing()> - no ViewShell" );
    2262             :     // #i78921# - make code robust, according to provided patch
    2263             :     // There could be no <ViewShell> instance in the case of loading a binary
    2264             :     // StarOffice file format containing an embedded Writer document.
    2265       11587 :     if ( !pVsh )
    2266             :     {
    2267           0 :         return;
    2268             :     }
    2269       11587 :     OutputDevice* pOut = pVsh->GetOut();
    2270       11587 :     const IDocumentSettingAccess* pIDSA = GetTxtNode()->getIDocumentSettingAccess();
    2271       11614 :     if ( !pVsh->GetViewOptions()->getBrowseMode() ||
    2272          27 :           pVsh->GetViewOptions()->IsPrtFormat() )
    2273             :     {
    2274       11560 :         pOut = GetTxtNode()->getIDocumentDeviceAccess()->getReferenceDevice( true );
    2275             :     }
    2276             :     OSL_ENSURE( pOut, "<SwTxtFrm::_GetHeightOfLastLineForPropLineSpacing()> - no OutputDevice" );
    2277             :     // #i78921# - make code robust, according to provided patch
    2278       11587 :     if ( !pOut )
    2279             :     {
    2280           0 :         return;
    2281             :     }
    2282             : 
    2283             :     // determine height of last line
    2284             : 
    2285       11587 :     if ( _bUseFont || pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING ) )
    2286             :     {
    2287             :         // former determination of last line height for proprotional line
    2288             :         // spacing - take height of font set at the paragraph
    2289         590 :         SwFont aFont( GetAttrSet(), pIDSA );
    2290             : 
    2291             :         // Wir muessen dafuer sorgen, dass am OutputDevice der Font
    2292             :         // korrekt restauriert wird, sonst droht ein Last!=Owner.
    2293         590 :         if ( pLastFont )
    2294             :         {
    2295         590 :             SwFntObj *pOldFont = pLastFont;
    2296         590 :             pLastFont = NULL;
    2297         590 :             aFont.SetFntChg( sal_True );
    2298         590 :             aFont.ChgPhysFnt( pVsh, *pOut );
    2299         590 :             mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
    2300         590 :             pLastFont->Unlock();
    2301         590 :             pLastFont = pOldFont;
    2302         590 :             pLastFont->SetDevFont( pVsh, *pOut );
    2303             :         }
    2304             :         else
    2305             :         {
    2306           0 :             Font aOldFont = pOut->GetFont();
    2307           0 :             aFont.SetFntChg( sal_True );
    2308           0 :             aFont.ChgPhysFnt( pVsh, *pOut );
    2309           0 :             mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
    2310           0 :             pLastFont->Unlock();
    2311           0 :             pLastFont = NULL;
    2312           0 :             pOut->SetFont( aOldFont );
    2313         590 :         }
    2314             :     }
    2315             :     else
    2316             :     {
    2317             :         // new determination of last line height - take actually height of last line
    2318             :         // #i89000#
    2319             :         // assure same results, if paragraph is undersized
    2320       10997 :         if ( IsUndersized() )
    2321             :         {
    2322         304 :             mnHeightOfLastLine = 0;
    2323             :         }
    2324             :         else
    2325             :         {
    2326       10693 :             bool bCalcHeightOfLastLine = true;
    2327       10693 :             if ( ( !HasPara() && IsEmpty( ) ) || GetTxt().Len( ) == 0 )
    2328             :             {
    2329        4311 :                 mnHeightOfLastLine = EmptyHeight();
    2330        4311 :                 bCalcHeightOfLastLine = false;
    2331             :             }
    2332             : 
    2333       10693 :             if ( bCalcHeightOfLastLine )
    2334             :             {
    2335             :                 OSL_ENSURE( HasPara(),
    2336             :                         "<SwTxtFrm::_CalcHeightOfLastLine()> - missing paragraph portions." );
    2337        6382 :                 const SwLineLayout* pLineLayout = GetPara();
    2338       51157 :                 while ( pLineLayout && pLineLayout->GetNext() )
    2339             :                 {
    2340             :                     // iteration to last line
    2341       38393 :                     pLineLayout = pLineLayout->GetNext();
    2342             :                 }
    2343        6382 :                 if ( pLineLayout )
    2344             :                 {
    2345             :                     SwTwips nAscent, nDescent, nDummy1, nDummy2;
    2346             :                     // #i47162# - suppress consideration of
    2347             :                     // fly content portions and the line portion.
    2348             :                     pLineLayout->MaxAscentDescent( nAscent, nDescent,
    2349             :                                                    nDummy1, nDummy2,
    2350        6382 :                                                    0, true );
    2351             :                     // #i71281#
    2352             :                     // Suppress wrong invalidation of printing area, if method is
    2353             :                     // called recursive.
    2354             :                     // Thus, member <mnHeightOfLastLine> is only set directly, if
    2355             :                     // no recursive call is needed.
    2356        6382 :                     const SwTwips nNewHeightOfLastLine = nAscent + nDescent;
    2357             :                     // #i47162# - if last line only contains
    2358             :                     // fly content portions, <mnHeightOfLastLine> is zero.
    2359             :                     // In this case determine height of last line by the font
    2360        6382 :                     if ( nNewHeightOfLastLine == 0 )
    2361             :                     {
    2362         577 :                         _CalcHeightOfLastLine( true );
    2363             :                     }
    2364             :                     else
    2365             :                     {
    2366        5805 :                         mnHeightOfLastLine = nNewHeightOfLastLine;
    2367             :                     }
    2368             :                 }
    2369             :             }
    2370             :         }
    2371             :     }
    2372             :     // #i71281#
    2373             :     // invalidate printing area, if height of last line changes
    2374       11587 :     if ( mnHeightOfLastLine != mnOldHeightOfLastLine )
    2375             :     {
    2376        3979 :         InvalidatePrt();
    2377             :     }
    2378             : }
    2379             : 
    2380             : /*************************************************************************
    2381             :  *                      SwTxtFrm::GetLineSpace()
    2382             :  *************************************************************************/
    2383             : // OD 07.01.2004 #i11859# - change return data type
    2384             : //      add default parameter <_bNoPropLineSpacing> to control, if the
    2385             : //      value of a proportional line spacing is returned or not
    2386             : // OD 07.01.2004 - trying to describe purpose of method:
    2387             : //      Method returns the value of the inter line spacing for a text frame.
    2388             : //      Such a value exists for proportional line spacings ("1,5 Lines",
    2389             : //      "Double", "Proportional" and for leading line spacing ("Leading").
    2390             : //      By parameter <_bNoPropLineSpace> (default value false) it can be
    2391             : //      controlled, if the value of a proportional line spacing is returned.
    2392        7140 : long SwTxtFrm::GetLineSpace( const bool _bNoPropLineSpace ) const
    2393             : {
    2394        7140 :     long nRet = 0;
    2395             : 
    2396        7140 :     const SwAttrSet* pSet = GetAttrSet();
    2397        7140 :     const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
    2398             : 
    2399        7140 :     switch( rSpace.GetInterLineSpaceRule() )
    2400             :     {
    2401             :         case SVX_INTER_LINE_SPACE_PROP:
    2402             :         {
    2403             :             // OD 07.01.2004 #i11859#
    2404        1464 :             if ( _bNoPropLineSpace )
    2405             :             {
    2406         908 :                 break;
    2407             :             }
    2408             : 
    2409             :             // OD 2004-03-17 #i11860# - use method <GetHeightOfLastLine()>
    2410         556 :             nRet = GetHeightOfLastLine();
    2411             : 
    2412         556 :             long nTmp = nRet;
    2413         556 :             nTmp *= rSpace.GetPropLineSpace();
    2414         556 :             nTmp /= 100;
    2415         556 :             nTmp -= nRet;
    2416         556 :             if ( nTmp > 0 )
    2417         374 :                 nRet = nTmp;
    2418             :             else
    2419         182 :                 nRet = 0;
    2420             :         }
    2421         556 :             break;
    2422             :         case SVX_INTER_LINE_SPACE_FIX:
    2423             :         {
    2424           0 :             if ( rSpace.GetInterLineSpace() > 0 )
    2425           0 :                 nRet = rSpace.GetInterLineSpace();
    2426             :         }
    2427           0 :             break;
    2428             :         default:
    2429        5676 :             break;
    2430             :     }
    2431        7140 :     return nRet;
    2432             : }
    2433             : 
    2434             : /*************************************************************************
    2435             :  *                      SwTxtFrm::FirstLineHeight()
    2436             :  *************************************************************************/
    2437             : 
    2438          33 : KSHORT SwTxtFrm::FirstLineHeight() const
    2439             : {
    2440          33 :     if ( !HasPara() )
    2441             :     {
    2442          33 :         if( IsEmpty() && IsValid() )
    2443          33 :             return IsVertical() ? (KSHORT)Prt().Width() : (KSHORT)Prt().Height();
    2444           0 :         return KSHRT_MAX;
    2445             :     }
    2446           0 :     const SwParaPortion *pPara = GetPara();
    2447           0 :     if ( !pPara )
    2448           0 :         return KSHRT_MAX;
    2449             : 
    2450           0 :     return pPara->Height();
    2451             : }
    2452             : 
    2453           0 : MSHORT SwTxtFrm::GetLineCount( xub_StrLen nPos )
    2454             : {
    2455           0 :     MSHORT nRet = 0;
    2456           0 :     SwTxtFrm *pFrm = this;
    2457           0 :     do
    2458             :     {
    2459           0 :         pFrm->GetFormatted();
    2460           0 :         if( !pFrm->HasPara() )
    2461           0 :             break;
    2462           0 :         SwTxtSizeInfo aInf( pFrm );
    2463           0 :         SwTxtMargin aLine( pFrm, &aInf );
    2464           0 :         if( STRING_LEN == nPos )
    2465           0 :             aLine.Bottom();
    2466             :         else
    2467           0 :             aLine.CharToLine( nPos );
    2468           0 :         nRet = nRet + aLine.GetLineNr();
    2469           0 :         pFrm = pFrm->GetFollow();
    2470           0 :     } while ( pFrm && pFrm->GetOfst() <= nPos );
    2471           0 :     return nRet;
    2472             : }
    2473             : 
    2474       11229 : void SwTxtFrm::ChgThisLines()
    2475             : {
    2476             :     //not necessary to format here (GerFormatted etc.), because we have to come from there!
    2477             : 
    2478       11229 :     sal_uLong nNew = 0;
    2479       11229 :     const SwLineNumberInfo &rInf = GetNode()->getIDocumentLineNumberAccess()->GetLineNumberInfo();
    2480       11229 :     if ( GetTxt().Len() && HasPara() )
    2481             :     {
    2482        6536 :         SwTxtSizeInfo aInf( this );
    2483       13072 :         SwTxtMargin aLine( this, &aInf );
    2484        6536 :         if ( rInf.IsCountBlankLines() )
    2485             :         {
    2486        6536 :             aLine.Bottom();
    2487        6536 :             nNew = (sal_uLong)aLine.GetLineNr();
    2488             :         }
    2489             :         else
    2490             :         {
    2491           0 :             do
    2492             :             {
    2493           0 :                 if( aLine.GetCurr()->HasCntnt() )
    2494           0 :                     ++nNew;
    2495           0 :             } while ( aLine.NextLine() );
    2496        6536 :         }
    2497             :     }
    2498        4693 :     else if ( rInf.IsCountBlankLines() )
    2499        4693 :         nNew = 1;
    2500             : 
    2501       11229 :     if ( nNew != nThisLines )
    2502             :     {
    2503        4458 :         if ( !IsInTab() && GetAttrSet()->GetLineNumber().IsCount() )
    2504             :         {
    2505        2745 :             nAllLines -= nThisLines;
    2506        2745 :             nThisLines = nNew;
    2507        2745 :             nAllLines  += nThisLines;
    2508        2745 :             SwFrm *pNxt = GetNextCntntFrm();
    2509        5554 :             while( pNxt && pNxt->IsInTab() )
    2510             :             {
    2511          64 :                 if( 0 != (pNxt = pNxt->FindTabFrm()) )
    2512          64 :                     pNxt = pNxt->FindNextCnt();
    2513             :             }
    2514        2745 :             if( pNxt )
    2515        1288 :                 pNxt->InvalidateLineNum();
    2516             : 
    2517             :             //Extend repaint to the bottom.
    2518        2745 :             if ( HasPara() )
    2519             :             {
    2520        1763 :                 SwRepaint *pRepaint = GetPara()->GetRepaint();
    2521        1763 :                 pRepaint->Bottom( std::max( pRepaint->Bottom(),
    2522        3526 :                                        Frm().Top()+Prt().Bottom()));
    2523             :             }
    2524             :         }
    2525             :         else //Paragraphs which are not counted should not manipulate the AllLines.
    2526        1713 :             nThisLines = nNew;
    2527             :     }
    2528       11229 : }
    2529             : 
    2530             : 
    2531        6091 : void SwTxtFrm::RecalcAllLines()
    2532             : {
    2533        6091 :     ValidateLineNum();
    2534             : 
    2535        6091 :     const SwAttrSet *pAttrSet = GetAttrSet();
    2536             : 
    2537        6091 :     if ( !IsInTab() )
    2538             :     {
    2539        3147 :         const sal_uLong nOld = GetAllLines();
    2540        3147 :         const SwFmtLineNumber &rLineNum = pAttrSet->GetLineNumber();
    2541             :         sal_uLong nNewNum;
    2542        3147 :         const bool bRestart = GetTxtNode()->getIDocumentLineNumberAccess()->GetLineNumberInfo().IsRestartEachPage();
    2543             : 
    2544        3147 :         if ( !IsFollow() && rLineNum.GetStartValue() && rLineNum.IsCount() )
    2545           2 :             nNewNum = rLineNum.GetStartValue() - 1;
    2546             :         //If it is a follow or not has not be considered if it is a restart at each page; the
    2547             :         //restart should also take affekt at follows.
    2548        3145 :         else if ( bRestart && FindPageFrm()->FindFirstBodyCntnt() == this )
    2549             :         {
    2550           0 :             nNewNum = 0;
    2551             :         }
    2552             :         else
    2553             :         {
    2554        3145 :             SwCntntFrm *pPrv = GetPrevCntntFrm();
    2555       14822 :             while ( pPrv &&
    2556        6340 :                     (pPrv->IsInTab() || pPrv->IsInDocBody() != IsInDocBody()) )
    2557        2222 :                 pPrv = pPrv->GetPrevCntntFrm();
    2558             : 
    2559             :             // #i78254# Restart line numbering at page change
    2560             :             // First body content may be in table!
    2561        3145 :             if ( bRestart && pPrv && pPrv->FindPageFrm() != FindPageFrm() )
    2562           0 :                 pPrv = 0;
    2563             : 
    2564        3145 :             nNewNum = pPrv ? ((SwTxtFrm*)pPrv)->GetAllLines() : 0;
    2565             :         }
    2566        3147 :         if ( rLineNum.IsCount() )
    2567        3055 :             nNewNum += GetThisLines();
    2568             : 
    2569        3147 :         if ( nOld != nNewNum )
    2570             :         {
    2571        1718 :             nAllLines = nNewNum;
    2572        1718 :             SwCntntFrm *pNxt = GetNextCntntFrm();
    2573        6901 :             while ( pNxt &&
    2574        3327 :                     (pNxt->IsInTab() || pNxt->IsInDocBody() != IsInDocBody()) )
    2575         754 :                 pNxt = pNxt->GetNextCntntFrm();
    2576        1718 :             if ( pNxt )
    2577             :             {
    2578        1203 :                 if ( pNxt->GetUpper() != GetUpper() )
    2579         264 :                     pNxt->InvalidateLineNum();
    2580             :                 else
    2581         939 :                     pNxt->_InvalidateLineNum();
    2582             :             }
    2583             :         }
    2584             :     }
    2585        6091 : }
    2586             : 
    2587         618 : void SwTxtFrm::VisitPortions( SwPortionHandler& rPH ) const
    2588             : {
    2589         618 :     const SwParaPortion* pPara = GetPara();
    2590             : 
    2591         618 :     if( pPara )
    2592             :     {
    2593         308 :         if ( IsFollow() )
    2594           0 :             rPH.Skip( GetOfst() );
    2595             : 
    2596         308 :         const SwLineLayout* pLine = pPara;
    2597         952 :         while ( pLine )
    2598             :         {
    2599         336 :             const SwLinePortion* pPor = pLine->GetFirstPortion();
    2600        1132 :             while ( pPor )
    2601             :             {
    2602         460 :                 pPor->HandlePortion( rPH );
    2603         460 :                 pPor = pPor->GetPortion();
    2604             :             }
    2605             : 
    2606         336 :             rPH.LineBreak(pLine->Width());
    2607         336 :             pLine = pLine->GetNext();
    2608             :         }
    2609             :     }
    2610             : 
    2611         618 :     rPH.Finish();
    2612         618 : }
    2613             : 
    2614             : 
    2615             : /*************************************************************************
    2616             :  *                      SwTxtFrm::GetScriptInfo()
    2617             :  *************************************************************************/
    2618             : 
    2619       30876 : const SwScriptInfo* SwTxtFrm::GetScriptInfo() const
    2620             : {
    2621       30876 :     const SwParaPortion* pPara = GetPara();
    2622       30876 :     return pPara ? &pPara->GetScriptInfo() : 0;
    2623             : }
    2624             : 
    2625             : /*************************************************************************
    2626             :  *                      lcl_CalcFlyBasePos()
    2627             :  * Helper function for SwTxtFrm::CalcBasePosForFly()
    2628             :  *************************************************************************/
    2629             : 
    2630        4446 : static SwTwips lcl_CalcFlyBasePos( const SwTxtFrm& rFrm, SwRect aFlyRect,
    2631             :                             SwTxtFly& rTxtFly )
    2632             : {
    2633        4446 :     SWRECTFN( (&rFrm) )
    2634        4446 :     SwTwips nRet = rFrm.IsRightToLeft() ?
    2635           8 :                    (rFrm.Frm().*fnRect->fnGetRight)() :
    2636        4454 :                    (rFrm.Frm().*fnRect->fnGetLeft)();
    2637             : 
    2638           9 :     do
    2639             :     {
    2640        4455 :         SwRect aRect = rTxtFly.GetFrm( aFlyRect );
    2641        4455 :         if ( 0 != (aRect.*fnRect->fnGetWidth)() )
    2642             :         {
    2643          59 :             if ( rFrm.IsRightToLeft() )
    2644             :             {
    2645           0 :                 if ( (aRect.*fnRect->fnGetRight)() -
    2646           0 :                      (aFlyRect.*fnRect->fnGetRight)() >= 0 )
    2647             :                 {
    2648             :                     (aFlyRect.*fnRect->fnSetRight)(
    2649           0 :                         (aRect.*fnRect->fnGetLeft)() );
    2650           0 :                     nRet = (aRect.*fnRect->fnGetLeft)();
    2651             :                 }
    2652             :                 else
    2653        4446 :                     break;
    2654             :             }
    2655             :             else
    2656             :             {
    2657         118 :                 if ( (aFlyRect.*fnRect->fnGetLeft)() -
    2658          59 :                      (aRect.*fnRect->fnGetLeft)() >= 0 )
    2659             :                 {
    2660             :                     (aFlyRect.*fnRect->fnSetLeft)(
    2661           9 :                         (aRect.*fnRect->fnGetRight)() + 1 );
    2662           9 :                     nRet = (aRect.*fnRect->fnGetRight)();
    2663             :                 }
    2664             :                 else
    2665          50 :                     break;
    2666             :             }
    2667             :         }
    2668             :         else
    2669        4396 :             break;
    2670             :     }
    2671           9 :     while ( (aFlyRect.*fnRect->fnGetWidth)() > 0 );
    2672             : 
    2673        4446 :     return nRet;
    2674             : }
    2675             : 
    2676             : /*************************************************************************
    2677             :  *                      SwTxtFrm::CalcBasePosForFly()
    2678             :  *************************************************************************/
    2679             : 
    2680       11010 : void SwTxtFrm::CalcBaseOfstForFly()
    2681             : {
    2682             :     OSL_ENSURE( !IsVertical() || !IsSwapped(),
    2683             :             "SwTxtFrm::CalcBasePosForFly with swapped frame!" );
    2684             : 
    2685       11010 :     const SwNode* pNode = GetTxtNode();
    2686       11010 :     if ( !pNode->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_FLY_OFFSETS) )
    2687       19797 :         return;
    2688             : 
    2689        2223 :     SWRECTFN( this )
    2690             : 
    2691        2223 :     SwRect aFlyRect( Frm().Pos() + Prt().Pos(), Prt().SSize() );
    2692             : 
    2693             :     // Get first 'real' line and adjust position and height of line rectangle
    2694             :     // OD 08.09.2003 #110978#, #108749#, #110354# - correct behaviour,
    2695             :     // if no 'real' line exists (empty paragraph with and without a dummy portion)
    2696             :     {
    2697        2223 :         SwTwips nTop = (aFlyRect.*fnRect->fnGetTop)();
    2698        2223 :         const SwLineLayout* pLay = GetPara();
    2699        2223 :         SwTwips nLineHeight = 200;
    2700        4448 :         while( pLay && pLay->IsDummy() && pLay->GetNext() )
    2701             :         {
    2702           2 :             nTop += pLay->Height();
    2703           2 :             pLay = pLay->GetNext();
    2704             :         }
    2705        2223 :         if ( pLay )
    2706             :         {
    2707        1419 :             nLineHeight = pLay->Height();
    2708             :         }
    2709        2223 :         (aFlyRect.*fnRect->fnSetTopAndHeight)( nTop, nLineHeight );
    2710             :     }
    2711             : 
    2712        2223 :     SwTxtFly aTxtFly( this );
    2713        2223 :     aTxtFly.SetIgnoreCurrentFrame( sal_True );
    2714        2223 :     aTxtFly.SetIgnoreContour( sal_True );
    2715             :     // #118809# - ignore objects in page header|footer for
    2716             :     // text frames not in page header|footer
    2717        2223 :     aTxtFly.SetIgnoreObjsInHeaderFooter( sal_True );
    2718        2223 :     SwTwips nRet1 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly );
    2719        2223 :     aTxtFly.SetIgnoreCurrentFrame( sal_False );
    2720        2223 :     SwTwips nRet2 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly );
    2721             : 
    2722             :     // make values relative to frame start position
    2723        2223 :     SwTwips nLeft = IsRightToLeft() ?
    2724           4 :                     (Frm().*fnRect->fnGetRight)() :
    2725        2227 :                     (Frm().*fnRect->fnGetLeft)();
    2726             : 
    2727        2223 :     mnFlyAnchorOfst = nRet1 - nLeft;
    2728        2223 :     mnFlyAnchorOfstNoWrap = nRet2 - nLeft;
    2729             : }
    2730             : 
    2731             : /* repaint all text frames of the given text node */
    2732           0 : void SwTxtFrm::repaintTextFrames( const SwTxtNode& rNode )
    2733             : {
    2734           0 :     SwIterator<SwTxtFrm,SwTxtNode> aIter( rNode );
    2735           0 :     for( const SwTxtFrm *pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
    2736             :     {
    2737           0 :         SwRect aRec( pFrm->PaintArea() );
    2738           0 :         const SwRootFrm *pRootFrm = pFrm->getRootFrm();
    2739           0 :         ViewShell *pCurShell = pRootFrm ? pRootFrm->GetCurrShell() : NULL;
    2740           0 :         if( pCurShell )
    2741           0 :             pCurShell->InvalidateWindows( aRec );
    2742           0 :     }
    2743          99 : }
    2744             : 
    2745             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10