LCOV - code coverage report
Current view: top level - sw/source/core/text - frmform.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 665 943 70.5 %
Date: 2014-11-03 Functions: 26 27 96.3 %
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 <editeng/keepitem.hxx>
      22             : #include <editeng/hyphenzoneitem.hxx>
      23             : #include <pagefrm.hxx>
      24             : #include <ndtxt.hxx>
      25             : #include <dcontact.hxx>
      26             : #include <dflyobj.hxx>
      27             : #include <flyfrm.hxx>
      28             : #include <ftnfrm.hxx>
      29             : #include <txtftn.hxx>
      30             : #include <fmtftn.hxx>
      31             : #include <paratr.hxx>
      32             : #include <viewopt.hxx>
      33             : #include <viewsh.hxx>
      34             : #include <frmatr.hxx>
      35             : #include <pam.hxx>
      36             : #include <flyfrms.hxx>
      37             : #include <fmtanchr.hxx>
      38             : #include <itrform2.hxx>
      39             : #include <widorp.hxx>
      40             : #include <txtcache.hxx>
      41             : #include <porrst.hxx>
      42             : #include <blink.hxx>
      43             : #include <porfld.hxx>
      44             : #include <sectfrm.hxx>
      45             : #include <pormulti.hxx>
      46             : #include <rootfrm.hxx>
      47             : #include <frmfmt.hxx>
      48             : #include <sortedobjs.hxx>
      49             : #include <portab.hxx>
      50             : #include <editeng/lrspitem.hxx>
      51             : #include <editeng/tstpitem.hxx>
      52             : 
      53             : // Tolerance in formatting and text output
      54             : #define SLOPPY_TWIPS    5
      55             : 
      56             : class FormatLevel
      57             : {
      58             :     static sal_uInt16 nLevel;
      59             : public:
      60      100483 :     inline FormatLevel()  { ++nLevel; }
      61      100483 :     inline ~FormatLevel() { --nLevel; }
      62      100483 :     inline sal_uInt16 GetLevel() const { return nLevel; }
      63        2180 :     static bool LastLevel() { return 10 < nLevel; }
      64             : };
      65             : sal_uInt16 FormatLevel::nLevel = 0;
      66             : 
      67         168 : void ValidateTxt( SwFrm *pFrm )     // Friend of frame
      68             : {
      69         504 :     if ( ( ! pFrm->IsVertical() &&
      70         336 :              pFrm->Frm().Width() == pFrm->GetUpper()->Prt().Width() ) ||
      71           0 :          (   pFrm->IsVertical() &&
      72           0 :              pFrm->Frm().Height() == pFrm->GetUpper()->Prt().Height() ) )
      73         168 :         pFrm->mbValidSize = true;
      74         168 : }
      75             : 
      76         168 : void SwTxtFrm::ValidateFrm()
      77             : {
      78             :     // Validate surroundings to avoid oscillation
      79         168 :     SWAP_IF_SWAPPED( this )
      80             : 
      81         168 :     if ( !IsInFly() && !IsInTab() )
      82             :     {   // Only validate 'this' when inside a fly, the rest should actually only be
      83             :         // needed for footnotes, which do not exist in flys.
      84         166 :         SwSectionFrm* pSct = FindSctFrm();
      85         166 :         if( pSct )
      86             :         {
      87          24 :             if( !pSct->IsColLocked() )
      88          12 :                 pSct->ColLock();
      89             :             else
      90          12 :                 pSct = NULL;
      91             :         }
      92             : 
      93         166 :         SwFrm *pUp = GetUpper();
      94         166 :         pUp->Calc();
      95         166 :         if( pSct )
      96          12 :             pSct->ColUnlock();
      97             :     }
      98         168 :     ValidateTxt( this );
      99             : 
     100             :     // We at least have to save the MustFit flag!
     101             :     OSL_ENSURE( HasPara(), "ResetPreps(), missing ParaPortion." );
     102         168 :     SwParaPortion *pPara = GetPara();
     103         168 :     const bool bMustFit = pPara->IsPrepMustFit();
     104         168 :     ResetPreps();
     105         168 :     pPara->SetPrepMustFit( bMustFit );
     106             : 
     107         168 :     UNDO_SWAP( this )
     108         168 : }
     109             : 
     110             : // After a RemoveFtn the BodyFrm and all Frms contained within it, need to be
     111             : // recalculated, so that the DeadLine is right.
     112             : // First we search outwards, on the way back we calculate everything.
     113         166 : void _ValidateBodyFrm( SwFrm *pFrm )
     114             : {
     115         166 :     if( pFrm && !pFrm->IsCellFrm() )
     116             :     {
     117         166 :         if( !pFrm->IsBodyFrm() && pFrm->GetUpper() )
     118          12 :             _ValidateBodyFrm( pFrm->GetUpper() );
     119         166 :         if( !pFrm->IsSctFrm() )
     120         154 :             pFrm->Calc();
     121             :         else
     122             :         {
     123          12 :             const bool bOld = ((SwSectionFrm*)pFrm)->IsCntntLocked();
     124          12 :             ((SwSectionFrm*)pFrm)->SetCntntLock( true );
     125          12 :             pFrm->Calc();
     126          12 :             if( !bOld )
     127          12 :                 ((SwSectionFrm*)pFrm)->SetCntntLock( false );
     128             :         }
     129             :     }
     130         166 : }
     131             : 
     132         168 : void SwTxtFrm::ValidateBodyFrm()
     133             : {
     134         168 :     SWAP_IF_SWAPPED( this )
     135             : 
     136             :      // See comment in ValidateFrm()
     137         488 :     if ( !IsInFly() && !IsInTab() &&
     138         190 :          !( IsInSct() && FindSctFrm()->Lower()->IsColumnFrm() ) )
     139         154 :         _ValidateBodyFrm( GetUpper() );
     140             : 
     141         168 :     UNDO_SWAP( this )
     142         168 : }
     143             : 
     144        1648 : bool SwTxtFrm::_GetDropRect( SwRect &rRect ) const
     145             : {
     146        1648 :     SWAP_IF_NOT_SWAPPED( this )
     147             : 
     148             :     OSL_ENSURE( HasPara(), "SwTxtFrm::_GetDropRect: try again next year." );
     149        1648 :     SwTxtSizeInfo aInf( (SwTxtFrm*)this );
     150        3296 :     SwTxtMargin aLine( (SwTxtFrm*)this, &aInf );
     151        1648 :     if( aLine.GetDropLines() )
     152             :     {
     153           0 :         rRect.Top( aLine.Y() );
     154           0 :         rRect.Left( aLine.GetLineStart() );
     155           0 :         rRect.Height( aLine.GetDropHeight() );
     156           0 :         rRect.Width( aLine.GetDropLeft() );
     157             : 
     158           0 :         if ( IsRightToLeft() )
     159           0 :             SwitchLTRtoRTL( rRect );
     160             : 
     161           0 :         if ( IsVertical() )
     162           0 :             SwitchHorizontalToVertical( rRect );
     163           0 :         UNDO_SWAP( this )
     164           0 :         return true;
     165             :     }
     166             : 
     167        1648 :     UNDO_SWAP( this )
     168             : 
     169        3296 :     return false;
     170             : }
     171             : 
     172       95695 : const SwBodyFrm *SwTxtFrm::FindBodyFrm() const
     173             : {
     174       95695 :     if ( IsInDocBody() )
     175             :     {
     176       72068 :         const SwFrm *pFrm = GetUpper();
     177      236834 :         while( pFrm && !pFrm->IsBodyFrm() )
     178       92698 :             pFrm = pFrm->GetUpper();
     179       72068 :         return (const SwBodyFrm*)pFrm;
     180             :     }
     181       23627 :     return 0;
     182             : }
     183             : 
     184        2029 : bool SwTxtFrm::CalcFollow( const sal_Int32 nTxtOfst )
     185             : {
     186        2029 :     SWAP_IF_SWAPPED( this )
     187             : 
     188             :     OSL_ENSURE( HasFollow(), "CalcFollow: missing Follow." );
     189             : 
     190        2029 :     SwTxtFrm* pMyFollow = GetFollow();
     191             : 
     192        2029 :     SwParaPortion *pPara = GetPara();
     193        2029 :     const bool bFollowFld = pPara && pPara->IsFollowField();
     194             : 
     195        4257 :     if( !pMyFollow->GetOfst() || pMyFollow->GetOfst() != nTxtOfst ||
     196         398 :         bFollowFld || pMyFollow->IsFieldFollow() ||
     197        4325 :         ( pMyFollow->IsVertical() && !pMyFollow->Prt().Width() ) ||
     198         398 :         ( ! pMyFollow->IsVertical() && !pMyFollow->Prt().Height() ) )
     199             :     {
     200             : #if OSL_DEBUG_LEVEL > 0
     201             :         const SwFrm *pOldUp = GetUpper();
     202             : #endif
     203             : 
     204        1898 :         SWRECTFN ( this )
     205        1898 :         SwTwips nOldBottom = (GetUpper()->Frm().*fnRect->fnGetBottom)();
     206        1898 :         SwTwips nMyPos = (Frm().*fnRect->fnGetTop)();
     207             : 
     208        1898 :         const SwPageFrm *pPage = 0;
     209        1898 :         bool bOldInvaCntnt = true;
     210        1898 :         if ( !IsInFly() && GetNext() )
     211             :         {
     212        1306 :             pPage = FindPageFrm();
     213             :             // Minimize = that is set back if needed - for invalidation see below
     214        1306 :             bOldInvaCntnt  = pPage->IsInvalidCntnt();
     215             :         }
     216             : 
     217        1898 :         pMyFollow->_SetOfst( nTxtOfst );
     218        1898 :         pMyFollow->SetFieldFollow( bFollowFld );
     219        1898 :         if( HasFtn() || pMyFollow->HasFtn() )
     220             :         {
     221           0 :             ValidateFrm();
     222           0 :             ValidateBodyFrm();
     223           0 :             if( pPara )
     224             :             {
     225           0 :                 pPara->GetReformat() = SwCharRange();
     226           0 :                 pPara->GetDelta() = 0;
     227             :             }
     228             :         }
     229             : 
     230             :         // The footnote area must not get larger
     231        1898 :         SwSaveFtnHeight aSave( FindFtnBossFrm( true ), LONG_MAX );
     232             : 
     233        1898 :         pMyFollow->CalcFtnFlag();
     234        1898 :         if ( !pMyFollow->GetNext() && !pMyFollow->HasFtn() )
     235        1216 :             nOldBottom = bVert ? 0 : LONG_MAX;
     236             : 
     237             :         while( true )
     238             :         {
     239        2180 :             if( !FormatLevel::LastLevel() )
     240             :             {
     241             :                 // If the follow is contained within a column section or column
     242             :                 // frame, we need to calculate that first. This is because the
     243             :                 // FormatWidthCols() does not work if it is called from MakeAll
     244             :                 // of the _locked_ follow.
     245        2170 :                 SwSectionFrm* pSct = pMyFollow->FindSctFrm();
     246        2170 :                 if( pSct && !pSct->IsAnLower( this ) )
     247             :                 {
     248          30 :                     if( pSct->GetFollow() )
     249           0 :                         pSct->SimpleFormat();
     250          86 :                     else if( ( pSct->IsVertical() && !pSct->Frm().Width() ) ||
     251          60 :                              ( ! pSct->IsVertical() && !pSct->Frm().Height() ) )
     252          26 :                         break;
     253             :                 }
     254             :                 // OD 14.03.2003 #i11760# - intrinsic format of follow is controlled.
     255        2144 :                 if ( FollowFormatAllowed() )
     256             :                 {
     257             :                     // OD 14.03.2003 #i11760# - no nested format of follows, if
     258             :                     // text frame is contained in a column frame.
     259             :                     // Thus, forbid intrinsic format of follow.
     260             :                     {
     261        2110 :                         bool bIsFollowInColumn = false;
     262        2110 :                         SwFrm* pFollowUpper = pMyFollow->GetUpper();
     263        7692 :                         while ( pFollowUpper )
     264             :                         {
     265        5582 :                             if ( pFollowUpper->IsColumnFrm() )
     266             :                             {
     267         776 :                                 bIsFollowInColumn = true;
     268         776 :                                 break;
     269             :                             }
     270        8278 :                             if ( pFollowUpper->IsPageFrm() ||
     271        3472 :                                  pFollowUpper->IsFlyFrm() )
     272             :                             {
     273        1334 :                                 break;
     274             :                             }
     275        3472 :                             pFollowUpper = pFollowUpper->GetUpper();
     276             :                         }
     277        2110 :                         if ( bIsFollowInColumn )
     278             :                         {
     279         776 :                             pMyFollow->ForbidFollowFormat();
     280             :                         }
     281             :                     }
     282             : 
     283        2110 :                     pMyFollow->Calc();
     284             :                     // The Follow can tell from its Frm().Height() that something went wrong
     285             :                     OSL_ENSURE( !pMyFollow->GetPrev(), "SwTxtFrm::CalcFollow: cheesy follow" );
     286        2110 :                     if( pMyFollow->GetPrev() )
     287             :                     {
     288           0 :                         pMyFollow->Prepare( PREP_CLEAR );
     289           0 :                         pMyFollow->Calc();
     290             :                         OSL_ENSURE( !pMyFollow->GetPrev(), "SwTxtFrm::CalcFollow: very cheesy follow" );
     291             :                     }
     292             : 
     293             :                     // OD 14.03.2003 #i11760# - reset control flag for follow format.
     294        2110 :                     pMyFollow->AllowFollowFormat();
     295             :                 }
     296             : 
     297             :                 // Make sure that the Follow gets painted
     298        2144 :                 pMyFollow->SetCompletePaint();
     299             :             }
     300             : 
     301        2154 :             pPara = GetPara();
     302             :             // As long as the Follow is requested due to orphan lines, it is passed these
     303             :             // and is reformatted if possible
     304        2154 :             if( pPara && pPara->IsPrepWidows() )
     305         282 :                 CalcPreps();
     306             :             else
     307        1872 :                 break;
     308             :         }
     309             : 
     310        1898 :         if( HasFtn() || pMyFollow->HasFtn() )
     311             :         {
     312           0 :             ValidateBodyFrm();
     313           0 :             ValidateFrm();
     314           0 :             if( pPara )
     315             :             {
     316           0 :                 pPara->GetReformat() = SwCharRange();
     317           0 :                 pPara->GetDelta() = 0;
     318             :             }
     319             :         }
     320             : 
     321        1898 :         if ( pPage )
     322             :         {
     323        1306 :             if ( !bOldInvaCntnt )
     324           2 :                 pPage->ValidateCntnt();
     325             :         }
     326             : 
     327             : #if OSL_DEBUG_LEVEL > 0
     328             :         OSL_ENSURE( pOldUp == GetUpper(), "SwTxtFrm::CalcFollow: heavy follow" );
     329             : #endif
     330             : 
     331             :         const long nRemaining =
     332        1898 :                  - (GetUpper()->Frm().*fnRect->fnBottomDist)( nOldBottom );
     333        1898 :         if (  nRemaining > 0 && !GetUpper()->IsSctFrm() &&
     334           0 :               nRemaining != ( bVert ?
     335           0 :                               nMyPos - Frm().Right() :
     336           0 :                               Frm().Top() - nMyPos ) )
     337             :         {
     338           0 :             UNDO_SWAP( this )
     339           0 :             return true;
     340        1898 :         }
     341             :     }
     342             : 
     343        2029 :     UNDO_SWAP( this )
     344             : 
     345        2029 :     return false;
     346             : }
     347             : 
     348      125911 : void SwTxtFrm::AdjustFrm( const SwTwips nChgHght, bool bHasToFit )
     349             : {
     350      125911 :     if( IsUndersized() )
     351             :     {
     352       10490 :         if( GetOfst() && !IsFollow() ) // A scrolled paragraph (undersized)
     353           0 :             return;
     354       10490 :         SetUndersized( nChgHght == 0 || bHasToFit );
     355             :     }
     356             : 
     357             :     // AdjustFrm is called with a swapped frame during
     358             :     // formatting but the frame is not swapped during FormatEmpty
     359      125911 :     SWAP_IF_SWAPPED( this )
     360      125911 :     SWRECTFN ( this )
     361             : 
     362             :     // The Frame's size variable is incremented by Grow or decremented by Shrink.
     363             :     // If the size cannot change, nothing should happen!
     364      125911 :     if( nChgHght >= 0)
     365             :     {
     366      125019 :         SwTwips nChgHeight = nChgHght;
     367      125019 :         if( nChgHght && !bHasToFit )
     368             :         {
     369       73287 :             if( IsInFtn() && !IsInSct() )
     370             :             {
     371         194 :                 SwTwips nReal = Grow( nChgHght, true );
     372         194 :                 if( nReal < nChgHght )
     373             :                 {
     374           0 :                     SwTwips nBot = (*fnRect->fnYInc)( (Frm().*fnRect->fnGetBottom)(),
     375           0 :                                                       nChgHght - nReal );
     376           0 :                     SwFrm* pCont = FindFtnFrm()->GetUpper();
     377             : 
     378           0 :                     if( (pCont->Frm().*fnRect->fnBottomDist)( nBot ) > 0 )
     379             :                     {
     380           0 :                         (Frm().*fnRect->fnAddBottom)( nChgHght );
     381           0 :                         if( bVert )
     382           0 :                             Prt().SSize().Width() += nChgHght;
     383             :                         else
     384           0 :                             Prt().SSize().Height() += nChgHght;
     385           0 :                         UNDO_SWAP( this )
     386           0 :                         return;
     387             :                     }
     388             :                 }
     389             :             }
     390             : 
     391       73287 :             Grow( nChgHght );
     392             : 
     393       73287 :             if ( IsInFly() )
     394             :             {
     395             :                 // If one of the Upper is a Fly, it's very likely that this fly changes its
     396             :                 // position by the Grow. Therefore, my position has to be corrected also or
     397             :                 // the check further down is not meaningful.
     398             :                 // The predecessors need to be calculated, so that the position can be
     399             :                 // calculated correctly.
     400        4126 :                 if ( GetPrev() )
     401             :                 {
     402        1110 :                     SwFrm *pPre = GetUpper()->Lower();
     403        6460 :                     do
     404        6460 :                     {   pPre->Calc();
     405        6460 :                         pPre = pPre->GetNext();
     406        6460 :                     } while ( pPre && pPre != this );
     407             :                 }
     408        4126 :                 const Point aOldPos( Frm().Pos() );
     409        4126 :                 MakePos();
     410        4126 :                 if ( aOldPos != Frm().Pos() )
     411             :                 {
     412             :                     // OD 2004-07-01 #i28701# - use new method <SwFrm::InvalidateObjs(..)>
     413             :                     // No format is performed for the floating screen objects.
     414          10 :                     InvalidateObjs( true );
     415             :                 }
     416             :             }
     417       73287 :             nChgHeight = 0;
     418             :         }
     419             :         // A Grow() is always accepted by the Layout, even if the
     420             :         // FixSize of the surrounding layout frame should not allow it.
     421             :         // We text for this case and correct the values.
     422             :         // The Frm must NOT be shrinked further than its size permits
     423             :         // even in the case of an emergency.
     424             :         SwTwips nRstHeight;
     425      125019 :         if ( IsVertical() )
     426             :         {
     427             :             OSL_ENSURE( ! IsSwapped(),"Swapped frame while calculating nRstHeight" );
     428             : 
     429           4 :             if ( IsVertLR() )
     430           0 :                     nRstHeight = GetUpper()->Frm().Left()
     431           0 :                                + GetUpper()->Prt().Left()
     432           0 :                                + GetUpper()->Prt().Width()
     433           0 :                                - Frm().Left();
     434             :             else
     435           4 :                 nRstHeight = Frm().Left() + Frm().Width() -
     436           4 :                             ( GetUpper()->Frm().Left() + GetUpper()->Prt().Left() );
     437             :          }
     438             :         else
     439      125015 :             nRstHeight = GetUpper()->Frm().Top()
     440      125015 :                        + GetUpper()->Prt().Top()
     441      125015 :                        + GetUpper()->Prt().Height()
     442      125015 :                        - Frm().Top();
     443             : 
     444             :         // We can get a bit of space in table cells, because there could be some
     445             :         // left through a vertical alignment to the top.
     446             :         // #115759# - assure, that first lower in upper
     447             :         // is the current one or is valid.
     448      187745 :         if ( IsInTab() &&
     449       35122 :              ( GetUpper()->Lower() == this ||
     450        3730 :                GetUpper()->Lower()->IsValid() ) )
     451             :         {
     452       62668 :             long nAdd = (*fnRect->fnYDiff)( (GetUpper()->Lower()->Frm().*fnRect->fnGetTop)(),
     453       94002 :                                             (GetUpper()->*fnRect->fnGetPrtTop)() );
     454             :             OSL_ENSURE( nAdd >= 0, "Ey" );
     455       31334 :             nRstHeight += nAdd;
     456             :         }
     457             : 
     458             :         // nRstHeight < 0 means that the TxtFrm is located completely outside of its Upper.
     459             :         // This can happen, if it's located within a FlyAtCntFrm, which changed sides by a
     460             :         // Grow(). In such a case, it's wrong to execute the following Grow().
     461             :         // In the case of a bug, we end up with an infinite loop.
     462      125019 :         SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
     463      125019 :         SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
     464             : 
     465      125019 :         if( nRstHeight < nFrmHeight )
     466             :         {
     467             :             // It can be that I have the right size, but the Upper is too small and can get me some room
     468       14018 :             if( ( nRstHeight >= 0 || ( IsInFtn() && IsInSct() ) ) && !bHasToFit )
     469       13856 :                 nRstHeight += GetUpper()->Grow( nFrmHeight - nRstHeight );
     470             :             // In column sections we do not want to get too big or else more areas are created by
     471             :             // GetNextSctLeaf. Instead, we shrink and remember bUndersized, so that FormatWidthCols
     472             :             // can calculate the right column size.
     473       14018 :             if ( nRstHeight < nFrmHeight )
     474             :             {
     475       28732 :                 if( bHasToFit || !IsMoveable() ||
     476        6816 :                     ( IsInSct() && !FindSctFrm()->MoveAllowed(this) ) )
     477             :                 {
     478       11036 :                     SetUndersized( true );
     479       11036 :                     Shrink( std::min( ( nFrmHeight - nRstHeight), nPrtHeight ) );
     480             :                 }
     481             :                 else
     482        2976 :                     SetUndersized( false );
     483             :             }
     484             :         }
     485      111001 :         else if( nChgHeight )
     486             :         {
     487           0 :             if( nRstHeight - nFrmHeight < nChgHeight )
     488           0 :                 nChgHeight = nRstHeight - nFrmHeight;
     489           0 :             if( nChgHeight )
     490           0 :                 Grow( nChgHeight );
     491             :         }
     492             :     }
     493             :     else
     494         892 :         Shrink( -nChgHght );
     495             : 
     496      125911 :     UNDO_SWAP( this )
     497             : }
     498             : 
     499           0 : com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > SwTxtFrm::GetTabStopInfo( SwTwips CurrentPos )
     500             : {
     501           0 :     com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > tabs(1);
     502           0 :     ::com::sun::star::style::TabStop ts;
     503             : 
     504           0 :     SwTxtFormatInfo     aInf( this );
     505           0 :     SwTxtFormatter      aLine( this, &aInf );
     506           0 :     SwTxtCursor         TxtCursor( this, &aInf );
     507           0 :     const Point aCharPos( TxtCursor.GetTopLeft() );
     508             : 
     509           0 :     SwTwips nRight = aLine.Right();
     510           0 :     CurrentPos -= aCharPos.X();
     511             : 
     512             :     // get current tab stop information stored in the Frm
     513           0 :     const SvxTabStop *pTS = aLine.GetLineInfo().GetTabStop( CurrentPos, nRight );
     514             : 
     515           0 :     if( !pTS )
     516             :     {
     517           0 :         return com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop >();
     518             :     }
     519             : 
     520             :     // copy tab stop information into a Sequence, which only contains one element.
     521           0 :     ts.Position = pTS->GetTabPos();
     522           0 :     ts.DecimalChar = pTS->GetDecimal();
     523           0 :     ts.FillChar = pTS->GetFill();
     524           0 :     switch( pTS->GetAdjustment() )
     525             :     {
     526           0 :     case SVX_TAB_ADJUST_LEFT   : ts.Alignment = ::com::sun::star::style::TabAlign_LEFT; break;
     527           0 :     case SVX_TAB_ADJUST_CENTER : ts.Alignment = ::com::sun::star::style::TabAlign_CENTER; break;
     528           0 :     case SVX_TAB_ADJUST_RIGHT  : ts.Alignment = ::com::sun::star::style::TabAlign_RIGHT; break;
     529           0 :     case SVX_TAB_ADJUST_DECIMAL: ts.Alignment = ::com::sun::star::style::TabAlign_DECIMAL; break;
     530           0 :     case SVX_TAB_ADJUST_DEFAULT: ts.Alignment = ::com::sun::star::style::TabAlign_DEFAULT; break;
     531           0 :     default: break; // prevent warning
     532             :     }
     533             : 
     534           0 :     tabs[0] = ts;
     535           0 :     return tabs;
     536             : }
     537             : 
     538             : // AdjustFollow expects the following situation:
     539             : // The SwTxtIter points to the lower end of the Master, the Offset is set in the Follow.
     540             : // nOffset holds the Offset in the text string, from which the Master closes
     541             : // and the Follow starts.
     542             : // If it's 0, the FollowFrame is deleted.
     543        3465 : void SwTxtFrm::_AdjustFollow( SwTxtFormatter &rLine,
     544             :                              const sal_Int32 nOffset, const sal_Int32 nEnd,
     545             :                              const sal_uInt8 nMode )
     546             : {
     547        3465 :     SwFrmSwapper aSwapper( this, false );
     548             : 
     549             :     // We got the rest of the text mass: Delete all Follows
     550             :     // DummyPortions() are a special case.
     551             :     // Special cases are controlled by parameter <nMode>.
     552        3465 :     if( HasFollow() && !(nMode & 1) && nOffset == nEnd )
     553             :     {
     554        2778 :         while( GetFollow() )
     555             :         {
     556         926 :             if( ((SwTxtFrm*)GetFollow())->IsLocked() )
     557             :             {
     558             :                 OSL_FAIL( "+SwTxtFrm::JoinFrm: Follow is locked." );
     559           0 :                 return;
     560             :             }
     561         926 :             JoinFrm();
     562             :         }
     563             : 
     564         926 :         return;
     565             :     }
     566             : 
     567             :     // Dancing on the volcano: We'll just format the last line quickly
     568             :     // for the QuoVadis stuff.
     569             :     // The Offset can move of course:
     570        3049 :     const sal_Int32 nNewOfst = ( IsInFtn() && ( !GetIndNext() || HasFollow() ) ) ?
     571        2979 :                             rLine.FormatQuoVadis(nOffset) : nOffset;
     572             : 
     573        2539 :     if( !(nMode & 1) )
     574             :     {
     575             :         // We steal text mass from our Follows
     576             :         // It can happen that we have to join some of them
     577        1435 :         while( GetFollow() && GetFollow()->GetFollow() &&
     578          17 :                nNewOfst >= GetFollow()->GetFollow()->GetOfst() )
     579             :         {
     580           0 :             JoinFrm();
     581             :         }
     582             :     }
     583             : 
     584             :     // The Offset moved
     585        2539 :     if( GetFollow() )
     586             :     {
     587             : #if OSL_DEBUG_LEVEL > 1
     588             :         static bool bTest = false;
     589             :         if( !bTest || ( nMode & 1 ) )
     590             : #endif
     591        2029 :         if ( nMode )
     592        1830 :             GetFollow()->ManipOfst( 0 );
     593             : 
     594        2029 :         if ( CalcFollow( nNewOfst ) )   // CalcFollow only at the end, we do a SetOfst there
     595           0 :             rLine.SetOnceMore( true );
     596        2539 :     }
     597             : }
     598             : 
     599         926 : SwCntntFrm *SwTxtFrm::JoinFrm()
     600             : {
     601             :     OSL_ENSURE( GetFollow(), "+SwTxtFrm::JoinFrm: no follow" );
     602         926 :     SwTxtFrm  *pFoll = GetFollow();
     603             : 
     604         926 :     SwTxtFrm *pNxt = pFoll->GetFollow();
     605             : 
     606             :     // All footnotes of the to-be-destroyed Follow are relocated to us
     607         926 :     sal_Int32 nStart = pFoll->GetOfst();
     608         926 :     if ( pFoll->HasFtn() )
     609             :     {
     610           0 :         const SwpHints *pHints = pFoll->GetTxtNode()->GetpSwpHints();
     611           0 :         if( pHints )
     612             :         {
     613           0 :             SwFtnBossFrm *pFtnBoss = 0;
     614           0 :             SwFtnBossFrm *pEndBoss = 0;
     615           0 :             for ( size_t i = 0; i < pHints->Count(); ++i )
     616             :             {
     617           0 :                 const SwTxtAttr *pHt = (*pHints)[i];
     618           0 :                 if( RES_TXTATR_FTN==pHt->Which() && pHt->GetStart()>=nStart )
     619             :                 {
     620           0 :                     if( pHt->GetFtn().IsEndNote() )
     621             :                     {
     622           0 :                         if( !pEndBoss )
     623           0 :                             pEndBoss = pFoll->FindFtnBossFrm();
     624           0 :                         pEndBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
     625             :                     }
     626             :                     else
     627             :                     {
     628           0 :                         if( !pFtnBoss )
     629           0 :                             pFtnBoss = pFoll->FindFtnBossFrm( true );
     630           0 :                         pFtnBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
     631             :                     }
     632           0 :                     SetFtn( true );
     633             :                 }
     634             :             }
     635             :         }
     636             :     }
     637             : 
     638             : #ifdef DBG_UTIL
     639             :     else if ( pFoll->GetValidPrtAreaFlag() ||
     640             :               pFoll->GetValidSizeFlag() )
     641             :     {
     642             :         pFoll->CalcFtnFlag();
     643             :         OSL_ENSURE( !pFoll->HasFtn(), "Missing FtnFlag." );
     644             :     }
     645             : #endif
     646             : 
     647         926 :     pFoll->MoveFlyInCnt( this, nStart, COMPLETE_STRING );
     648         926 :     pFoll->SetFtn( false );
     649             :     // #i27138#
     650             :     // notify accessibility paragraphs objects about changed CONTENT_FLOWS_FROM/_TO relation.
     651             :     // Relation CONTENT_FLOWS_FROM for current next paragraph will change
     652             :     // and relation CONTENT_FLOWS_TO for current previous paragraph, which
     653             :     // is <this>, will change.
     654             :     {
     655         926 :         SwViewShell* pViewShell( pFoll->getRootFrm()->GetCurrShell() );
     656        1852 :         if ( pViewShell && pViewShell->GetLayout() &&
     657         926 :              pViewShell->GetLayout()->IsAnyShellAccessible() )
     658             :         {
     659             :             pViewShell->InvalidateAccessibleParaFlowRelation(
     660           0 :                             dynamic_cast<SwTxtFrm*>(pFoll->FindNextCnt( true )),
     661           0 :                             this );
     662             :         }
     663             :     }
     664         926 :     pFoll->Cut();
     665         926 :     SetFollow(pNxt);
     666         926 :     delete pFoll;
     667         926 :     return pNxt;
     668             : }
     669             : 
     670        1238 : SwCntntFrm *SwTxtFrm::SplitFrm( const sal_Int32 nTxtPos )
     671             : {
     672        1238 :     SWAP_IF_SWAPPED( this )
     673             : 
     674             :     // The Paste sends a Modify() to me
     675             :     // I lock myself, so that my data does not disappear
     676        1238 :     SwTxtFrmLocker aLock( this );
     677        1238 :     SwTxtFrm *pNew = (SwTxtFrm *)(GetTxtNode()->MakeFrm( this ));
     678             : 
     679        1238 :     pNew->SetFollow( GetFollow() );
     680        1238 :     SetFollow( pNew );
     681             : 
     682        1238 :     pNew->Paste( GetUpper(), GetNext() );
     683             :     // #i27138#
     684             :     // notify accessibility paragraphs objects about changed CONTENT_FLOWS_FROM/_TO relation.
     685             :     // Relation CONTENT_FLOWS_FROM for current next paragraph will change
     686             :     // and relation CONTENT_FLOWS_TO for current previous paragraph, which
     687             :     // is <this>, will change.
     688             :     {
     689        1238 :         SwViewShell* pViewShell( pNew->getRootFrm()->GetCurrShell() );
     690        2476 :         if ( pViewShell && pViewShell->GetLayout() &&
     691        1238 :              pViewShell->GetLayout()->IsAnyShellAccessible() )
     692             :         {
     693             :             pViewShell->InvalidateAccessibleParaFlowRelation(
     694           0 :                             dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )),
     695           0 :                             this );
     696             :         }
     697             :     }
     698             : 
     699             :     // If footnotes end up in pNew bz our actions, we need
     700             :     // to re-register them
     701        1238 :     if ( HasFtn() )
     702             :     {
     703           0 :         const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
     704           0 :         if( pHints )
     705             :         {
     706           0 :             SwFtnBossFrm *pFtnBoss = 0;
     707           0 :             SwFtnBossFrm *pEndBoss = 0;
     708           0 :             for ( size_t i = 0; i < pHints->Count(); ++i )
     709             :             {
     710           0 :                 const SwTxtAttr *pHt = (*pHints)[i];
     711           0 :                 if( RES_TXTATR_FTN==pHt->Which() && pHt->GetStart()>=nTxtPos )
     712             :                 {
     713           0 :                     if( pHt->GetFtn().IsEndNote() )
     714             :                     {
     715           0 :                         if( !pEndBoss )
     716           0 :                             pEndBoss = FindFtnBossFrm();
     717           0 :                         pEndBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
     718             :                     }
     719             :                     else
     720             :                     {
     721           0 :                         if( !pFtnBoss )
     722           0 :                             pFtnBoss = FindFtnBossFrm( true );
     723           0 :                         pFtnBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
     724             :                     }
     725           0 :                     pNew->SetFtn( true );
     726             :                 }
     727             :             }
     728             :         }
     729             :     }
     730             : 
     731             : #ifdef DBG_UTIL
     732             :     else
     733             :     {
     734             :         CalcFtnFlag( nTxtPos-1 );
     735             :         OSL_ENSURE( !HasFtn(), "Missing FtnFlag." );
     736             :     }
     737             : #endif
     738             : 
     739        1238 :     MoveFlyInCnt( pNew, nTxtPos, COMPLETE_STRING );
     740             : 
     741             :     // No SetOfst or CalcFollow, because an AdjustFollow follows immediately anyways
     742             : 
     743        1238 :     pNew->ManipOfst( nTxtPos );
     744             : 
     745        1238 :     UNDO_SWAP( this )
     746        1238 :     return pNew;
     747             : }
     748             : 
     749        1962 : void SwTxtFrm::_SetOfst( const sal_Int32 nNewOfst )
     750             : {
     751             :     // We do not need to invalidate out Follow.
     752             :     // We are a Follow, get formatted right away and call
     753             :     // SetOfst() from there
     754        1962 :     nOfst = nNewOfst;
     755        1962 :     SwParaPortion *pPara = GetPara();
     756        1962 :     if( pPara )
     757             :     {
     758         664 :         SwCharRange &rReformat = pPara->GetReformat();
     759         664 :         rReformat.Start() = 0;
     760         664 :         rReformat.Len() = GetTxt().getLength();
     761         664 :         pPara->GetDelta() = rReformat.Len();
     762             :     }
     763        1962 :     InvalidateSize();
     764        1962 : }
     765             : 
     766       99971 : bool SwTxtFrm::CalcPreps()
     767             : {
     768             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(), "SwTxtFrm::CalcPreps with swapped frame" );
     769       99971 :     SWRECTFN( this );
     770             : 
     771       99971 :     SwParaPortion *pPara = GetPara();
     772       99971 :     if ( !pPara )
     773       70703 :         return false;
     774       29268 :     const bool bPrep = pPara->IsPrep();
     775       29268 :     const bool bPrepWidows = pPara->IsPrepWidows();
     776       29268 :     const bool bPrepAdjust = pPara->IsPrepAdjust();
     777       29268 :     const bool bPrepMustFit = pPara->IsPrepMustFit();
     778       29268 :     ResetPreps();
     779             : 
     780       29268 :     bool bRet = false;
     781       29268 :     if( bPrep && !pPara->GetReformat().Len() )
     782             :     {
     783             :         // PREP_WIDOWS means that the orphans rule got activated in the Follow.
     784             :         // In unfortunate cases we could also have a PrepAdjust!
     785       15187 :         if( bPrepWidows )
     786             :         {
     787         282 :             if( !GetFollow() )
     788             :             {
     789             :                 OSL_ENSURE( GetFollow(), "+SwTxtFrm::CalcPreps: no credits" );
     790           0 :                 return false;
     791             :             }
     792             : 
     793             :             // We need to prepare for two cases:
     794             :             // We were able to hand over a few lines to the Follow
     795             :             // -> we need to shrink
     796             :             // or we need to go on the next page
     797             :             // -> we let our Frame become too big
     798             : 
     799         282 :             SwTwips nChgHeight = GetParHeight();
     800         282 :             if( nChgHeight >= (Prt().*fnRect->fnGetHeight)() )
     801             :             {
     802         248 :                 if( bPrepMustFit )
     803             :                 {
     804           0 :                     GetFollow()->SetJustWidow( true );
     805           0 :                     GetFollow()->Prepare( PREP_CLEAR );
     806             :                 }
     807         248 :                 else if ( bVert )
     808             :                 {
     809           0 :                     Frm().Width( Frm().Width() + Frm().Left() );
     810           0 :                     Prt().Width( Prt().Width() + Frm().Left() );
     811           0 :                     Frm().Left( 0 );
     812           0 :                     SetWidow( true );
     813             :                 }
     814             :                 else
     815             :                 {
     816         248 :                     SwTwips nTmp  = LONG_MAX - (Frm().Top()+10000);
     817         248 :                     SwTwips nDiff = nTmp - Frm().Height();
     818         248 :                     Frm().Height( nTmp );
     819         248 :                     Prt().Height( Prt().Height() + nDiff );
     820         248 :                     SetWidow( true );
     821             :                 }
     822             :             }
     823             :             else
     824             :             {
     825             :                 OSL_ENSURE( nChgHeight < (Prt().*fnRect->fnGetHeight)(),
     826             :                         "+SwTxtFrm::CalcPrep: wanna shrink" );
     827             : 
     828          34 :                 nChgHeight = (Prt().*fnRect->fnGetHeight)() - nChgHeight;
     829             : 
     830          34 :                 GetFollow()->SetJustWidow( true );
     831          34 :                 GetFollow()->Prepare( PREP_CLEAR );
     832          34 :                 Shrink( nChgHeight );
     833          34 :                 SwRect &rRepaint = pPara->GetRepaint();
     834             : 
     835          34 :                 if ( bVert )
     836             :                 {
     837           0 :                     SwRect aRepaint( Frm().Pos() + Prt().Pos(), Prt().SSize() );
     838           0 :                     SwitchVerticalToHorizontal( aRepaint );
     839           0 :                     rRepaint.Chg( aRepaint.Pos(), aRepaint.SSize() );
     840             :                 }
     841             :                 else
     842          34 :                     rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
     843             : 
     844          34 :                 if( 0 >= rRepaint.Width() )
     845           0 :                     rRepaint.Width(1);
     846             :             }
     847         282 :             bRet = true;
     848             :         }
     849       14905 :         else if ( bPrepAdjust )
     850             :         {
     851        9607 :             if ( HasFtn() )
     852             :             {
     853          32 :                 if( !CalcPrepFtnAdjust() )
     854             :                 {
     855           4 :                     if( bPrepMustFit )
     856             :                     {
     857           0 :                         SwTxtLineAccess aAccess( this );
     858           0 :                         aAccess.GetPara()->SetPrepMustFit();
     859             :                     }
     860           4 :                     return false;
     861             :                 }
     862             :             }
     863             : 
     864        9603 :             SWAP_IF_NOT_SWAPPED( this )
     865             : 
     866        9603 :             SwTxtFormatInfo aInf( this );
     867       19206 :             SwTxtFormatter aLine( this, &aInf );
     868             : 
     869        9603 :             WidowsAndOrphans aFrmBreak( this );
     870             :             // Whatever the attributes say: we split the paragraph in
     871             :             // MustFit in any case
     872        9603 :             if( bPrepMustFit )
     873             :             {
     874         486 :                 aFrmBreak.SetKeep( false );
     875         486 :                 aFrmBreak.ClrOrphLines();
     876             :             }
     877             :             // Before calling FormatAdjust, we need to make sure
     878             :             // that the lines protruding at the bottom get indeed
     879             :             // truncated
     880        9603 :             bool bBreak = aFrmBreak.IsBreakNowWidAndOrp( aLine );
     881        9603 :             bRet = true;
     882       23599 :             while( !bBreak && aLine.Next() )
     883             :             {
     884        4393 :                 bBreak = aFrmBreak.IsBreakNowWidAndOrp( aLine );
     885             :             }
     886        9603 :             if( bBreak )
     887             :             {
     888             :                 // We run into troubles: when TruncLines get called, the
     889             :                 // conditions in IsInside change immediately such that
     890             :                 // IsBreakNow can return different results.
     891             :                 // For this reason, we make it clear to rFrmBreak, that the
     892             :                 // end is reached at the location of rLine.
     893             :                 // Let's see if it works ...
     894         702 :                 aLine.TruncLines();
     895         702 :                 aFrmBreak.SetRstHeight( aLine );
     896         702 :                 FormatAdjust( aLine, aFrmBreak, aInf.GetTxt().getLength(), aInf.IsStop() );
     897             :             }
     898             :             else
     899             :             {
     900        8901 :                 if( !GetFollow() )
     901             :                 {
     902             :                     FormatAdjust( aLine, aFrmBreak,
     903        8618 :                                   aInf.GetTxt().getLength(), aInf.IsStop() );
     904             :                 }
     905         283 :                 else if ( !aFrmBreak.IsKeepAlways() )
     906             :                 {
     907             :                     // We delete a line before the Master, because the Follow
     908             :                     // could hand over a line
     909         265 :                     const SwCharRange aFollowRg( GetFollow()->GetOfst(), 1 );
     910         265 :                     pPara->GetReformat() += aFollowRg;
     911             :                     // We should continue!
     912         265 :                     bRet = false;
     913             :                 }
     914             :             }
     915             : 
     916        9603 :             UNDO_SWAP( this )
     917             :             // A final check, if FormatAdjust() didn't help we need to
     918             :             // truncate
     919        9603 :             if( bPrepMustFit )
     920             :             {
     921         486 :                 const SwTwips nMust = (GetUpper()->*fnRect->fnGetPrtBottom)();
     922         486 :                 const SwTwips nIs   = (Frm().*fnRect->fnGetBottom)();
     923             : 
     924         486 :                 if( bVert && nIs < nMust )
     925             :                 {
     926           0 :                     Shrink( nMust - nIs );
     927           0 :                     if( Prt().Width() < 0 )
     928           0 :                         Prt().Width( 0 );
     929           0 :                     SetUndersized( true );
     930             :                 }
     931         486 :                 else if ( ! bVert && nIs > nMust )
     932             :                 {
     933         480 :                     Shrink( nIs - nMust );
     934         480 :                     if( Prt().Height() < 0 )
     935           0 :                         Prt().Height( 0 );
     936         480 :                     SetUndersized( true );
     937             :                 }
     938        9603 :             }
     939             :         }
     940             :     }
     941       29264 :     pPara->SetPrepMustFit( bPrepMustFit );
     942       29264 :     return bRet;
     943             : }
     944             : 
     945             : // We rewire the footnotes and the character bound objects
     946             : #define CHG_OFFSET( pFrm, nNew )\
     947             :     {\
     948             :         if( pFrm->GetOfst() < nNew )\
     949             :             pFrm->MoveFlyInCnt( this, 0, nNew );\
     950             :         else if( pFrm->GetOfst() > nNew )\
     951             :             MoveFlyInCnt( pFrm, nNew, COMPLETE_STRING );\
     952             :     }
     953             : 
     954       91923 : void SwTxtFrm::FormatAdjust( SwTxtFormatter &rLine,
     955             :                              WidowsAndOrphans &rFrmBreak,
     956             :                              const sal_Int32 nStrLen,
     957             :                              const bool bDummy )
     958             : {
     959       91923 :     SWAP_IF_NOT_SWAPPED( this )
     960             : 
     961       91923 :     SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
     962             : 
     963       91923 :     sal_Int32 nEnd = rLine.GetStart();
     964             : 
     965       91923 :     const bool bHasToFit = pPara->IsPrepMustFit();
     966             : 
     967             :     // The StopFlag is set by footnotes which want to go onto the next page
     968             :     // Call base class method <SwTxtFrmBreak::IsBreakNow(..)>
     969             :     // instead of method <WidowsAndOrphans::IsBreakNow(..)> to get a break,
     970             :     // even if due to widow rule no enough lines exists.
     971      182129 :     sal_uInt8 nNew = ( !GetFollow() &&
     972       65761 :                        nEnd < nStrLen &&
     973      131522 :                        ( rLine.IsStop() ||
     974             :                          ( bHasToFit
     975           0 :                            ? ( rLine.GetLineNr() > 1 &&
     976           0 :                                !rFrmBreak.IsInside( rLine ) )
     977       65761 :                            : rFrmBreak.IsBreakNow( rLine ) ) ) )
     978      158930 :                      ? 1 : 0;
     979             :     // --> OD #i84870#
     980             :     // no split of text frame, which only contains a as-character anchored object
     981             :     bool bOnlyContainsAsCharAnchoredObj =
     982      186981 :             !IsFollow() && nStrLen == 1 &&
     983      104073 :             GetDrawObjs() && GetDrawObjs()->size() == 1 &&
     984       94601 :             (*GetDrawObjs())[0]->GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR;
     985             : 
     986             :     // Still try split text frame if we have columns.
     987       91923 :     if (FindColFrm())
     988        9128 :         bOnlyContainsAsCharAnchoredObj = false;
     989             : 
     990       91923 :     if ( nNew && bOnlyContainsAsCharAnchoredObj )
     991             :     {
     992           8 :         nNew = 0;
     993             :     }
     994             :     // <--
     995       91923 :     if ( nNew )
     996             :     {
     997        1238 :         SplitFrm( nEnd );
     998             :     }
     999             : 
    1000       91923 :     const SwFrm *pBodyFrm = (const SwFrm*)(FindBodyFrm());
    1001             : 
    1002       68300 :     const long nBodyHeight = pBodyFrm ? ( IsVertical() ?
    1003           2 :                                           pBodyFrm->Frm().Width() :
    1004      160225 :                                           pBodyFrm->Frm().Height() ) : 0;
    1005             : 
    1006             :     // If the current values have been calculated, show that they
    1007             :     // are valid now
    1008       91923 :     pPara->GetReformat() = SwCharRange();
    1009       91923 :     bool bDelta = pPara->GetDelta() != 0;
    1010       91923 :     pPara->GetDelta() = 0;
    1011             : 
    1012       91923 :     if( rLine.IsStop() )
    1013             :     {
    1014           0 :         rLine.TruncLines( true );
    1015           0 :         nNew = 1;
    1016             :     }
    1017             : 
    1018             :     // FindBreak truncates the last line
    1019       91923 :     if( !rFrmBreak.FindBreak( this, rLine, bHasToFit ) )
    1020             :     {
    1021             :         // If we're done formatting, we set nEnd to the end.
    1022             :         // AdjustFollow might execute JoinFrm() because of this.
    1023             :         // Else, nEnd is the end of the last line in the Master.
    1024       90466 :         sal_Int32 nOld = nEnd;
    1025       90466 :         nEnd = rLine.GetEnd();
    1026       90466 :         if( GetFollow() )
    1027             :         {
    1028        1500 :             if( nNew && nOld < nEnd )
    1029         566 :                 RemoveFtn( nOld, nEnd - nOld );
    1030        1500 :             CHG_OFFSET( GetFollow(), nEnd )
    1031        1500 :             if( !bDelta )
    1032         542 :                 GetFollow()->ManipOfst( nEnd );
    1033             :         }
    1034             :     }
    1035             :     else
    1036             :     {   // If we pass over lines, we must not call Join in Follows, instead we even
    1037             :         // need to create a Follow.
    1038             :         // We also need to do this if the whole mass of text remains in the Master,
    1039             :         // because a hard line break could necessitate another line (without text mass)!
    1040        1457 :         nEnd = rLine.GetEnd();
    1041        1457 :         if( GetFollow() )
    1042             :         {
    1043             :             // Another case for not joining the follow:
    1044             :             // Text frame has no content, but a numbering. Then, do *not* join.
    1045             :             // Example of this case: When an empty, but numbered paragraph
    1046             :             // at the end of page is completely displaced by a fly frame.
    1047             :             // Thus, the text frame introduced a follow by a
    1048             :             // <SwTxtFrm::SplitFrm(..)> - see below. The follow then shows
    1049             :             // the numbering and must stay.
    1050        3773 :             if ( GetFollow()->GetOfst() != nEnd ||
    1051        2910 :                  GetFollow()->IsFieldFollow() ||
    1052           0 :                  ( nStrLen == 0 && GetTxtNode()->GetNumRule() ) )
    1053             :             {
    1054         592 :                 nNew |= 3;
    1055             :             }
    1056        1455 :             CHG_OFFSET( GetFollow(), nEnd )
    1057        1455 :             GetFollow()->ManipOfst( nEnd );
    1058             :         }
    1059             :         else
    1060             :         {
    1061             :             // Only split frame, if the frame contains
    1062             :             // content or contains no content, but has a numbering.
    1063             :             // OD #i84870# - no split, if text frame only contains one
    1064             :             // as-character anchored object.
    1065           2 :             if ( !bOnlyContainsAsCharAnchoredObj &&
    1066           2 :                  ( nStrLen > 0 ||
    1067           2 :                    ( nStrLen == 0 && GetTxtNode()->GetNumRule() ) )
    1068             :                )
    1069             :             {
    1070           0 :                 SplitFrm( nEnd );
    1071           0 :                 nNew |= 3;
    1072             :             }
    1073             :         }
    1074             :         // If the remaining height changed e.g by RemoveFtn() we need to
    1075             :         // fill up in order to avoid oscillation.
    1076        1457 :         if( bDummy && pBodyFrm &&
    1077           0 :            nBodyHeight < ( IsVertical() ?
    1078           0 :                            pBodyFrm->Frm().Width() :
    1079           0 :                            pBodyFrm->Frm().Height() ) )
    1080           0 :             rLine.MakeDummyLine();
    1081             :     }
    1082             : 
    1083             :     // In AdjustFrm() we set ourselves via Grow/Shrink
    1084             :     // In AdjustFollow() we set our FollowFrame
    1085             : 
    1086       91923 :     const SwTwips nDocPrtTop = Frm().Top() + Prt().Top();
    1087       91923 :     const SwTwips nOldHeight = Prt().SSize().Height();
    1088       91923 :     SwTwips nChg = rLine.CalcBottomLine() - nDocPrtTop - nOldHeight;
    1089             : 
    1090             :     // Vertical Formatting:
    1091             :     // The (rotated) repaint rectangle's x coordinate referes to the frame.
    1092             :     // If the frame grows (or shirks) the repaint rectangle cannot simply
    1093             :     // be rotated back after formatting, because we use the upper left point
    1094             :     // of the frame for rotation. This point changes when growing/shrinking.
    1095             : 
    1096       91923 :     if ( IsVertical() && !IsVertLR() && nChg )
    1097             :     {
    1098           2 :         SwRect &rRepaint = pPara->GetRepaint();
    1099           2 :         rRepaint.Left( rRepaint.Left() - nChg );
    1100           2 :         rRepaint.Width( rRepaint.Width() - nChg );
    1101             :     }
    1102             : 
    1103       91923 :     AdjustFrm( nChg, bHasToFit );
    1104             : 
    1105       91923 :     if( HasFollow() || IsInFtn() )
    1106        3465 :         _AdjustFollow( rLine, nEnd, nStrLen, nNew );
    1107             : 
    1108       91923 :     pPara->SetPrepMustFit( false );
    1109             : 
    1110       91923 :     UNDO_SWAP( this )
    1111       91923 : }
    1112             : 
    1113             : // bPrev is set whether Reformat.Start() was called because of Prev().
    1114             : // Else, wo don't know whether we can limit the repaint or not.
    1115      136772 : bool SwTxtFrm::FormatLine( SwTxtFormatter &rLine, const bool bPrev )
    1116             : {
    1117             :     OSL_ENSURE( ! IsVertical() || IsSwapped(),
    1118             :             "SwTxtFrm::FormatLine( rLine, bPrev) with unswapped frame" );
    1119      136772 :     SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
    1120      136772 :     const SwLineLayout *pOldCur = rLine.GetCurr();
    1121      136772 :     const sal_Int32 nOldLen    = pOldCur->GetLen();
    1122      136772 :     const sal_uInt16 nOldAscent = pOldCur->GetAscent();
    1123      136772 :     const sal_uInt16 nOldHeight = pOldCur->Height();
    1124      136772 :     const SwTwips nOldWidth = pOldCur->Width() + pOldCur->GetHangingMargin();
    1125      136772 :     const bool bOldHyph = pOldCur->IsEndHyph();
    1126      136772 :     SwTwips nOldTop = 0;
    1127      136772 :     SwTwips nOldBottom = 0;
    1128      136772 :     if( rLine.GetCurr()->IsClipping() )
    1129          20 :         rLine.CalcUnclipped( nOldTop, nOldBottom );
    1130             : 
    1131      136772 :     const sal_Int32 nNewStart = rLine.FormatLine( rLine.GetStart() );
    1132             : 
    1133             :     OSL_ENSURE( Frm().Pos().Y() + Prt().Pos().Y() == rLine.GetFirstPos(),
    1134             :             "SwTxtFrm::FormatLine: frame leaves orbit." );
    1135             :     OSL_ENSURE( rLine.GetCurr()->Height(),
    1136             :             "SwTxtFrm::FormatLine: line height is zero" );
    1137             : 
    1138             :     // The current line break object
    1139      136772 :     const SwLineLayout *pNew = rLine.GetCurr();
    1140             : 
    1141      181680 :     bool bUnChg = nOldLen == pNew->GetLen() &&
    1142      181680 :                   bOldHyph == pNew->IsEndHyph();
    1143      136772 :     if ( bUnChg && !bPrev )
    1144             :     {
    1145       43751 :         const long nWidthDiff = nOldWidth > pNew->Width()
    1146         306 :                                 ? nOldWidth - pNew->Width()
    1147       44057 :                                 : pNew->Width() - nOldWidth;
    1148             : 
    1149             :         // we only declare a line as unchanged, if its main values have not
    1150             :         // changed and it is not the last line (!paragraph end symbol!)
    1151       65035 :         bUnChg = nOldHeight == pNew->Height() &&
    1152       42564 :                  nOldAscent == pNew->GetAscent() &&
    1153       64079 :                  nWidthDiff <= SLOPPY_TWIPS &&
    1154       64079 :                  pOldCur->GetNext();
    1155             :     }
    1156             : 
    1157             :     // Calculate rRepaint
    1158      136772 :     const SwTwips nBottom = rLine.Y() + rLine.GetLineHeight();
    1159      136772 :     SwRepaint &rRepaint = pPara->GetRepaint();
    1160      153547 :     if( bUnChg && rRepaint.Top() == rLine.Y()
    1161        1647 :                && (bPrev || nNewStart <= pPara->GetReformat().Start())
    1162      137927 :                && (nNewStart < GetTxtNode()->GetTxt().getLength()))
    1163             :     {
    1164        1153 :         rRepaint.Top( nBottom );
    1165        1153 :         rRepaint.Height( 0 );
    1166             :     }
    1167             :     else
    1168             :     {
    1169      135619 :         if( nOldTop )
    1170             :         {
    1171          20 :             if( nOldTop < rRepaint.Top() )
    1172          20 :                 rRepaint.Top( nOldTop );
    1173          20 :             if( !rLine.IsUnclipped() || nOldBottom > rRepaint.Bottom() )
    1174             :             {
    1175          20 :                 rRepaint.Bottom( nOldBottom - 1 );
    1176          20 :                 rLine.SetUnclipped( true );
    1177             :             }
    1178             :         }
    1179      135619 :         if( rLine.GetCurr()->IsClipping() && rLine.IsFlyInCntBase() )
    1180             :         {
    1181             :             SwTwips nTmpTop, nTmpBottom;
    1182        1438 :             rLine.CalcUnclipped( nTmpTop, nTmpBottom );
    1183        1438 :             if( nTmpTop < rRepaint.Top() )
    1184         210 :                 rRepaint.Top( nTmpTop );
    1185        1438 :             if( !rLine.IsUnclipped() || nTmpBottom > rRepaint.Bottom() )
    1186             :             {
    1187        1438 :                 rRepaint.Bottom( nTmpBottom - 1 );
    1188        1438 :                 rLine.SetUnclipped( true );
    1189             :             }
    1190             :         }
    1191             :         else
    1192             :         {
    1193      134181 :             if( !rLine.IsUnclipped() || nBottom > rRepaint.Bottom() )
    1194             :             {
    1195      134181 :                 rRepaint.Bottom( nBottom - 1 );
    1196      134181 :                 rLine.SetUnclipped( false );
    1197             :             }
    1198             :         }
    1199      271238 :         SwTwips nRght = std::max( nOldWidth, pNew->Width() +
    1200      271238 :                              pNew->GetHangingMargin() );
    1201      135619 :         SwViewShell *pSh = getRootFrm()->GetCurrShell();
    1202      135619 :         const SwViewOption *pOpt = pSh ? pSh->GetViewOptions() : 0;
    1203      135619 :         if( pOpt && (pOpt->IsParagraph() || pOpt->IsLineBreak()) )
    1204           0 :             nRght += ( std::max( nOldAscent, pNew->GetAscent() ) );
    1205             :         else
    1206      135619 :             nRght += ( std::max( nOldAscent, pNew->GetAscent() ) / 4);
    1207      135619 :         nRght += rLine.GetLeftMargin();
    1208      135619 :         if( rRepaint.GetOfst() || rRepaint.GetRightOfst() < nRght )
    1209       89049 :             rRepaint.SetRightOfst( nRght );
    1210             : 
    1211             :         // Finally we enlarge the repaint rectangle if we found an underscore
    1212             :         // within our line. 40 Twips should be enough
    1213             :         const bool bHasUnderscore =
    1214      135619 :                 ( rLine.GetInfo().GetUnderScorePos() < nNewStart );
    1215      135619 :         if ( bHasUnderscore || rLine.GetCurr()->HasUnderscore() )
    1216         236 :             rRepaint.Bottom( rRepaint.Bottom() + 40 );
    1217             : 
    1218      135619 :         ((SwLineLayout*)rLine.GetCurr())->SetUnderscore( bHasUnderscore );
    1219             :     }
    1220      136772 :     if( !bUnChg )
    1221      119997 :         rLine.SetChanges();
    1222             : 
    1223             :     // Calculating the good ol' nDelta
    1224      136772 :     pPara->GetDelta() -= long(pNew->GetLen()) - long(nOldLen);
    1225             : 
    1226             :     // Stop!
    1227      136772 :     if( rLine.IsStop() )
    1228           0 :         return false;
    1229             : 
    1230             :     // Absolutely another line
    1231      136772 :     if( rLine.IsNewLine() )
    1232         602 :         return true;
    1233             : 
    1234             :     // Until the String's end?
    1235      136170 :     if (nNewStart >= GetTxtNode()->GetTxt().getLength())
    1236       80404 :         return false;
    1237             : 
    1238       55766 :     if( rLine.GetInfo().IsShift() )
    1239       27252 :         return true;
    1240             : 
    1241             :     // Reached the Reformat's end?
    1242       57028 :     const sal_Int32 nEnd = pPara->GetReformat().Start() +
    1243       57028 :                         pPara->GetReformat().Len();
    1244             : 
    1245       28514 :     if( nNewStart <= nEnd )
    1246       15092 :         return true;
    1247             : 
    1248       13422 :     return 0 != pPara->GetDelta();
    1249             : }
    1250             : 
    1251       82793 : void SwTxtFrm::_Format( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf,
    1252             :                         const bool bAdjust )
    1253             : {
    1254             :     OSL_ENSURE( ! IsVertical() || IsSwapped(),"SwTxtFrm::_Format with unswapped frame" );
    1255             : 
    1256       82793 :     SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
    1257       82793 :     rLine.SetUnclipped( false );
    1258             : 
    1259             :     // That was too complicated for the C30: aString( GetTxt() );
    1260       82793 :     const OUString &rString = GetTxtNode()->GetTxt();
    1261       82793 :     const sal_Int32 nStrLen = rString.getLength();
    1262             : 
    1263       82793 :     SwCharRange &rReformat = pPara->GetReformat();
    1264       82793 :     SwRepaint   &rRepaint = pPara->GetRepaint();
    1265       82793 :     SwRepaint *pFreeze = NULL;
    1266             : 
    1267             :     // Due to performance reasons we set rReformat to COMPLETE_STRING in Init()
    1268             :     // In this case we adjust rReformat
    1269       82793 :     if( rReformat.Len() > nStrLen )
    1270       72103 :         rReformat.Len() = nStrLen;
    1271             : 
    1272             :     // Optimized:
    1273       82793 :     sal_Int32 nEnd = rReformat.Start() + rReformat.Len();
    1274       82793 :     if( nEnd > nStrLen )
    1275             :     {
    1276         134 :         rReformat.Len() = nStrLen - rReformat.Start();
    1277         134 :         nEnd = nStrLen;
    1278             :     }
    1279             : 
    1280             :     SwTwips nOldBottom;
    1281       82793 :     if( GetOfst() && !IsFollow() )
    1282             :     {
    1283           0 :         rLine.Bottom();
    1284           0 :         nOldBottom = rLine.Y();
    1285           0 :         rLine.Top();
    1286             :     }
    1287             :     else
    1288       82793 :         nOldBottom = 0;
    1289       82793 :     rLine.CharToLine( rReformat.Start() );
    1290             : 
    1291             :     // Words can be swapped-out when inserting a space into the
    1292             :     // line that comes before the edited one. That's why we also
    1293             :     // need to format that.
    1294             :     // Optimization: If rReformat starts after the first word of the line
    1295             :     // this line cannot possibly influence the previous one.
    1296             :     // Unfortunately it can: Text size changes + FlyFrames.
    1297             :     // The backlash can affect multiple lines (Frame!)!
    1298             : 
    1299             :     // #i46560#
    1300             :     // FME: Yes, consider this case: (word) has to go to the next line
    1301             :     // because) is a forbidden character at the beginning of a line although
    1302             :     // (word would still fit on the previous line. Adding text right in front
    1303             :     // of) would not trigger a reformatting of the previous line. Adding 1
    1304             :     // to the result of FindBrk() does not solve the problem in all cases,
    1305             :     // nevertheless it should be sufficient.
    1306       86957 :     bool bPrev = rLine.GetPrev() &&
    1307        2891 :                      ( FindBrk( rString, rLine.GetStart(), rReformat.Start() + 1 )
    1308             :                        // #i46560#
    1309        2891 :                        + 1
    1310        4509 :                        >= rReformat.Start() ||
    1311       84411 :                        rLine.GetCurr()->IsRest() );
    1312       82793 :     if( bPrev )
    1313             :     {
    1314        2546 :         while( rLine.Prev() )
    1315        1273 :             if( rLine.GetCurr()->GetLen() && !rLine.GetCurr()->IsRest() )
    1316             :             {
    1317        1273 :                 if( !rLine.GetStart() )
    1318          78 :                     rLine.Top(); // So that NumDone doesn't get confused
    1319        1273 :                 break;
    1320             :             }
    1321        1273 :         sal_Int32 nNew = rLine.GetStart() + rLine.GetLength();
    1322        1273 :         if( nNew )
    1323             :         {
    1324        1273 :             --nNew;
    1325        1273 :             if( CH_BREAK == rString[nNew] )
    1326             :             {
    1327          58 :                 ++nNew;
    1328          58 :                 rLine.Next();
    1329          58 :                 bPrev = false;
    1330             :             }
    1331             :         }
    1332        1273 :         rReformat.Len()  += rReformat.Start() - nNew;
    1333        1273 :         rReformat.Start() = nNew;
    1334             :     }
    1335             : 
    1336       82793 :     rRepaint.SetOfst( 0 );
    1337       82793 :     rRepaint.SetRightOfst( 0 );
    1338       82793 :     rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
    1339       82793 :     if( pPara->IsMargin() )
    1340           0 :         rRepaint.Width( rRepaint.Width() + pPara->GetHangingMargin() );
    1341       82793 :     rRepaint.Top( rLine.Y() );
    1342       82793 :     if( 0 >= rRepaint.Width() )
    1343           0 :         rRepaint.Width(1);
    1344       82793 :     WidowsAndOrphans aFrmBreak( this, rInf.IsTest() ? 1 : 0 );
    1345             : 
    1346             :     // rLine is now set to the first line which needs formatting.
    1347             :     // The bFirst flag makes sure that Next() is not called.
    1348             :     // The whole thing looks weird, but we need to make sure that
    1349             :     // rLine stops at the last non-fitting line when calling IsBreakNow.
    1350       82793 :     bool bFirst  = true;
    1351       82793 :     bool bFormat = true;
    1352             : 
    1353             :     // The CharToLine() can also get us into the danger zone.
    1354             :     // In that case we need to walk back until rLine is set
    1355             :     // to the non-fitting line. Or else the mass of text is lost,
    1356             :     // because the Ofst was set wrongly in the Follow.
    1357             : 
    1358       82831 :     bool bBreak = ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 )
    1359      165548 :                     && aFrmBreak.IsBreakNowWidAndOrp( rLine );
    1360       82793 :     if( bBreak )
    1361             :     {
    1362          60 :         bool bPrevDone = 0 != rLine.Prev();
    1363         214 :         while( bPrevDone && aFrmBreak.IsBreakNowWidAndOrp(rLine) )
    1364          94 :             bPrevDone = 0 != rLine.Prev();
    1365          60 :         if( bPrevDone )
    1366             :         {
    1367           2 :             aFrmBreak.SetKeep( false );
    1368           2 :             rLine.Next();
    1369             :         }
    1370          60 :         rLine.TruncLines();
    1371             : 
    1372             :         // Play it safe
    1373         180 :         bBreak = aFrmBreak.IsBreakNowWidAndOrp(rLine) &&
    1374         120 :                   ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 );
    1375             :     }
    1376             : 
    1377             :  /* Meaning if the following flags are set:
    1378             : 
    1379             :     Watch(End/Mid)Hyph: we need to format if we have a break at
    1380             :     the line end/Fly, as long as MaxHyph is reached
    1381             : 
    1382             :     Jump(End/Mid)Flag: the next line which has no break (line end/Fly),
    1383             :     needs to be formatted, because we could wrap now. This might have been
    1384             :     forbidden earlier by MaxHyph
    1385             : 
    1386             :     Watch(End/Mid)Hyph: if the last formatted line got a cutoff point, but
    1387             :     didn't have one before
    1388             : 
    1389             :     Jump(End/Mid)Hyph: if a cutoff point disappears
    1390             :  */
    1391       82793 :     bool bJumpEndHyph  = false;
    1392       82793 :     bool bWatchEndHyph = false;
    1393       82793 :     bool bJumpMidHyph  = false;
    1394       82793 :     bool bWatchMidHyph = false;
    1395             : 
    1396       82793 :     const SwAttrSet& rAttrSet = GetTxtNode()->GetSwAttrSet();
    1397       82793 :     bool bMaxHyph = ( 0 !=
    1398      165586 :         ( rInf.MaxHyph() = rAttrSet.GetHyphenZone().GetMaxHyphens() ) );
    1399       82793 :     if ( bMaxHyph )
    1400           2 :         rLine.InitCntHyph();
    1401             : 
    1402       82793 :     if( IsFollow() && IsFieldFollow() && rLine.GetStart() == GetOfst() )
    1403             :     {
    1404           0 :         SwTxtFrm *pMaster = FindMaster();
    1405             :         OSL_ENSURE( pMaster, "SwTxtFrm::Format: homeless follow" );
    1406           0 :         const SwLineLayout* pLine=NULL;
    1407           0 :         if (pMaster)
    1408             :         {
    1409           0 :             if( !pMaster->HasPara() )
    1410           0 :                 pMaster->GetFormatted();
    1411           0 :             SwTxtSizeInfo aInf( pMaster );
    1412           0 :             SwTxtIter aMasterLine( pMaster, &aInf );
    1413           0 :             aMasterLine.Bottom();
    1414           0 :             pLine = aMasterLine.GetCurr();
    1415             :         }
    1416             :         SwLinePortion* pRest = pLine ?
    1417           0 :             rLine.MakeRestPortion(pLine, GetOfst()) : NULL;
    1418           0 :         if( pRest )
    1419           0 :             rInf.SetRest( pRest );
    1420             :         else
    1421           0 :             SetFieldFollow( false );
    1422             :     }
    1423             : 
    1424             :     /* Ad cancel criterion:
    1425             :      * In order to recognize, whether a line does not fit onto the page
    1426             :      * anymore, we need to format it. This overflow is removed again in
    1427             :      * e.g. AdjustFollow.
    1428             :      * Another complication: if we are the Master, we need to traverse
    1429             :      * the lines, because it could happen that one line can overflow
    1430             :      * from the Follow to the Master.
    1431             :      */
    1432       54846 :     do
    1433             :     {
    1434      136772 :         if( bFirst )
    1435       82793 :             bFirst = false;
    1436             :         else
    1437             :         {
    1438       53979 :             if ( bMaxHyph )
    1439             :             {
    1440           0 :                 if ( rLine.GetCurr()->IsEndHyph() )
    1441           0 :                     rLine.CntEndHyph()++;
    1442             :                 else
    1443           0 :                     rLine.CntEndHyph() = 0;
    1444           0 :                 if ( rLine.GetCurr()->IsMidHyph() )
    1445           0 :                     rLine.CntMidHyph()++;
    1446             :                 else
    1447           0 :                     rLine.CntMidHyph() = 0;
    1448             :             }
    1449       53979 :             if( !rLine.Next() )
    1450             :             {
    1451       28496 :                 if( !bFormat )
    1452             :                 {
    1453             :                     SwLinePortion* pRest =
    1454         134 :                         rLine.MakeRestPortion( rLine.GetCurr(), rLine.GetEnd() );
    1455         134 :                     if( pRest )
    1456           0 :                         rInf.SetRest( pRest );
    1457             :                 }
    1458       28496 :                 rLine.Insert( new SwLineLayout() );
    1459       28496 :                 rLine.Next();
    1460       28496 :                 bFormat = true;
    1461             :             }
    1462             :         }
    1463      136772 :         if ( !bFormat && bMaxHyph &&
    1464           0 :               (bWatchEndHyph || bJumpEndHyph || bWatchMidHyph || bJumpMidHyph) )
    1465             :         {
    1466           0 :             if ( rLine.GetCurr()->IsEndHyph() )
    1467             :             {
    1468           0 :                 if ( bWatchEndHyph )
    1469           0 :                     bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
    1470             :             }
    1471             :             else
    1472             :             {
    1473           0 :                 bFormat = bJumpEndHyph;
    1474           0 :                 bWatchEndHyph = false;
    1475           0 :                 bJumpEndHyph = false;
    1476             :             }
    1477           0 :             if ( rLine.GetCurr()->IsMidHyph() )
    1478             :             {
    1479           0 :                 if ( bWatchMidHyph && !bFormat )
    1480           0 :                     bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
    1481             :             }
    1482             :             else
    1483             :             {
    1484           0 :                 bFormat |= bJumpMidHyph;
    1485           0 :                 bWatchMidHyph = false;
    1486           0 :                 bJumpMidHyph = false;
    1487             :             }
    1488             :         }
    1489      136772 :         if( bFormat )
    1490             :         {
    1491      136772 :             const bool bOldEndHyph = rLine.GetCurr()->IsEndHyph();
    1492      136772 :             const bool bOldMidHyph = rLine.GetCurr()->IsMidHyph();
    1493      136772 :             bFormat = FormatLine( rLine, bPrev );
    1494             :             // There can only be one bPrev ... (???)
    1495      136772 :             bPrev = false;
    1496      136772 :             if ( bMaxHyph )
    1497             :             {
    1498           2 :                 if ( rLine.GetCurr()->IsEndHyph() != bOldEndHyph )
    1499             :                 {
    1500           0 :                     bWatchEndHyph = !bOldEndHyph;
    1501           0 :                     bJumpEndHyph = bOldEndHyph;
    1502             :                 }
    1503           2 :                 if ( rLine.GetCurr()->IsMidHyph() != bOldMidHyph )
    1504             :                 {
    1505           0 :                     bWatchMidHyph = !bOldMidHyph;
    1506           0 :                     bJumpMidHyph = bOldMidHyph;
    1507             :                 }
    1508             :             }
    1509             :         }
    1510             : 
    1511      136772 :         if( !rInf.IsNewLine() )
    1512             :         {
    1513      136170 :             if( !bFormat )
    1514       82060 :                  bFormat = 0 != rInf.GetRest();
    1515      136170 :             if( rInf.IsStop() || rInf.GetIdx() >= nStrLen )
    1516       80404 :                 break;
    1517       55766 :             if( !bFormat && ( !bMaxHyph || ( !bWatchEndHyph &&
    1518           0 :                     !bJumpEndHyph && !bWatchMidHyph && !bJumpMidHyph ) ) )
    1519             :             {
    1520        1656 :                 if( GetFollow() )
    1521             :                 {
    1522         134 :                     while( rLine.Next() )
    1523             :                         ; //Nothing
    1524         134 :                     pFreeze = new SwRepaint( rRepaint ); // to minimize painting
    1525             :                 }
    1526             :                 else
    1527        1522 :                     break;
    1528             :             }
    1529             :         }
    1530       54846 :         bBreak = aFrmBreak.IsBreakNowWidAndOrp(rLine);
    1531       54846 :     }while( !bBreak );
    1532             : 
    1533       82793 :     if( pFreeze )
    1534             :     {
    1535         134 :         rRepaint = *pFreeze;
    1536         134 :         delete pFreeze;
    1537             :     }
    1538             : 
    1539       82793 :     if( !rLine.IsStop() )
    1540             :     {
    1541             :         // If we're finished formatting the text and we still
    1542             :         // have other line objects left, these are superfluous
    1543             :         // now because the text has gotten shorter.
    1544      163211 :         if( rLine.GetStart() + rLine.GetLength() >= nStrLen &&
    1545       80418 :             rLine.GetCurr()->GetNext() )
    1546             :         {
    1547         112 :             rLine.TruncLines();
    1548         112 :             rLine.SetTruncLines( true );
    1549             :         }
    1550             :     }
    1551             : 
    1552       82793 :     if( !rInf.IsTest() )
    1553             :     {
    1554             :         // FormatAdjust does not pay off at OnceMore
    1555       82615 :         if( bAdjust || !rLine.GetDropFmt() || !rLine.CalcOnceMore() )
    1556             :         {
    1557       82603 :             FormatAdjust( rLine, aFrmBreak, nStrLen, rInf.IsStop() );
    1558             :         }
    1559       82615 :         if( rRepaint.HasArea() )
    1560       82613 :             SetRepaint();
    1561       82615 :         rLine.SetTruncLines( false );
    1562       82615 :         if( nOldBottom ) // We check whether paragraphs that need scrolling can
    1563             :                          // be shrunk, so that they don't need scrolling anymore
    1564             :         {
    1565           0 :             rLine.Bottom();
    1566           0 :             SwTwips nNewBottom = rLine.Y();
    1567           0 :             if( nNewBottom < nOldBottom )
    1568           0 :                 _SetOfst( 0 );
    1569             :         }
    1570             :     }
    1571       82793 : }
    1572             : 
    1573          12 : void SwTxtFrm::FormatOnceMore( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf )
    1574             : {
    1575             :     OSL_ENSURE( ! IsVertical() || IsSwapped(),
    1576             :             "A frame is not swapped in SwTxtFrm::FormatOnceMore" );
    1577             : 
    1578          12 :     SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
    1579          12 :     if( !pPara )
    1580          12 :         return;
    1581             : 
    1582             :     // If necessary the pPara
    1583          12 :     sal_uInt16 nOld  = ((const SwTxtMargin&)rLine).GetDropHeight();
    1584          12 :     bool bShrink = false;
    1585          12 :     bool bGrow   = false;
    1586          12 :     bool bGoOn   = rLine.IsOnceMore();
    1587          12 :     sal_uInt8 nGo    = 0;
    1588          36 :     while( bGoOn )
    1589             :     {
    1590          12 :         ++nGo;
    1591          12 :         rInf.Init();
    1592          12 :         rLine.Top();
    1593          12 :         if( !rLine.GetDropFmt() )
    1594           0 :             rLine.SetOnceMore( false );
    1595          12 :         SwCharRange aRange( 0, rInf.GetTxt().getLength() );
    1596          12 :         pPara->GetReformat() = aRange;
    1597          12 :         _Format( rLine, rInf );
    1598             : 
    1599          12 :         bGoOn = rLine.IsOnceMore();
    1600          12 :         if( bGoOn )
    1601             :         {
    1602           0 :             const sal_uInt16 nNew = ((const SwTxtMargin&)rLine).GetDropHeight();
    1603           0 :             if( nOld == nNew )
    1604           0 :                 bGoOn = false;
    1605             :             else
    1606             :             {
    1607           0 :                 if( nOld > nNew )
    1608           0 :                     bShrink = true;
    1609             :                 else
    1610           0 :                     bGrow = true;
    1611             : 
    1612           0 :                 if( bShrink == bGrow || 5 < nGo )
    1613           0 :                     bGoOn = false;
    1614             : 
    1615           0 :                 nOld = nNew;
    1616             :             }
    1617             : 
    1618             :             // If something went wrong, we need to reformat again
    1619           0 :             if( !bGoOn )
    1620             :             {
    1621           0 :                 rInf.CtorInitTxtFormatInfo( this );
    1622           0 :                 rLine.CtorInitTxtFormatter( this, &rInf );
    1623           0 :                 rLine.SetDropLines( 1 );
    1624           0 :                 rLine.CalcDropHeight( 1 );
    1625           0 :                 SwCharRange aTmpRange( 0, rInf.GetTxt().getLength() );
    1626           0 :                 pPara->GetReformat() = aTmpRange;
    1627           0 :                 _Format( rLine, rInf, true );
    1628             :                 // We paint everything ...
    1629           0 :                 SetCompletePaint();
    1630             :             }
    1631             :         }
    1632             :     }
    1633             : }
    1634             : 
    1635       82603 : void SwTxtFrm::_Format( SwParaPortion *pPara )
    1636             : {
    1637       82603 :     const bool bIsEmpty = GetTxt().isEmpty();
    1638             : 
    1639       82603 :     if ( bIsEmpty )
    1640             :     {
    1641             :         // Empty lines do not get tortured for very long:
    1642             :         // pPara is cleared, which is the same as:
    1643             :         // *pPara = SwParaPortion;
    1644       22255 :         const bool bMustFit = pPara->IsPrepMustFit();
    1645       22255 :         pPara->Truncate();
    1646       22255 :         pPara->FormatReset();
    1647       22255 :         if( pBlink && pPara->IsBlinking() )
    1648           0 :             pBlink->Delete( pPara );
    1649             : 
    1650             :         // delete pSpaceAdd und pKanaComp
    1651       22255 :         pPara->FinishSpaceAdd();
    1652       22255 :         pPara->FinishKanaComp();
    1653       22255 :         pPara->ResetFlags();
    1654       22255 :         pPara->SetPrepMustFit( bMustFit );
    1655             :     }
    1656             : 
    1657             :     OSL_ENSURE( ! IsSwapped(), "A frame is swapped before _Format" );
    1658             : 
    1659       82603 :     if ( IsVertical() )
    1660           2 :         SwapWidthAndHeight();
    1661             : 
    1662       82603 :     SwTxtFormatInfo aInf( this );
    1663      165206 :     SwTxtFormatter  aLine( this, &aInf );
    1664             : 
    1665       82603 :     HideAndShowObjects();
    1666             : 
    1667       82603 :     _Format( aLine, aInf );
    1668             : 
    1669       82603 :     if( aLine.IsOnceMore() )
    1670          12 :         FormatOnceMore( aLine, aInf );
    1671             : 
    1672       82603 :     if ( IsVertical() )
    1673           2 :         SwapWidthAndHeight();
    1674             : 
    1675             :     OSL_ENSURE( ! IsSwapped(), "A frame is swapped after _Format" );
    1676             : 
    1677       82603 :     if( 1 < aLine.GetDropLines() )
    1678             :     {
    1679           0 :         if( SVX_ADJUST_LEFT != aLine.GetAdjust() &&
    1680           0 :             SVX_ADJUST_BLOCK != aLine.GetAdjust() )
    1681             :         {
    1682           0 :             aLine.CalcDropAdjust();
    1683           0 :             aLine.SetPaintDrop( true );
    1684             :         }
    1685             : 
    1686           0 :         if( aLine.IsPaintDrop() )
    1687             :         {
    1688           0 :             aLine.CalcDropRepaint();
    1689           0 :             aLine.SetPaintDrop( false );
    1690             :         }
    1691       82603 :     }
    1692       82603 : }
    1693             : 
    1694             : // We calculate the text frame's size and send a notification.
    1695             : // Shrink() or Grow() to adjust the frame's size to the changed required space.
    1696      131507 : void SwTxtFrm::Format( const SwBorderAttrs * )
    1697             : {
    1698      131507 :     SWRECTFN( this )
    1699             : 
    1700      131507 :     CalcAdditionalFirstLineOffset();
    1701             : 
    1702             :     // The range autopilot or the BASIC interface pass us TxtFrms with
    1703             :     // a width <= 0 from time to time
    1704      131507 :     if( (Prt().*fnRect->fnGetWidth)() <= 0 )
    1705             :     {
    1706             :         // If MustFit is set, we shrink to the Upper's bottom edge if needed.
    1707             :         // Else we just take a standard size of 12 Pt. (240 twip).
    1708         352 :         SwTxtLineAccess aAccess( this );
    1709         352 :         long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
    1710         352 :         if( aAccess.GetPara()->IsPrepMustFit() )
    1711             :         {
    1712           0 :             const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)();
    1713           0 :             const SwTwips nDiff = - (Frm().*fnRect->fnBottomDist)( nLimit );
    1714           0 :             if( nDiff > 0 )
    1715           0 :                 Shrink( nDiff );
    1716             :         }
    1717         352 :         else if( 240 < nFrmHeight )
    1718         172 :             Shrink( nFrmHeight - 240 );
    1719         180 :         else if( 240 > nFrmHeight )
    1720         148 :             Grow( 240 - nFrmHeight );
    1721         352 :         nFrmHeight = (Frm().*fnRect->fnGetHeight)();
    1722             : 
    1723         352 :         long nTop = (this->*fnRect->fnGetTopMargin)();
    1724         352 :         if( nTop > nFrmHeight )
    1725         172 :             (this->*fnRect->fnSetYMargins)( nFrmHeight, 0 );
    1726         180 :         else if( (Prt().*fnRect->fnGetHeight)() < 0 )
    1727           0 :             (Prt().*fnRect->fnSetHeight)( 0 );
    1728         352 :         return;
    1729             :     }
    1730             : 
    1731      131155 :     const sal_Int32 nStrLen = GetTxtNode()->GetTxt().getLength();
    1732      131155 :     if ( nStrLen || !FormatEmpty() )
    1733             :     {
    1734             : 
    1735      100483 :         SetEmpty( false );
    1736             :         // In order to not get confused by nested Formats
    1737      100483 :         FormatLevel aLevel;
    1738      100483 :         if( 12 == aLevel.GetLevel() )
    1739           0 :             return;
    1740             : 
    1741             :         // We could be possibly not allowed to alter the format information
    1742      100483 :         if( IsLocked() )
    1743           0 :             return;
    1744             : 
    1745             :         // Attention: Format() could be triggered by GetFormatted()
    1746      100483 :         if( IsHiddenNow() )
    1747             :         {
    1748         794 :             long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
    1749         794 :             if( nPrtHeight )
    1750             :             {
    1751           4 :                 HideHidden();
    1752           4 :                 Shrink( nPrtHeight );
    1753             :             }
    1754             :             else
    1755             :             {
    1756             :                 // Assure that objects anchored
    1757             :                 // at paragraph resp. at/as character inside paragraph
    1758             :                 // are hidden.
    1759         790 :                 HideAndShowObjects();
    1760             :             }
    1761         794 :             ChgThisLines();
    1762         794 :             return;
    1763             :         }
    1764             : 
    1765             :         // We do not want to be interrupted during formatting
    1766      199378 :         SwTxtFrmLocker aLock(this);
    1767      199378 :         SwTxtLineAccess aAccess( this );
    1768       99689 :         const bool bNew = !aAccess.SwTxtLineAccess::IsAvailable();
    1769             :         const bool bSetOfst =
    1770       99689 :             (GetOfst() && GetOfst() > GetTxtNode()->GetTxt().getLength());
    1771             : 
    1772       99689 :         if( CalcPreps() )
    1773             :             ; // nothing
    1774             :         // We return if already formatted, but if the TxtFrm was just created
    1775             :         // and does not have any format information
    1776       90351 :         else if( !bNew && !aAccess.GetPara()->GetReformat().Len() )
    1777             :         {
    1778        7748 :             if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
    1779             :             {
    1780           0 :                 aAccess.GetPara()->SetPrepAdjust();
    1781           0 :                 aAccess.GetPara()->SetPrep();
    1782           0 :                 CalcPreps();
    1783             :             }
    1784        7748 :             SetWidow( false );
    1785             :         }
    1786       82603 :         else if( bSetOfst && IsFollow() )
    1787             :         {
    1788           0 :             SwTxtFrm *pMaster = FindMaster();
    1789             :             OSL_ENSURE( pMaster, "SwTxtFrm::Format: homeless follow" );
    1790           0 :             if( pMaster )
    1791           0 :                 pMaster->Prepare( PREP_FOLLOW_FOLLOWS );
    1792           0 :             SwTwips nMaxY = (GetUpper()->*fnRect->fnGetPrtBottom)();
    1793           0 :             if( (Frm().*fnRect->fnOverStep)( nMaxY  ) )
    1794           0 :                 (this->*fnRect->fnSetLimit)( nMaxY );
    1795           0 :             else if( (Frm().*fnRect->fnBottomDist)( nMaxY  ) < 0 )
    1796           0 :                 (Frm().*fnRect->fnAddBottom)( -(Frm().*fnRect->fnGetHeight)() );
    1797             :         }
    1798             :         else
    1799             :         {
    1800             :             // bSetOfst here means that we have the "red arrow situation"
    1801       82603 :             if ( bSetOfst )
    1802           0 :                 _SetOfst( 0 );
    1803             : 
    1804       82603 :             const bool bOrphan = IsWidow();
    1805       82603 :             const SwFtnBossFrm* pFtnBoss = HasFtn() ? FindFtnBossFrm() : 0;
    1806       82603 :             SwTwips nFtnHeight = 0;
    1807       82603 :             if( pFtnBoss )
    1808             :             {
    1809          80 :                 const SwFtnContFrm* pCont = pFtnBoss->FindFtnCont();
    1810          80 :                 nFtnHeight = pCont ? (pCont->Frm().*fnRect->fnGetHeight)() : 0;
    1811             :             }
    1812           0 :             do
    1813             :             {
    1814       82603 :                 _Format( aAccess.GetPara() );
    1815       82603 :                 if( pFtnBoss && nFtnHeight )
    1816             :                 {
    1817          50 :                     const SwFtnContFrm* pCont = pFtnBoss->FindFtnCont();
    1818          50 :                     SwTwips nNewHeight = pCont ? (pCont->Frm().*fnRect->fnGetHeight)() : 0;
    1819             :                     // If we lost some footnotes, we may have more space
    1820             :                     // for our main text, so we have to format again ...
    1821          50 :                     if( nNewHeight < nFtnHeight )
    1822           0 :                         nFtnHeight = nNewHeight;
    1823             :                     else
    1824          50 :                         break;
    1825             :                 }
    1826             :                 else
    1827             :                     break;
    1828             :             } while ( pFtnBoss );
    1829       82603 :             if( bOrphan )
    1830             :             {
    1831           0 :                 ValidateFrm();
    1832           0 :                 SetWidow( false );
    1833             :             }
    1834             :         }
    1835       99689 :         if( IsEmptyMaster() )
    1836             :         {
    1837          14 :             SwFrm* pPre = GetPrev();
    1838          20 :             if( pPre &&
    1839             :                 // #i10826# It's the first, it cannot keep!
    1840          16 :                 pPre->GetIndPrev() &&
    1841           2 :                 pPre->GetAttrSet()->GetKeep().GetValue() )
    1842             :             {
    1843           0 :                 pPre->InvalidatePos();
    1844             :             }
    1845       99689 :         }
    1846             :     }
    1847             : 
    1848      130361 :     ChgThisLines();
    1849             : 
    1850             :     // the PrepMustFit should not survive a Format operation
    1851      130361 :     SwParaPortion *pPara = GetPara();
    1852      130361 :     if ( pPara )
    1853       99689 :            pPara->SetPrepMustFit( false );
    1854             : 
    1855      130361 :     CalcBaseOfstForFly();
    1856      130361 :     _CalcHeightOfLastLine(); // #i11860#
    1857             : }
    1858             : 
    1859             : // bForceQuickFormat is set if GetFormatted() has been called during the
    1860             : // painting process. Actually I cannot imagine a situation which requires
    1861             : // a full formatting of the paragraph during painting, on the other hand
    1862             : // a full formatting can cause the invalidation of other layout frames,
    1863             : // e.g., if there are footnotes in this paragraph, and invalid layout
    1864             : // frames will not calculated during the painting. So I actually want to
    1865             : // avoid a formatting during painting, but since I'm a coward, I'll only
    1866             : // force the quick formatting in the situation of issue i29062.
    1867           4 : bool SwTxtFrm::FormatQuick( bool bForceQuickFormat )
    1868             : {
    1869             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
    1870             :             "SwTxtFrm::FormatQuick with swapped frame" );
    1871             : 
    1872             : #if OSL_DEBUG_LEVEL > 1
    1873             :     const OUString aXXX = GetTxtNode()->GetTxt();
    1874             :     const SwTwips nDbgY = Frm().Top();
    1875             :     (void)nDbgY;
    1876             :     // nStopAt allows CV to alter it
    1877             :     static sal_uInt16 nStopAt = 0;
    1878             :     if( nStopAt == GetFrmId() )
    1879             :     {
    1880             :         int i = GetFrmId();
    1881             :         (void)i;
    1882             :     }
    1883             : #endif
    1884             : 
    1885           4 :     if( IsEmpty() && FormatEmpty() )
    1886           4 :         return true;
    1887             : 
    1888             :     // We're very picky:
    1889           0 :     if( HasPara() || IsWidow() || IsLocked()
    1890           0 :         || !GetValidSizeFlag() ||
    1891           0 :         ( ( IsVertical() ? Prt().Width() : Prt().Height() ) && IsHiddenNow() ) )
    1892           0 :         return false;
    1893             : 
    1894           0 :     SwTxtLineAccess aAccess( this );
    1895           0 :     SwParaPortion *pPara = aAccess.GetPara();
    1896           0 :     if( !pPara )
    1897           0 :         return false;
    1898             : 
    1899           0 :     SwFrmSwapper aSwapper( this, true );
    1900             : 
    1901           0 :     SwTxtFrmLocker aLock(this);
    1902           0 :     SwTxtFormatInfo aInf( this, false, true );
    1903           0 :     if( 0 != aInf.MaxHyph() )   // Respect MaxHyphen!
    1904           0 :         return false;
    1905             : 
    1906           0 :     SwTxtFormatter  aLine( this, &aInf );
    1907             : 
    1908             :     // DropCaps are too complicated ...
    1909           0 :     if( aLine.GetDropFmt() )
    1910           0 :         return false;
    1911             : 
    1912           0 :     sal_Int32 nStart = GetOfst();
    1913           0 :     const sal_Int32 nEnd = GetFollow()
    1914           0 :                       ? GetFollow()->GetOfst() : aInf.GetTxt().getLength();
    1915           0 :     do
    1916             :     {
    1917           0 :         nStart = aLine.FormatLine( nStart );
    1918           0 :         if( aInf.IsNewLine() || (!aInf.IsStop() && nStart < nEnd) )
    1919           0 :             aLine.Insert( new SwLineLayout() );
    1920           0 :     } while( aLine.Next() );
    1921             : 
    1922             :     // Last exit: the heights need to match
    1923           0 :     Point aTopLeft( Frm().Pos() );
    1924           0 :     aTopLeft += Prt().Pos();
    1925           0 :     const SwTwips nNewHeight = aLine.Y() + aLine.GetLineHeight();
    1926           0 :     const SwTwips nOldHeight = aTopLeft.Y() + Prt().Height();
    1927             : 
    1928           0 :     if( !bForceQuickFormat && nNewHeight != nOldHeight && !IsUndersized() )
    1929             :     {
    1930             :         // Attention: This situation can occur due to FormatLevel==12. Don't panic!
    1931           0 :         const sal_Int32 nStrt = GetOfst();
    1932           0 :         _InvalidateRange( SwCharRange( nStrt, nEnd - nStrt) );
    1933           0 :         return false;
    1934             :     }
    1935             : 
    1936           0 :     if (m_pFollow && nStart != (static_cast<SwTxtFrm*>(m_pFollow))->GetOfst())
    1937           0 :         return false; // can be caused by e.g. Orphans
    1938             : 
    1939             :     // We made it!
    1940             : 
    1941             :     // Set repaint
    1942           0 :     pPara->GetRepaint().Pos( aTopLeft );
    1943           0 :     pPara->GetRepaint().SSize( Prt().SSize() );
    1944             : 
    1945             :     // Delete reformat
    1946           0 :     pPara->GetReformat() = SwCharRange();
    1947           0 :     pPara->GetDelta() = 0;
    1948             : 
    1949           0 :     return true;
    1950         270 : }
    1951             : 
    1952             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10