LCOV - code coverage report
Current view: top level - sw/source/core/text - frmform.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 940 0.0 %
Date: 2014-04-14 Functions: 0 25 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10