LCOV - code coverage report
Current view: top level - sw/source/core/text - frmcrsr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 259 831 31.2 %
Date: 2012-08-25 Functions: 15 32 46.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 267 1290 20.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include "ndtxt.hxx"        // GetNode()
      30                 :            : #include "pam.hxx"          // SwPosition
      31                 :            : #include "frmtool.hxx"
      32                 :            : #include "viewopt.hxx"
      33                 :            : #include "paratr.hxx"
      34                 :            : #include "rootfrm.hxx"
      35                 :            : #include "pagefrm.hxx"
      36                 :            : #include "colfrm.hxx"
      37                 :            : #include "txttypes.hxx"
      38                 :            : #include <sfx2/printer.hxx>
      39                 :            : #include <editeng/lrspitem.hxx>
      40                 :            : #include <editeng/tstpitem.hxx>
      41                 :            : #include <editeng/ulspitem.hxx>
      42                 :            : #include <editeng/lspcitem.hxx>
      43                 :            : #include <pormulti.hxx>     // SwMultiPortion
      44                 :            : #include <doc.hxx>
      45                 :            : #include <sortedobjs.hxx>
      46                 :            : 
      47                 :            : #include <unicode/ubidi.h>
      48                 :            : 
      49                 :            : #include "txtfrm.hxx"       // SwTxtFrm
      50                 :            : #include "inftxt.hxx"       // SwTxtSizeInfo
      51                 :            : #include "itrtxt.hxx"       // SwTxtCursor
      52                 :            : #include "crstate.hxx"      // SwTxtCursor
      53                 :            : #include "viewsh.hxx"       // InvalidateWindows
      54                 :            : #include "swfntcch.hxx"     // SwFontAccess
      55                 :            : #include "flyfrm.hxx"
      56                 :            : 
      57                 :            : 
      58                 :            : #define MIN_OFFSET_STEP 10
      59                 :            : 
      60                 :            : using namespace ::com::sun::star;
      61                 :            : 
      62                 :            : 
      63                 :            : /*
      64                 :            :  * - SurvivalKit: For how long do we get past the last char of the line.
      65                 :            :  * - RightMargin abstains from adjusting position with -1
      66                 :            :  * - GetCharRect returns a GetEndCharRect for MV_RIGHTMARGIN
      67                 :            :  * - GetEndCharRect sets bRightMargin to sal_True
      68                 :            :  * - SwTxtCursor::bRightMargin is set to sal_False by CharCrsrToLine
      69                 :            :  */
      70                 :            : 
      71                 :            : /*************************************************************************
      72                 :            :  *                      GetAdjFrmAtPos()
      73                 :            :  *************************************************************************/
      74                 :            : 
      75                 :      70722 : SwTxtFrm *GetAdjFrmAtPos( SwTxtFrm *pFrm, const SwPosition &rPos,
      76                 :            :                           const sal_Bool bRightMargin, const sal_Bool bNoScroll = sal_True )
      77                 :            : {
      78                 :            :     // RightMargin in the last master line
      79                 :      70722 :     const xub_StrLen nOffset = rPos.nContent.GetIndex();
      80                 :      70722 :     SwTxtFrm *pFrmAtPos = pFrm;
      81 [ +  + ][ +  + ]:      70722 :     if( !bNoScroll || pFrm->GetFollow() )
                 [ +  + ]
      82                 :            :     {
      83                 :      69792 :         pFrmAtPos = pFrm->GetFrmAtPos( rPos );
      84         [ +  + ]:      69794 :         if( nOffset < pFrmAtPos->GetOfst() &&
           [ +  +  +  - ]
      85                 :          2 :             !pFrmAtPos->IsFollow() )
      86                 :            :         {
      87                 :          2 :             xub_StrLen nNew = nOffset;
      88         [ +  - ]:          2 :             if( nNew < MIN_OFFSET_STEP )
      89                 :          2 :                 nNew = 0;
      90                 :            :             else
      91                 :          0 :                 nNew -= MIN_OFFSET_STEP;
      92                 :          2 :             lcl_ChangeOffset( pFrmAtPos, nNew );
      93                 :            :         }
      94                 :            :     }
      95         [ -  + ]:      70722 :     while( pFrm != pFrmAtPos )
      96                 :            :     {
      97                 :          0 :         pFrm = pFrmAtPos;
      98                 :          0 :         pFrm->GetFormatted();
      99                 :          0 :         pFrmAtPos = (SwTxtFrm*)pFrm->GetFrmAtPos( rPos );
     100                 :            :     }
     101                 :            : 
     102 [ +  + ][ -  + ]:      70722 :     if( nOffset && bRightMargin )
     103                 :            :     {
     104         [ #  # ]:          0 :         while( pFrmAtPos && pFrmAtPos->GetOfst() == nOffset &&
           [ #  #  #  # ]
                 [ #  # ]
     105                 :          0 :                pFrmAtPos->IsFollow() )
     106                 :            :         {
     107                 :          0 :             pFrmAtPos->GetFormatted();
     108                 :          0 :             pFrmAtPos = pFrmAtPos->FindMaster();
     109                 :            :         }
     110                 :            :         OSL_ENSURE( pFrmAtPos, "+GetCharRect: no frame with my rightmargin" );
     111                 :            :     }
     112         [ +  - ]:      70722 :     return pFrmAtPos ? pFrmAtPos : pFrm;
     113                 :            : }
     114                 :            : 
     115                 :         44 : sal_Bool lcl_ChangeOffset( SwTxtFrm* pFrm, xub_StrLen nNew )
     116                 :            : {
     117                 :            :     // Do not scroll in areas and outside of flies
     118                 :            :     OSL_ENSURE( !pFrm->IsFollow(), "Illegal Scrolling by Follow!" );
     119 [ +  - ][ +  - ]:         44 :     if( pFrm->GetOfst() != nNew && !pFrm->IsInSct() )
                 [ +  - ]
     120                 :            :     {
     121                 :         44 :         SwFlyFrm *pFly = pFrm->FindFlyFrm();
     122                 :            :         // Attention: if e.g. in a column frame the size is still invalid
     123                 :            :         // we must not scroll around just like that
     124   [ +  -  +  -  :        132 :         if ( ( pFly && pFly->IsValid() &&
                   -  + ]
           [ #  #  #  # ]
         [ +  - ][ +  - ]
     125                 :         88 :              !pFly->GetNextLink() && !pFly->GetPrevLink() ) ||
     126                 :          0 :              ( !pFly && pFrm->IsInTab() ) )
     127                 :            :         {
     128                 :         44 :             ViewShell* pVsh = pFrm->getRootFrm()->GetCurrShell();
     129         [ +  - ]:         44 :             if( pVsh )
     130                 :            :             {
     131   [ +  -  -  +  :         88 :                 if( pVsh->GetNext() != pVsh ||
           #  # ][ -  + ]
     132                 :         44 :                     ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() ) )
     133                 :            :                 {
     134         [ #  # ]:          0 :                     if( !pFrm->GetOfst() )
     135                 :          0 :                         return sal_False;
     136                 :          0 :                     nNew = 0;
     137                 :            :                 }
     138                 :         44 :                 pFrm->SetOfst( nNew );
     139                 :         44 :                 pFrm->SetPara( 0 );
     140                 :         44 :                 pFrm->GetFormatted();
     141         [ +  - ]:         44 :                 if( pFrm->Frm().HasArea() )
     142                 :         44 :                     pFrm->getRootFrm()->GetCurrShell()->InvalidateWindows( pFrm->Frm() );
     143                 :         44 :                 return sal_True;
     144                 :            :             }
     145                 :            :         }
     146                 :            :     }
     147                 :         44 :     return sal_False;
     148                 :            : }
     149                 :            : 
     150                 :            : /*************************************************************************
     151                 :            :  *                      GetFrmAtOfst(), GetFrmAtPos()
     152                 :            :  *************************************************************************/
     153                 :            : 
     154                 :      11535 : SwTxtFrm& SwTxtFrm::GetFrmAtOfst( const xub_StrLen nWhere )
     155                 :            : {
     156                 :      11535 :     SwTxtFrm* pRet = this;
     157 [ +  + ][ +  + ]:      11539 :     while( pRet->HasFollow() && nWhere >= pRet->GetFollow()->GetOfst() )
                 [ +  + ]
     158                 :          4 :         pRet = pRet->GetFollow();
     159                 :      11535 :     return *pRet;
     160                 :            : }
     161                 :            : 
     162                 :     233183 : SwTxtFrm *SwTxtFrm::GetFrmAtPos( const SwPosition &rPos )
     163                 :            : {
     164                 :     233183 :     SwTxtFrm *pFoll = (SwTxtFrm*)this;
     165         [ +  + ]:     276032 :     while( pFoll->GetFollow() )
     166                 :            :     {
     167         [ +  + ]:      42925 :         if( rPos.nContent.GetIndex() > pFoll->GetFollow()->GetOfst() )
     168                 :      42797 :             pFoll = pFoll->GetFollow();
     169                 :            :         else
     170                 :            :         {
     171   [ +  +  +  - ]:        180 :             if( rPos.nContent.GetIndex() == pFoll->GetFollow()->GetOfst()
                 [ +  + ]
     172                 :         52 :                  && !SwTxtCursor::IsRightMargin() )
     173                 :         52 :                  pFoll = pFoll->GetFollow();
     174                 :            :             else
     175                 :         76 :                 break;
     176                 :            :         }
     177                 :            :     }
     178                 :     233183 :     return pFoll;
     179                 :            : }
     180                 :            : 
     181                 :            : /*************************************************************************
     182                 :            :  *                      SwTxtFrm::GetCharRect()
     183                 :            :  *************************************************************************/
     184                 :            : 
     185                 :            : /*
     186                 :            :  * GetCharRect() returns the char's char line described by aPos.
     187                 :            :  * GetCrsrOfst() does the reverse: It goes from a document coordinate to
     188                 :            :  * a Pam.
     189                 :            :  * Both are virtual in the frame base class and thus are redefined here.
     190                 :            :  */
     191                 :            : 
     192                 :      70882 : sal_Bool SwTxtFrm::GetCharRect( SwRect& rOrig, const SwPosition &rPos,
     193                 :            :                             SwCrsrMoveState *pCMS ) const
     194                 :            : {
     195                 :            :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),"SwTxtFrm::GetCharRect with swapped frame" );
     196                 :            : 
     197 [ +  + ][ +  + ]:      70882 :     if( IsLocked() || IsHiddenNow() )
                 [ +  + ]
     198                 :        166 :         return sal_False;
     199                 :            : 
     200                 :            :     // Find the right frame first. We need to keep in mind that:
     201                 :            :     // - the cached information could be invalid  (GetPara() == 0)
     202                 :            :     // - we could have a Follow
     203                 :            :     // - the Follow chain grows dynamically; the one we end up in
     204                 :            :     //   needs to be formatted
     205                 :            : 
     206                 :            :     // Optimisation: reading ahead saves us a GetAdjFrmAtPos
     207 [ +  + ][ -  + ]:      70716 :     const sal_Bool bRightMargin = pCMS && ( MV_RIGHTMARGIN == pCMS->eState );
     208 [ +  + ][ +  + ]:      70716 :     const sal_Bool bNoScroll = pCMS && pCMS->bNoScroll;
     209                 :            :     SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, rPos, bRightMargin,
     210                 :      70716 :                                      bNoScroll );
     211                 :      70716 :     pFrm->GetFormatted();
     212                 :      70716 :     const SwFrm* pTmpFrm = (SwFrm*)pFrm->GetUpper();
     213                 :            : 
     214 [ #  # ][ #  # ]:      70716 :     SWRECTFN ( pFrm )
         [ -  + ][ -  + ]
     215         [ +  - ]:      70716 :     const SwTwips nUpperMaxY = (pTmpFrm->*fnRect->fnGetPrtBottom)();
     216         [ +  - ]:      70716 :     const SwTwips nFrmMaxY = (pFrm->*fnRect->fnGetPrtBottom)();
     217                 :            : 
     218                 :            :     // nMaxY is an absolute value
     219                 :            :     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     220                 :            :     SwTwips nMaxY = bVert ?
     221                 :            :                     ( bVertL2R ? Min( nFrmMaxY, nUpperMaxY ) : Max( nFrmMaxY, nUpperMaxY ) ) :
     222 [ #  # ][ -  + ]:      70716 :                     Min( nFrmMaxY, nUpperMaxY );
     223                 :            : 
     224                 :      70716 :     sal_Bool bRet = sal_False;
     225                 :            : 
     226 [ +  + ][ +  - ]:      70716 :     if ( pFrm->IsEmpty() || ! (pFrm->Prt().*fnRect->fnGetHeight)() )
         [ -  + ][ +  + ]
     227                 :            :     {
     228                 :      19492 :         Point aPnt1 = pFrm->Frm().Pos() + pFrm->Prt().Pos();
     229                 :      19492 :         SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
     230                 :            :         short nFirstOffset;
     231         [ +  - ]:      19492 :         pTxtNd->GetFirstLineOfsWithNum( nFirstOffset );
     232                 :            : 
     233                 :      19492 :         Point aPnt2;
     234         [ -  + ]:      19492 :         if ( bVert )
     235                 :            :         {
     236         [ #  # ]:          0 :             if( nFirstOffset > 0 )
     237                 :          0 :                 aPnt1.Y() += nFirstOffset;
     238                 :            :             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     239 [ #  # ][ #  # ]:          0 :             if ( aPnt1.X() < nMaxY && !bVertL2R )
                 [ #  # ]
     240                 :          0 :                 aPnt1.X() = nMaxY;
     241                 :          0 :             aPnt2.X() = aPnt1.X() + pFrm->Prt().Width();
     242                 :          0 :             aPnt2.Y() = aPnt1.Y();
     243         [ #  # ]:          0 :             if( aPnt2.X() < nMaxY )
     244                 :          0 :                 aPnt2.X() = nMaxY;
     245                 :            :         }
     246                 :            :         else
     247                 :            :         {
     248         [ -  + ]:      19492 :             if( nFirstOffset > 0 )
     249                 :          0 :                 aPnt1.X() += nFirstOffset;
     250                 :            : 
     251         [ -  + ]:      19492 :             if( aPnt1.Y() > nMaxY )
     252                 :          0 :                 aPnt1.Y() = nMaxY;
     253                 :      19492 :             aPnt2.X() = aPnt1.X();
     254                 :      19492 :             aPnt2.Y() = aPnt1.Y() + pFrm->Prt().Height();
     255         [ -  + ]:      19492 :             if( aPnt2.Y() > nMaxY )
     256                 :          0 :                 aPnt2.Y() = nMaxY;
     257                 :            :         }
     258                 :            : 
     259                 :      19492 :         rOrig = SwRect( aPnt1, aPnt2 );
     260                 :            : 
     261         [ +  + ]:      19492 :         if ( pCMS )
     262                 :            :         {
     263                 :      19484 :             pCMS->aRealHeight.X() = 0;
     264         [ -  + ]:      19484 :             pCMS->aRealHeight.Y() = bVert ? -rOrig.Width() : rOrig.Height();
     265                 :            :         }
     266                 :            : 
     267 [ +  - ][ -  + ]:      19492 :         if ( pFrm->IsRightToLeft() )
     268         [ #  # ]:          0 :             pFrm->SwitchLTRtoRTL( rOrig );
     269                 :            : 
     270                 :      19492 :         bRet = sal_True;
     271                 :            :     }
     272                 :            :     else
     273                 :            :     {
     274 [ +  - ][ -  + ]:      51224 :         if( !pFrm->HasPara() )
     275                 :          0 :             return sal_False;
     276                 :            : 
     277         [ +  - ]:      51224 :         SwFrmSwapper aSwapper( pFrm, sal_True );
     278         [ -  + ]:      51224 :         if ( bVert )
     279         [ #  # ]:          0 :             nMaxY = pFrm->SwitchVerticalToHorizontal( nMaxY );
     280                 :            : 
     281                 :      51224 :         sal_Bool bGoOn = sal_True;
     282                 :      51224 :         xub_StrLen nOffset = rPos.nContent.GetIndex();
     283                 :            :         xub_StrLen nNextOfst;
     284                 :            : 
     285         [ +  + ]:      51266 :         do
     286                 :            :         {
     287                 :            :             {
     288         [ +  - ]:      51266 :                 SwTxtSizeInfo aInf( pFrm );
     289         [ +  - ]:      51266 :                 SwTxtCursor  aLine( pFrm, &aInf );
     290                 :      51266 :                 nNextOfst = aLine.GetEnd();
     291                 :            :                 // See comment in AdjustFrm
     292                 :            :                 // Include the line's last char?
     293                 :          0 :                 bRet = bRightMargin ? aLine.GetEndCharRect( &rOrig, nOffset, pCMS, nMaxY )
     294 [ #  # ][ +  - ]:      51266 :                                 : aLine.GetCharRect( &rOrig, nOffset, pCMS, nMaxY );
         [ +  - ][ -  + ]
     295                 :            :             }
     296                 :            : 
     297 [ -  + ][ +  - ]:      51266 :             if ( pFrm->IsRightToLeft() )
     298         [ #  # ]:          0 :                 pFrm->SwitchLTRtoRTL( rOrig );
     299                 :            : 
     300         [ -  + ]:      51266 :             if ( bVert )
     301         [ #  # ]:          0 :                 pFrm->SwitchHorizontalToVertical( rOrig );
     302                 :            : 
     303 [ +  + ][ +  - ]:      51658 :             if( pFrm->IsUndersized() && pCMS && !pFrm->GetNext() &&
         [ +  - ][ +  +  
             +  +  +  - ]
           [ +  -  +  - ]
                 [ +  + ]
     304 [ +  - ][ +  - ]:        156 :                 (rOrig.*fnRect->fnGetBottom)() == nUpperMaxY &&
     305                 :        152 :                 pFrm->GetOfst() < nOffset &&
     306                 :         42 :                 !pFrm->IsFollow() && !bNoScroll &&
     307                 :         42 :                 pFrm->GetTxtNode()->GetTxt().Len() != nNextOfst )
     308         [ +  - ]:         42 :                 bGoOn = lcl_ChangeOffset( pFrm, nNextOfst );
     309                 :            :             else
     310                 :      51224 :                 bGoOn = sal_False;
     311                 :            :         } while ( bGoOn );
     312                 :            : 
     313         [ +  + ]:      51224 :         if ( pCMS )
     314                 :            :         {
     315 [ +  - ][ -  + ]:      51139 :             if ( pFrm->IsRightToLeft() )
     316                 :            :             {
     317 [ #  # ][ #  # ]:          0 :                 if( pCMS->b2Lines && pCMS->p2Lines)
     318                 :            :                 {
     319         [ #  # ]:          0 :                     pFrm->SwitchLTRtoRTL( pCMS->p2Lines->aLine );
     320         [ #  # ]:          0 :                     pFrm->SwitchLTRtoRTL( pCMS->p2Lines->aPortion );
     321                 :            :                 }
     322                 :            :             }
     323                 :            : 
     324         [ -  + ]:      51139 :             if ( bVert )
     325                 :            :             {
     326         [ #  # ]:          0 :                 if ( pCMS->bRealHeight )
     327                 :            :                 {
     328                 :          0 :                     pCMS->aRealHeight.Y() = -pCMS->aRealHeight.Y();
     329         [ #  # ]:          0 :                     if ( pCMS->aRealHeight.Y() < 0 )
     330                 :            :                     {
     331                 :            :                         // writing direction is from top to bottom
     332                 :          0 :                         pCMS->aRealHeight.X() =  ( rOrig.Width() -
     333                 :          0 :                                                     pCMS->aRealHeight.X() +
     334                 :          0 :                                                     pCMS->aRealHeight.Y() );
     335                 :            :                     }
     336                 :            :                 }
     337 [ #  # ][ #  # ]:          0 :                 if( pCMS->b2Lines && pCMS->p2Lines)
     338                 :            :                 {
     339         [ #  # ]:          0 :                     pFrm->SwitchHorizontalToVertical( pCMS->p2Lines->aLine );
     340         [ #  # ]:          0 :                     pFrm->SwitchHorizontalToVertical( pCMS->p2Lines->aPortion );
     341                 :            :                 }
     342                 :            :             }
     343                 :            : 
     344         [ +  - ]:      51224 :         }
     345                 :            :     }
     346         [ +  - ]:      70716 :     if( bRet )
     347                 :            :     {
     348                 :      70716 :         SwPageFrm *pPage = pFrm->FindPageFrm();
     349                 :            :         OSL_ENSURE( pPage, "Text escaped from page?" );
     350         [ +  - ]:      70716 :         const SwTwips nOrigTop = (rOrig.*fnRect->fnGetTop)();
     351         [ +  - ]:      70716 :         const SwTwips nPageTop = (pPage->Frm().*fnRect->fnGetTop)();
     352         [ +  - ]:      70716 :         const SwTwips nPageBott = (pPage->Frm().*fnRect->fnGetBottom)();
     353                 :            : 
     354                 :            :         // We have the following situation: if the frame is in an invalid
     355                 :            :         // sectionframe, it's possible that the frame is outside the page.
     356                 :            :         // If we restrict the cursor position to the page area, we enforce
     357                 :            :         // the formatting of the page, of the section frame and the frame itself.
     358         [ -  + ]:      70716 :         if( (*fnRect->fnYDiff)( nPageTop, nOrigTop ) > 0 )
     359         [ #  # ]:          0 :             (rOrig.*fnRect->fnSetTop)( nPageTop );
     360                 :            : 
     361         [ -  + ]:      70716 :         if ( (*fnRect->fnYDiff)( nOrigTop, nPageBott ) > 0 )
     362         [ #  # ]:          0 :             (rOrig.*fnRect->fnSetTop)( nPageBott );
     363                 :            :     }
     364                 :            : 
     365                 :      70882 :     return bRet;
     366                 :            : }
     367                 :            : 
     368                 :            : /*************************************************************************
     369                 :            :  *                      SwTxtFrm::GetAutoPos()
     370                 :            :  *************************************************************************/
     371                 :            : 
     372                 :            : /*
     373                 :            :  * GetAutoPos() looks up the char's char line which is described by rPos
     374                 :            :  * and is used by the auto-positioned frame.
     375                 :            :  */
     376                 :            : 
     377                 :        287 : sal_Bool SwTxtFrm::GetAutoPos( SwRect& rOrig, const SwPosition &rPos ) const
     378                 :            : {
     379         [ -  + ]:        287 :     if( IsHiddenNow() )
     380                 :          0 :         return sal_False;
     381                 :            : 
     382                 :        287 :     xub_StrLen nOffset = rPos.nContent.GetIndex();
     383                 :        287 :     SwTxtFrm* pFrm = &(const_cast<SwTxtFrm*>(this)->GetFrmAtOfst( nOffset ));
     384                 :            : 
     385                 :        287 :     pFrm->GetFormatted();
     386                 :        287 :     const SwFrm* pTmpFrm = (SwFrm*)pFrm->GetUpper();
     387                 :            : 
     388 [ #  # ][ #  # ]:        287 :     SWRECTFN( pTmpFrm )
         [ -  + ][ -  + ]
     389         [ +  - ]:        287 :     SwTwips nUpperMaxY = (pTmpFrm->*fnRect->fnGetPrtBottom)();
     390                 :            : 
     391                 :            :     // nMaxY is in absolute value
     392                 :            :     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     393                 :            :     SwTwips nMaxY = bVert ?
     394 [ #  # ][ #  # ]:          0 :                     ( bVertL2R ? Min( (pFrm->*fnRect->fnGetPrtBottom)(), nUpperMaxY ) : Max( (pFrm->*fnRect->fnGetPrtBottom)(), nUpperMaxY ) ) :
     395 [ #  # ][ +  - ]:        287 :                     Min( (pFrm->*fnRect->fnGetPrtBottom)(), nUpperMaxY );
                 [ -  + ]
     396                 :            : 
     397 [ +  + ][ +  - ]:        287 :     if ( pFrm->IsEmpty() || ! (pFrm->Prt().*fnRect->fnGetHeight)() )
         [ -  + ][ +  + ]
     398                 :            :     {
     399                 :         24 :         Point aPnt1 = pFrm->Frm().Pos() + pFrm->Prt().Pos();
     400                 :         24 :         Point aPnt2;
     401         [ -  + ]:         24 :         if ( bVert )
     402                 :            :         {
     403 [ #  # ][ #  # ]:          0 :             if ( aPnt1.X() < nMaxY && !bVertL2R )
                 [ #  # ]
     404                 :          0 :                 aPnt1.X() = nMaxY;
     405                 :            : 
     406                 :          0 :             aPnt2.X() = aPnt1.X() + pFrm->Prt().Width();
     407                 :          0 :             aPnt2.Y() = aPnt1.Y();
     408         [ #  # ]:          0 :             if( aPnt2.X() < nMaxY )
     409                 :          0 :                 aPnt2.X() = nMaxY;
     410                 :            :         }
     411                 :            :         else
     412                 :            :         {
     413         [ -  + ]:         24 :             if( aPnt1.Y() > nMaxY )
     414                 :          0 :                 aPnt1.Y() = nMaxY;
     415                 :         24 :             aPnt2.X() = aPnt1.X();
     416                 :         24 :             aPnt2.Y() = aPnt1.Y() + pFrm->Prt().Height();
     417         [ -  + ]:         24 :             if( aPnt2.Y() > nMaxY )
     418                 :          0 :                 aPnt2.Y() = nMaxY;
     419                 :            :         }
     420                 :         24 :         rOrig = SwRect( aPnt1, aPnt2 );
     421                 :         24 :         return sal_True;
     422                 :            :     }
     423                 :            :     else
     424                 :            :     {
     425 [ +  - ][ -  + ]:        263 :         if( !pFrm->HasPara() )
     426                 :          0 :             return sal_False;
     427                 :            : 
     428         [ +  - ]:        263 :         SwFrmSwapper aSwapper( pFrm, sal_True );
     429         [ -  + ]:        263 :         if ( bVert )
     430         [ #  # ]:          0 :             nMaxY = pFrm->SwitchVerticalToHorizontal( nMaxY );
     431                 :            : 
     432         [ +  - ]:        263 :         SwTxtSizeInfo aInf( pFrm );
     433         [ +  - ]:        263 :         SwTxtCursor aLine( pFrm, &aInf );
     434                 :        263 :         SwCrsrMoveState aTmpState( MV_SETONLYTEXT );
     435                 :        263 :         aTmpState.bRealHeight = sal_True;
     436 [ +  - ][ +  - ]:        263 :         if( aLine.GetCharRect( &rOrig, nOffset, &aTmpState, nMaxY ) )
     437                 :            :         {
     438         [ +  - ]:        263 :             if( aTmpState.aRealHeight.X() >= 0 )
     439                 :            :             {
     440                 :        263 :                 rOrig.Pos().Y() += aTmpState.aRealHeight.X();
     441                 :        263 :                 rOrig.Height( aTmpState.aRealHeight.Y() );
     442                 :            :             }
     443                 :            : 
     444 [ +  - ][ -  + ]:        263 :             if ( pFrm->IsRightToLeft() )
     445         [ #  # ]:          0 :                 pFrm->SwitchLTRtoRTL( rOrig );
     446                 :            : 
     447         [ -  + ]:        263 :             if ( bVert )
     448         [ #  # ]:          0 :                 pFrm->SwitchHorizontalToVertical( rOrig );
     449                 :            : 
     450                 :        263 :             return sal_True;
     451                 :            :         }
     452 [ +  - ][ +  - ]:        287 :         return sal_False;
     453                 :            :     }
     454                 :            : }
     455                 :            : 
     456                 :            : /** determine top of line for given position in the text frame
     457                 :            : 
     458                 :            :     - Top of first paragraph line is the top of the printing area of the text frame
     459                 :            :     - If a proportional line spacing is applied use top of anchor character as
     460                 :            :       top of the line.
     461                 :            : 
     462                 :            :     @author OD
     463                 :            : */
     464                 :        254 : bool SwTxtFrm::GetTopOfLine( SwTwips& _onTopOfLine,
     465                 :            :                              const SwPosition& _rPos ) const
     466                 :            : {
     467                 :        254 :     bool bRet = true;
     468                 :            : 
     469                 :            :     // get position offset
     470                 :        254 :     xub_StrLen nOffset = _rPos.nContent.GetIndex();
     471                 :            : 
     472         [ -  + ]:        254 :     if ( GetTxt().Len() < nOffset )
     473                 :            :     {
     474                 :          0 :         bRet = false;
     475                 :            :     }
     476                 :            :     else
     477                 :            :     {
     478 [ -  + ][ #  # ]:        254 :         SWRECTFN( this )
         [ #  # ][ -  + ]
     479 [ +  + ][ +  - ]:        254 :         if ( IsEmpty() || !(Prt().*fnRect->fnGetHeight)() )
         [ -  + ][ +  + ]
     480                 :            :         {
     481                 :            :             // consider upper space amount considered
     482                 :            :             // for previous frame and the page grid.
     483         [ +  - ]:         24 :             _onTopOfLine = (this->*fnRect->fnGetPrtTop)();
     484                 :            :         }
     485                 :            :         else
     486                 :            :         {
     487                 :            :             // determine formatted text frame that contains the requested position
     488                 :        230 :             SwTxtFrm* pFrm = &(const_cast<SwTxtFrm*>(this)->GetFrmAtOfst( nOffset ));
     489                 :        230 :             pFrm->GetFormatted();
     490 [ -  + ][ -  + ]:        230 :             SWREFRESHFN( pFrm )
         [ -  + ][ #  # ]
         [ #  # ][ -  + ]
                 [ +  - ]
     491                 :            :             // If proportional line spacing is applied
     492                 :            :             // to the text frame, the top of the anchor character is also the
     493                 :            :             // top of the line.
     494                 :            :             // Otherwise the line layout determines the top of the line
     495                 :        230 :             const SvxLineSpacingItem& rSpace = GetAttrSet()->GetLineSpacing();
     496         [ +  + ]:        230 :             if ( rSpace.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
     497                 :            :             {
     498                 :         33 :                 SwRect aCharRect;
     499 [ +  - ][ +  - ]:         33 :                 if ( GetAutoPos( aCharRect, _rPos ) )
     500                 :            :                 {
     501 [ +  - ][ +  - ]:         33 :                     _onTopOfLine = (aCharRect.*fnRect->fnGetTop)();
     502                 :            :                 }
     503                 :            :                 else
     504                 :            :                 {
     505                 :         33 :                     bRet = false;
     506                 :            :                 }
     507                 :            :             }
     508                 :            :             else
     509                 :            :             {
     510                 :            :                 // assure that text frame is in a horizontal layout
     511         [ +  - ]:        197 :                 SwFrmSwapper aSwapper( pFrm, sal_True );
     512                 :            :                 // determine text line that contains the requested position
     513         [ +  - ]:        197 :                 SwTxtSizeInfo aInf( pFrm );
     514         [ +  - ]:        197 :                 SwTxtCursor aLine( pFrm, &aInf );
     515         [ +  - ]:        197 :                 aLine.CharCrsrToLine( nOffset );
     516                 :            :                 // determine top of line
     517                 :        197 :                 _onTopOfLine = aLine.Y();
     518         [ -  + ]:        197 :                 if ( bVert )
     519                 :            :                 {
     520         [ #  # ]:          0 :                     _onTopOfLine = pFrm->SwitchHorizontalToVertical( _onTopOfLine );
     521 [ +  - ][ +  - ]:        197 :                 }
     522                 :            :             }
     523                 :            :         }
     524                 :            :     }
     525                 :            : 
     526                 :        254 :     return bRet;
     527                 :            : }
     528                 :            : 
     529                 :            : /*************************************************************************
     530                 :            :  *                      SwTxtFrm::_GetCrsrOfst()
     531                 :            :  *************************************************************************/
     532                 :            : 
     533                 :            : // Minimum distance of non-empty lines is a little less than 2 cm
     534                 :            : #define FILL_MIN_DIST 1100
     535                 :            : 
     536                 :            : struct SwFillData
     537                 :            : {
     538                 :            :     SwRect aFrm;
     539                 :            :     const SwCrsrMoveState *pCMS;
     540                 :            :     SwPosition* pPos;
     541                 :            :     const Point& rPoint;
     542                 :            :     SwTwips nLineWidth;
     543                 :            :     sal_Bool bFirstLine : 1;
     544                 :            :     sal_Bool bInner     : 1;
     545                 :            :     sal_Bool bColumn    : 1;
     546                 :            :     sal_Bool bEmpty     : 1;
     547                 :          0 :     SwFillData( const SwCrsrMoveState *pC, SwPosition* pP, const SwRect& rR,
     548                 :            :         const Point& rPt ) : aFrm( rR ), pCMS( pC ), pPos( pP ), rPoint( rPt ),
     549                 :            :         nLineWidth( 0 ), bFirstLine( sal_True ), bInner( sal_False ), bColumn( sal_False ),
     550                 :          0 :         bEmpty( sal_True ){}
     551                 :          0 :     SwFillMode Mode() const { return pCMS->pFill->eMode; }
     552                 :          0 :     long X() const { return rPoint.X(); }
     553                 :          0 :     long Y() const { return rPoint.Y(); }
     554                 :          0 :     long Left() const { return aFrm.Left(); }
     555                 :          0 :     long Right() const { return aFrm.Right(); }
     556                 :          0 :     long Bottom() const { return aFrm.Bottom(); }
     557                 :            :     SwRect& Frm() { return aFrm; }
     558                 :          0 :     SwFillCrsrPos &Fill() const { return *pCMS->pFill; }
     559                 :          0 :     void SetTab( MSHORT nNew ) { pCMS->pFill->nTabCnt = nNew; }
     560                 :          0 :     void SetSpace( MSHORT nNew ) { pCMS->pFill->nSpaceCnt = nNew; }
     561                 :          0 :     void SetOrient( const sal_Int16 eNew ){ pCMS->pFill->eOrient = eNew; }
     562                 :            : };
     563                 :            : 
     564                 :        648 : sal_Bool SwTxtFrm::_GetCrsrOfst(SwPosition* pPos, const Point& rPoint,
     565                 :            :                     const sal_Bool bChgFrm, SwCrsrMoveState* pCMS ) const
     566                 :            : {
     567                 :            :     // _GetCrsrOfst is called by GetCrsrOfst and GetKeyCrsrOfst.
     568                 :            :     // Never just a return sal_False.
     569                 :            : 
     570 [ +  + ][ +  - ]:        648 :     if( IsLocked() || IsHiddenNow() )
         [ +  + ][ +  + ]
     571                 :        186 :         return sal_False;
     572                 :            : 
     573         [ +  - ]:        462 :     ((SwTxtFrm*)this)->GetFormatted();
     574                 :            : 
     575                 :        462 :     Point aOldPoint( rPoint );
     576                 :            : 
     577 [ +  - ][ -  + ]:        462 :     if ( IsVertical() )
     578                 :            :     {
     579         [ #  # ]:          0 :         SwitchVerticalToHorizontal( (Point&)rPoint );
     580         [ #  # ]:          0 :         ((SwTxtFrm*)this)->SwapWidthAndHeight();
     581                 :            :     }
     582                 :            : 
     583 [ +  - ][ -  + ]:        462 :     if ( IsRightToLeft() )
     584         [ #  # ]:          0 :         SwitchRTLtoLTR( (Point&)rPoint );
     585                 :            : 
     586                 :            :     SwFillData *pFillData = ( pCMS && pCMS->pFill ) ?
     587 [ +  - ][ -  + ]:        462 :                         new SwFillData( pCMS, pPos, Frm(), rPoint ) : NULL;
                 [ #  # ]
     588                 :            : 
     589         [ +  + ]:        462 :     if ( IsEmpty() )
     590                 :            :     {
     591                 :        240 :         SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
     592         [ +  - ]:        240 :         pPos->nNode = *pTxtNd;
     593 [ +  - ][ +  - ]:        240 :         pPos->nContent.Assign( pTxtNd, 0 );
     594 [ +  - ][ -  + ]:        240 :         if( pCMS && pCMS->bFieldInfo )
     595                 :            :         {
     596                 :          0 :             SwTwips nDiff = rPoint.X() - Frm().Left() - Prt().Left();
     597 [ #  # ][ #  # ]:          0 :             if( nDiff > 50 || nDiff < 0 )
     598                 :          0 :                 ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True;
     599                 :            :         }
     600                 :            :     }
     601                 :            :     else
     602                 :            :     {
     603         [ +  - ]:        222 :         SwTxtSizeInfo aInf( (SwTxtFrm*)this );
     604         [ +  - ]:        222 :         SwTxtCursor  aLine( ((SwTxtFrm*)this), &aInf );
     605                 :            : 
     606                 :            :         // See comment in AdjustFrm()
     607                 :        222 :         SwTwips nMaxY = Frm().Top() + Prt().Top() + Prt().Height();
     608         [ +  - ]:        222 :         aLine.TwipsToLine( rPoint.Y() );
     609         [ -  + ]:        222 :         while( aLine.Y() + aLine.GetLineHeight() > nMaxY )
     610                 :            :         {
     611 [ #  # ][ #  # ]:          0 :             if( !aLine.Prev() )
     612                 :          0 :                 break;
     613                 :            :         }
     614                 :            : 
     615         [ -  + ]:        222 :         if( aLine.GetDropLines() >= aLine.GetLineNr() && 1 != aLine.GetLineNr()
           [ #  #  #  # ]
                 [ -  + ]
     616                 :          0 :             && rPoint.X() < aLine.FirstLeft() + aLine.GetDropLeft() )
     617         [ #  # ]:          0 :             while( aLine.GetLineNr() > 1 )
     618         [ #  # ]:          0 :                 aLine.Prev();
     619                 :            : 
     620         [ +  - ]:        222 :         xub_StrLen nOffset = aLine.GetCrsrOfst( pPos, rPoint, bChgFrm, pCMS );
     621                 :            : 
     622 [ +  - ][ -  + ]:        222 :         if( pCMS && pCMS->eState == MV_NONE && aLine.GetEnd() == nOffset )
         [ #  # ][ -  + ]
     623                 :          0 :             ((SwCrsrMoveState*)pCMS)->eState = MV_RIGHTMARGIN;
     624                 :            : 
     625                 :            :     // pPos is a pure IN parameter and must not be evaluated.
     626                 :            :     // pIter->GetCrsrOfst returns from a nesting with STRING_LEN.
     627                 :            :     // If SwTxtIter::GetCrsrOfst calls GetCrsrOfst further by itself
     628                 :            :     // nNode changes the position.
     629                 :            :     // In such cases, pPos must not be calculated.
     630         [ +  - ]:        222 :         if( STRING_LEN != nOffset )
     631                 :            :         {
     632                 :        222 :             SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
     633         [ +  - ]:        222 :             pPos->nNode = *pTxtNd;
     634 [ +  - ][ +  - ]:        222 :             pPos->nContent.Assign( pTxtNd, nOffset );
     635         [ -  + ]:        222 :             if( pFillData )
     636                 :            :             {
     637   [ #  #  #  # ]:          0 :                 if( pTxtNd->GetTxt().Len() > nOffset ||
                 [ #  # ]
     638                 :          0 :                     rPoint.Y() < Frm().Top() )
     639                 :          0 :                     pFillData->bInner = sal_True;
     640                 :          0 :                 pFillData->bFirstLine = aLine.GetLineNr() < 2;
     641         [ #  # ]:          0 :                 if( pTxtNd->GetTxt().Len() )
     642                 :            :                 {
     643                 :          0 :                     pFillData->bEmpty = sal_False;
     644                 :          0 :                     pFillData->nLineWidth = aLine.GetCurr()->Width();
     645                 :            :                 }
     646                 :            :             }
     647         [ +  - ]:        222 :         }
     648                 :            :     }
     649                 :        462 :     sal_Bool bChgFillData = sal_False;
     650 [ -  + ][ #  # ]:        462 :     if( pFillData && FindPageFrm()->Frm().IsInside( aOldPoint ) )
         [ #  # ][ #  # ]
                 [ -  + ]
     651                 :            :     {
     652         [ #  # ]:          0 :         FillCrsrPos( *pFillData );
     653                 :          0 :         bChgFillData = sal_True;
     654                 :            :     }
     655                 :            : 
     656 [ +  - ][ -  + ]:        462 :     if ( IsVertical() )
     657                 :            :     {
     658         [ #  # ]:          0 :         if ( bChgFillData )
     659         [ #  # ]:          0 :             SwitchHorizontalToVertical( pFillData->Fill().aCrsr.Pos() );
     660         [ #  # ]:          0 :         ((SwTxtFrm*)this)->SwapWidthAndHeight();
     661                 :            :     }
     662                 :            : 
     663 [ +  - ][ -  + ]:        462 :     if ( IsRightToLeft() && bChgFillData )
         [ #  # ][ -  + ]
     664                 :            :     {
     665         [ #  # ]:          0 :             SwitchLTRtoRTL( pFillData->Fill().aCrsr.Pos() );
     666                 :          0 :             const sal_Int16 eOrient = pFillData->pCMS->pFill->eOrient;
     667                 :            : 
     668         [ #  # ]:          0 :             if ( text::HoriOrientation::LEFT == eOrient )
     669                 :          0 :                 pFillData->SetOrient( text::HoriOrientation::RIGHT );
     670         [ #  # ]:          0 :             else if ( text::HoriOrientation::RIGHT == eOrient )
     671                 :          0 :                 pFillData->SetOrient( text::HoriOrientation::LEFT );
     672                 :            :     }
     673                 :            : 
     674                 :        462 :     (Point&)rPoint = aOldPoint;
     675                 :        462 :     delete pFillData;
     676                 :            : 
     677                 :        648 :     return sal_True;
     678                 :            : }
     679                 :            : 
     680                 :            : /*************************************************************************
     681                 :            :  *                 virtual SwTxtFrm::GetCrsrOfst()
     682                 :            :  *************************************************************************/
     683                 :            : 
     684                 :        648 : sal_Bool SwTxtFrm::GetCrsrOfst(SwPosition* pPos, Point& rPoint,
     685                 :            :                                SwCrsrMoveState* pCMS ) const
     686                 :            : {
     687                 :        648 :     MSHORT nChgFrm = 2;
     688         [ +  - ]:        648 :     if( pCMS )
     689                 :            :     {
     690         [ -  + ]:        648 :         if( MV_UPDOWN == pCMS->eState )
     691                 :          0 :             nChgFrm = 0;
     692 [ +  + ][ -  + ]:        648 :         else if( MV_SETONLYTEXT == pCMS->eState ||
     693                 :            :                  MV_TBLSEL == pCMS->eState )
     694                 :        462 :             nChgFrm = 1;
     695                 :            :     }
     696                 :        648 :     return _GetCrsrOfst( pPos, rPoint, nChgFrm != 0, pCMS );
     697                 :            : }
     698                 :            : 
     699                 :            : /*************************************************************************
     700                 :            :  *                      SwTxtFrm::LeftMargin()
     701                 :            :  *************************************************************************/
     702                 :            : 
     703                 :            : /*
     704                 :            :  * Layout-oriented cursor movement to the line start.
     705                 :            :  */
     706                 :            : 
     707                 :          0 : sal_Bool SwTxtFrm::LeftMargin(SwPaM *pPam) const
     708                 :            : {
     709 [ #  # ][ #  # ]:          0 :     if( ((const SwNode*)pPam->GetNode()) != GetNode() )
     710                 :          0 :         pPam->GetPoint()->nNode = *((SwTxtFrm*)this)->GetTxtNode();
     711                 :            : 
     712                 :          0 :     SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *pPam->GetPoint(),
     713                 :          0 :                                      SwTxtCursor::IsRightMargin() );
     714                 :          0 :     pFrm->GetFormatted();
     715                 :            :     xub_StrLen nIndx;
     716         [ #  # ]:          0 :     if ( pFrm->IsEmpty() )
     717                 :          0 :         nIndx = 0;
     718                 :            :     else
     719                 :            :     {
     720         [ #  # ]:          0 :         SwTxtSizeInfo aInf( pFrm );
     721         [ #  # ]:          0 :         SwTxtCursor  aLine( pFrm, &aInf );
     722                 :            : 
     723         [ #  # ]:          0 :         aLine.CharCrsrToLine(pPam->GetPoint()->nContent.GetIndex());
     724                 :          0 :         nIndx = aLine.GetStart();
     725 [ #  # ][ #  # ]:          0 :         if( pFrm->GetOfst() && !pFrm->IsFollow() && !aLine.GetPrev() )
         [ #  # ][ #  # ]
                 [ #  # ]
     726                 :            :         {
     727         [ #  # ]:          0 :             lcl_ChangeOffset( pFrm, 0 );
     728                 :          0 :             nIndx = 0;
     729         [ #  # ]:          0 :         }
     730                 :            :     }
     731 [ #  # ][ #  # ]:          0 :     pPam->GetPoint()->nContent = SwIndex( pFrm->GetTxtNode(), nIndx );
     732                 :          0 :     SwTxtCursor::SetRightMargin( sal_False );
     733                 :          0 :     return sal_True;
     734                 :            : }
     735                 :            : 
     736                 :            : /*************************************************************************
     737                 :            :  *                      SwTxtFrm::RightMargin()
     738                 :            :  *************************************************************************/
     739                 :            : 
     740                 :            : /*
     741                 :            :  * To the line end: That's the position before the last char of the line.
     742                 :            :  * Exception: In the last line, it should be able to place the cursor after
     743                 :            :  * the last char in order to append text.
     744                 :            :  */
     745                 :            : 
     746                 :          0 : sal_Bool SwTxtFrm::RightMargin(SwPaM *pPam, sal_Bool bAPI) const
     747                 :            : {
     748 [ #  # ][ #  # ]:          0 :     if( ((const SwNode*)pPam->GetNode()) != GetNode() )
     749                 :          0 :         pPam->GetPoint()->nNode = *((SwTxtFrm*)this)->GetTxtNode();
     750                 :            : 
     751                 :          0 :     SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *pPam->GetPoint(),
     752                 :          0 :                                      SwTxtCursor::IsRightMargin() );
     753                 :          0 :     pFrm->GetFormatted();
     754                 :            :     xub_StrLen nRightMargin;
     755         [ #  # ]:          0 :     if ( IsEmpty() )
     756                 :          0 :         nRightMargin = 0;
     757                 :            :     else
     758                 :            :     {
     759         [ #  # ]:          0 :         SwTxtSizeInfo aInf( pFrm );
     760         [ #  # ]:          0 :         SwTxtCursor  aLine( pFrm, &aInf );
     761                 :            : 
     762         [ #  # ]:          0 :         aLine.CharCrsrToLine(pPam->GetPoint()->nContent.GetIndex());
     763                 :          0 :         nRightMargin = aLine.GetStart() + aLine.GetCurr()->GetLen();
     764                 :            : 
     765                 :            :         // We skip hard line brakes
     766         [ #  # ]:          0 :         if( aLine.GetCurr()->GetLen() &&
           [ #  #  #  # ]
     767                 :          0 :             CH_BREAK == aInf.GetTxt().GetChar( nRightMargin - 1 ) )
     768                 :          0 :             --nRightMargin;
     769 [ #  # ][ #  # ]:          0 :         else if( !bAPI && (aLine.GetNext() || pFrm->GetFollow()) )
         [ #  # ][ #  # ]
     770                 :            :         {
     771   [ #  #  #  # ]:          0 :             while( nRightMargin > aLine.GetStart() &&
                 [ #  # ]
     772                 :          0 :                 ' ' == aInf.GetTxt().GetChar( nRightMargin - 1 ) )
     773                 :          0 :                 --nRightMargin;
     774         [ #  # ]:          0 :         }
     775                 :            :     }
     776 [ #  # ][ #  # ]:          0 :     pPam->GetPoint()->nContent = SwIndex( pFrm->GetTxtNode(), nRightMargin );
     777                 :          0 :     SwTxtCursor::SetRightMargin( !bAPI );
     778                 :          0 :     return sal_True;
     779                 :            : }
     780                 :            : 
     781                 :            : /*************************************************************************
     782                 :            :  *                      SwTxtFrm::_UnitUp()
     783                 :            :  *************************************************************************/
     784                 :            : 
     785                 :            : // The following two methods try to put the Crsr into the next/succsessive
     786                 :            : // line. If we do not have a preceding/successive line we forward the call
     787                 :            : // to the base class.
     788                 :            : // The Crsr's horizontal justification is done afterwards by the CrsrShell.
     789                 :            : 
     790                 :            : class SwSetToRightMargin
     791                 :            : {
     792                 :            :     sal_Bool bRight;
     793                 :            : public:
     794                 :          4 :     inline SwSetToRightMargin() : bRight( sal_False ) { }
     795                 :          4 :     inline ~SwSetToRightMargin() { SwTxtCursor::SetRightMargin( bRight ); }
     796                 :          0 :     inline void SetRight( const sal_Bool bNew ) { bRight = bNew; }
     797                 :            : };
     798                 :            : 
     799                 :          4 : sal_Bool SwTxtFrm::_UnitUp( SwPaM *pPam, const SwTwips nOffset,
     800                 :            :                             sal_Bool bSetInReadOnly ) const
     801                 :            : {
     802                 :            :     // Set the RightMargin if needed
     803                 :          4 :     SwSetToRightMargin aSet;
     804                 :            : 
     805   [ +  -  -  + ]:          8 :     if( IsInTab() &&
         [ -  + ][ +  - ]
     806                 :          4 :         pPam->GetNode( sal_True )->StartOfSectionNode() !=
     807                 :          4 :         pPam->GetNode( sal_False )->StartOfSectionNode() )
     808                 :            :     {
     809                 :            :         // If the PaM is located within different boxes, we have a table selection,
     810                 :            :         // which is handled by the base class.
     811         [ #  # ]:          0 :         return SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
     812                 :            :     }
     813                 :            : 
     814         [ +  - ]:          4 :     ((SwTxtFrm*)this)->GetFormatted();
     815                 :          4 :     const xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
     816                 :          4 :     SwRect aCharBox;
     817                 :            : 
     818 [ #  # ][ #  # ]:          4 :     if( !IsEmpty() && !IsHiddenNow() )
         [ -  + ][ -  + ]
     819                 :            :     {
     820                 :          0 :         xub_StrLen nFormat = STRING_LEN;
     821                 :          0 :         do
     822                 :            :         {
     823 [ #  # ][ #  # ]:          0 :             if( nFormat != STRING_LEN && !IsFollow() )
                 [ #  # ]
     824         [ #  # ]:          0 :                 lcl_ChangeOffset( ((SwTxtFrm*)this), nFormat );
     825                 :            : 
     826         [ #  # ]:          0 :             SwTxtSizeInfo aInf( (SwTxtFrm*)this );
     827         [ #  # ]:          0 :             SwTxtCursor  aLine( ((SwTxtFrm*)this), &aInf );
     828                 :            : 
     829                 :            :             // Optimize away flys with no flow and IsDummy()
     830         [ #  # ]:          0 :             if( nPos )
     831         [ #  # ]:          0 :                 aLine.CharCrsrToLine( nPos );
     832                 :            :             else
     833         [ #  # ]:          0 :                 aLine.Top();
     834                 :            : 
     835         [ #  # ]:          0 :             const SwLineLayout *pPrevLine = aLine.GetPrevLine();
     836                 :          0 :             const xub_StrLen nStart = aLine.GetStart();
     837         [ #  # ]:          0 :             aLine.GetCharRect( &aCharBox, nPos );
     838                 :            : 
     839 [ #  # ][ #  # ]:          0 :             sal_Bool bSecondOfDouble = ( aInf.IsMulti() && ! aInf.IsFirstMulti() );
     840 [ #  # ][ #  # ]:          0 :             sal_Bool bPrevLine = ( pPrevLine && pPrevLine != aLine.GetCurr() );
     841                 :            : 
     842 [ #  # ][ #  # ]:          0 :             if( !pPrevLine && !bSecondOfDouble && GetOfst() && !IsFollow() )
         [ #  # ][ #  # ]
                 [ #  # ]
     843                 :            :             {
     844                 :          0 :                 nFormat = GetOfst();
     845                 :          0 :                 xub_StrLen nDiff = aLine.GetLength();
     846         [ #  # ]:          0 :                 if( !nDiff )
     847                 :          0 :                     nDiff = MIN_OFFSET_STEP;
     848         [ #  # ]:          0 :                 if( nFormat > nDiff )
     849                 :          0 :                     nFormat = nFormat - nDiff;
     850                 :            :                 else
     851                 :          0 :                     nFormat = 0;
     852                 :          0 :                 continue;
     853                 :            :             }
     854                 :            : 
     855                 :            :             // We select the target line for the cursor, in case we are in a
     856                 :            :             // double line portion, prev line = curr line
     857 [ #  # ][ #  # ]:          0 :             if( bPrevLine && !bSecondOfDouble )
     858                 :            :             {
     859         [ #  # ]:          0 :                 aLine.PrevLine();
     860 [ #  # ][ #  # ]:          0 :                 while ( aLine.GetStart() == nStart &&
           [ #  #  #  # ]
                 [ #  # ]
     861                 :            :                         0 != ( pPrevLine = aLine.GetPrevLine() ) &&
     862                 :          0 :                         pPrevLine != aLine.GetCurr() )
     863         [ #  # ]:          0 :                     aLine.PrevLine();
     864                 :            :             }
     865                 :            : 
     866 [ #  # ][ #  # ]:          0 :             if ( bPrevLine || bSecondOfDouble )
     867                 :            :             {
     868                 :          0 :                 aCharBox.SSize().Width() /= 2;
     869                 :          0 :                 aCharBox.Pos().X() = aCharBox.Pos().X() - 150;
     870                 :            : 
     871                 :            :                 // See comment in SwTxtFrm::GetCrsrOfst()
     872                 :            : #if OSL_DEBUG_LEVEL > 0
     873                 :            :                 const sal_uLong nOldNode = pPam->GetPoint()->nNode.GetIndex();
     874                 :            : #endif
     875                 :            :                 // The node should not be changed
     876                 :            :                 xub_StrLen nTmpOfst = aLine.GetCrsrOfst( pPam->GetPoint(),
     877         [ #  # ]:          0 :                                                          aCharBox.Pos(), sal_False );
     878                 :            : #if OSL_DEBUG_LEVEL > 0
     879                 :            :                 OSL_ENSURE( nOldNode == pPam->GetPoint()->nNode.GetIndex(),
     880                 :            :                         "SwTxtFrm::UnitUp: illegal node change" );
     881                 :            : #endif
     882                 :            : 
     883                 :            :                 // We make sure that we move up.
     884 [ #  # ][ #  # ]:          0 :                 if( nTmpOfst >= nStart && nStart && !bSecondOfDouble )
                 [ #  # ]
     885                 :            :                 {
     886                 :          0 :                     nTmpOfst = nStart;
     887                 :          0 :                     aSet.SetRight( sal_True );
     888                 :            :                 }
     889                 :          0 :                 pPam->GetPoint()->nContent =
     890         [ #  # ]:          0 :                       SwIndex( ((SwTxtFrm*)this)->GetTxtNode(), nTmpOfst );
           [ #  #  #  # ]
                 [ #  # ]
     891                 :          0 :                 return sal_True;
     892                 :            :             }
     893                 :            : 
     894         [ #  # ]:          0 :             if ( IsFollow() )
     895                 :            :             {
     896         [ #  # ]:          0 :                 aLine.GetCharRect( &aCharBox, nPos );
     897                 :          0 :                 aCharBox.SSize().Width() /= 2;
     898                 :            :             }
     899         [ #  # ]:          0 :             break;
              [ #  #  # ]
              [ #  #  # ]
     900                 :            :         } while ( sal_True );
     901                 :            :     }
     902                 :            :     /* If 'this' is a follow and a prev failed, we need to go to the
     903                 :            :      * last line of the master, which is us.
     904                 :            :      * Or: If we are a follow with follow, we need to get the master.
     905                 :            :      */
     906         [ -  + ]:          4 :     if ( IsFollow() )
     907                 :            :     {
     908         [ #  # ]:          0 :         const SwTxtFrm *pTmpPrev = FindMaster();
     909                 :          0 :         xub_StrLen nOffs = GetOfst();
     910         [ #  # ]:          0 :         if( pTmpPrev )
     911                 :            :         {
     912                 :          0 :             ViewShell *pSh = getRootFrm()->GetCurrShell();
     913 [ #  # ][ #  # ]:          0 :             sal_Bool bProtectedAllowed = pSh && pSh->GetViewOptions()->IsCursorInProtectedArea();
     914                 :          0 :             const SwTxtFrm *pPrevPrev = pTmpPrev;
     915                 :            :             // We skip protected frames and frames without content here
     916 [ #  # ][ #  # ]:          0 :             while( pPrevPrev && ( pPrevPrev->GetOfst() == nOffs ||
         [ #  # ][ #  # ]
                 [ #  # ]
     917         [ #  # ]:          0 :                    ( !bProtectedAllowed && pPrevPrev->IsProtected() ) ) )
     918                 :            :             {
     919                 :          0 :                 pTmpPrev = pPrevPrev;
     920                 :          0 :                 nOffs = pTmpPrev->GetOfst();
     921         [ #  # ]:          0 :                 if ( pPrevPrev->IsFollow() )
     922         [ #  # ]:          0 :                     pPrevPrev = pTmpPrev->FindMaster();
     923                 :            :                 else
     924                 :          0 :                     pPrevPrev = NULL;
     925                 :            :             }
     926         [ #  # ]:          0 :             if ( !pPrevPrev )
     927         [ #  # ]:          0 :                 return pTmpPrev->SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
     928                 :          0 :             aCharBox.Pos().Y() = pPrevPrev->Frm().Bottom() - 1;
     929         [ #  # ]:          0 :             return pPrevPrev->GetKeyCrsrOfst( pPam->GetPoint(), aCharBox.Pos() );
     930                 :            :         }
     931                 :            :     }
     932         [ +  - ]:          4 :     return SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
     933                 :            : }
     934                 :            : 
     935                 :            : //
     936                 :            : // Used for Bidi. nPos is the logical position in the string, bLeft indicates
     937                 :            : // if left arrow or right arrow was pressed. The return values are:
     938                 :            : // nPos: the new visual position
     939                 :            : // bLeft: whether the break iterator has to add or subtract from the
     940                 :            : //        current position
     941                 :          0 : void lcl_VisualMoveRecursion( const SwLineLayout& rCurrLine, xub_StrLen nIdx,
     942                 :            :                               xub_StrLen& nPos, sal_Bool& bRight,
     943                 :            :                               sal_uInt8& nCrsrLevel, sal_uInt8 nDefaultDir )
     944                 :            : {
     945                 :          0 :     const SwLinePortion* pPor = rCurrLine.GetFirstPortion();
     946                 :          0 :     const SwLinePortion* pLast = 0;
     947                 :            : 
     948                 :            :     // What's the current portion?
     949 [ #  # ][ #  # ]:          0 :     while ( pPor && nIdx + pPor->GetLen() <= nPos )
                 [ #  # ]
     950                 :            :     {
     951                 :          0 :         nIdx = nIdx + pPor->GetLen();
     952                 :          0 :         pLast = pPor;
     953                 :          0 :         pPor = pPor->GetPortion();
     954                 :            :     }
     955                 :            : 
     956         [ #  # ]:          0 :     if ( bRight )
     957                 :            :     {
     958                 :          0 :         sal_Bool bRecurse = pPor && pPor->IsMultiPortion() &&
     959   [ #  #  #  # ]:          0 :                            ((SwMultiPortion*)pPor)->IsBidi();
                 [ #  # ]
     960                 :            : 
     961                 :            :         // 1. special case: at beginning of bidi portion
     962 [ #  # ][ #  # ]:          0 :         if ( bRecurse && nIdx == nPos )
     963                 :            :         {
     964                 :          0 :             nPos = nPos + pPor->GetLen();
     965                 :            : 
     966                 :            :             // leave bidi portion
     967         [ #  # ]:          0 :             if ( nCrsrLevel != nDefaultDir )
     968                 :            :             {
     969                 :          0 :                 bRecurse = sal_False;
     970                 :            :             }
     971                 :            :             else
     972                 :            :                 // special case:
     973                 :            :                 // buffer: abcXYZ123 in LTR paragraph
     974                 :            :                 // view:   abc123ZYX
     975                 :            :                 // cursor is between c and X in the buffer and cursor level = 0
     976                 :          0 :                 nCrsrLevel++;
     977                 :            :         }
     978                 :            : 
     979                 :            :         // 2. special case: at beginning of portion after bidi portion
     980         [ #  # ]:          0 :         else if ( pLast && pLast->IsMultiPortion() &&
           [ #  #  #  # ]
         [ #  # ][ #  # ]
     981                 :          0 :                  ((SwMultiPortion*)pLast)->IsBidi() && nIdx == nPos )
     982                 :            :         {
     983                 :            :             // enter bidi portion
     984         [ #  # ]:          0 :             if ( nCrsrLevel != nDefaultDir )
     985                 :            :             {
     986                 :          0 :                 bRecurse = sal_True;
     987                 :          0 :                 nIdx = nIdx - pLast->GetLen();
     988                 :          0 :                 pPor = pLast;
     989                 :            :             }
     990                 :            :         }
     991                 :            : 
     992                 :            :         // Recursion
     993         [ #  # ]:          0 :         if ( bRecurse )
     994                 :            :         {
     995                 :          0 :             const SwLineLayout& rLine = ((SwMultiPortion*)pPor)->GetRoot();
     996                 :          0 :             xub_StrLen nTmpPos = nPos - nIdx;
     997                 :          0 :             sal_Bool bTmpForward = ! bRight;
     998                 :          0 :             sal_uInt8 nTmpCrsrLevel = nCrsrLevel;
     999                 :            :             lcl_VisualMoveRecursion( rLine, 0, nTmpPos, bTmpForward,
    1000         [ #  # ]:          0 :                                      nTmpCrsrLevel, nDefaultDir + 1 );
    1001                 :            : 
    1002                 :          0 :             nPos = nTmpPos + nIdx;
    1003                 :          0 :             bRight = bTmpForward;
    1004                 :          0 :             nCrsrLevel = nTmpCrsrLevel;
    1005                 :            :         }
    1006                 :            : 
    1007                 :            :         // go forward
    1008                 :            :         else
    1009                 :            :         {
    1010                 :          0 :             bRight = sal_True;
    1011                 :          0 :             nCrsrLevel = nDefaultDir;
    1012                 :            :         }
    1013                 :            : 
    1014                 :            :     }
    1015                 :            :     else
    1016                 :            :     {
    1017 [ #  # ][ #  # ]:          0 :         sal_Bool bRecurse = pPor && pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->IsBidi();
                 [ #  # ]
    1018                 :            : 
    1019                 :            :         // 1. special case: at beginning of bidi portion
    1020 [ #  # ][ #  # ]:          0 :         if ( bRecurse && nIdx == nPos )
    1021                 :            :         {
    1022                 :            :             // leave bidi portion
    1023         [ #  # ]:          0 :             if ( nCrsrLevel == nDefaultDir )
    1024                 :            :             {
    1025                 :          0 :                 bRecurse = sal_False;
    1026                 :            :             }
    1027                 :            :         }
    1028                 :            : 
    1029                 :            :         // 2. special case: at beginning of portion after bidi portion
    1030         [ #  # ]:          0 :         else if ( pLast && pLast->IsMultiPortion() &&
           [ #  #  #  # ]
         [ #  # ][ #  # ]
    1031                 :          0 :                  ((SwMultiPortion*)pLast)->IsBidi() && nIdx == nPos )
    1032                 :            :         {
    1033                 :          0 :             nPos = nPos - pLast->GetLen();
    1034                 :            : 
    1035                 :            :             // enter bidi portion
    1036         [ #  # ]:          0 :             if ( nCrsrLevel % 2 == nDefaultDir % 2 )
    1037                 :            :             {
    1038                 :          0 :                 bRecurse = sal_True;
    1039                 :          0 :                 nIdx = nIdx - pLast->GetLen();
    1040                 :          0 :                 pPor = pLast;
    1041                 :            : 
    1042                 :            :                 // special case:
    1043                 :            :                 // buffer: abcXYZ123 in LTR paragraph
    1044                 :            :                 // view:   abc123ZYX
    1045                 :            :                 // cursor is behind 3 in the buffer and cursor level = 2
    1046         [ #  # ]:          0 :                 if ( nDefaultDir + 2 == nCrsrLevel )
    1047                 :          0 :                     nPos = nPos + pLast->GetLen();
    1048                 :            :             }
    1049                 :            :         }
    1050                 :            : 
    1051                 :            :         // go forward
    1052         [ #  # ]:          0 :         if ( bRecurse )
    1053                 :            :         {
    1054                 :          0 :             const SwLineLayout& rLine = ((SwMultiPortion*)pPor)->GetRoot();
    1055                 :          0 :             xub_StrLen nTmpPos = nPos - nIdx;
    1056                 :          0 :             sal_Bool bTmpForward = ! bRight;
    1057                 :          0 :             sal_uInt8 nTmpCrsrLevel = nCrsrLevel;
    1058                 :            :             lcl_VisualMoveRecursion( rLine, 0, nTmpPos, bTmpForward,
    1059         [ #  # ]:          0 :                                      nTmpCrsrLevel, nDefaultDir + 1 );
    1060                 :            : 
    1061                 :            :             // special case:
    1062                 :            :             // buffer: abcXYZ123 in LTR paragraph
    1063                 :            :             // view:   abc123ZYX
    1064                 :            :             // cursor is between Z and 1 in the buffer and cursor level = 2
    1065 [ #  # ][ #  # ]:          0 :             if ( nTmpPos == pPor->GetLen() && nTmpCrsrLevel == nDefaultDir + 1 )
                 [ #  # ]
    1066                 :            :             {
    1067                 :          0 :                 nTmpPos = nTmpPos - pPor->GetLen();
    1068                 :          0 :                 nTmpCrsrLevel = nDefaultDir;
    1069                 :          0 :                 bTmpForward = ! bTmpForward;
    1070                 :            :             }
    1071                 :            : 
    1072                 :          0 :             nPos = nTmpPos + nIdx;
    1073                 :          0 :             bRight = bTmpForward;
    1074                 :          0 :             nCrsrLevel = nTmpCrsrLevel;
    1075                 :            :         }
    1076                 :            : 
    1077                 :            :         // go backward
    1078                 :            :         else
    1079                 :            :         {
    1080                 :          0 :             bRight = sal_False;
    1081                 :          0 :             nCrsrLevel = nDefaultDir;
    1082                 :            :         }
    1083                 :            :     }
    1084                 :          0 : }
    1085                 :            : 
    1086                 :          0 : void SwTxtFrm::PrepareVisualMove( xub_StrLen& nPos, sal_uInt8& nCrsrLevel,
    1087                 :            :                                   sal_Bool& bForward, sal_Bool bInsertCrsr )
    1088                 :            : {
    1089 [ #  # ][ #  # ]:          0 :     if( IsEmpty() || IsHiddenNow() )
         [ #  # ][ #  # ]
    1090                 :            :         return;
    1091                 :            : 
    1092         [ #  # ]:          0 :     ((SwTxtFrm*)this)->GetFormatted();
    1093                 :            : 
    1094         [ #  # ]:          0 :     SwTxtSizeInfo aInf( (SwTxtFrm*)this );
    1095         [ #  # ]:          0 :     SwTxtCursor  aLine( ((SwTxtFrm*)this), &aInf );
    1096                 :            : 
    1097         [ #  # ]:          0 :     if( nPos )
    1098         [ #  # ]:          0 :         aLine.CharCrsrToLine( nPos );
    1099                 :            :     else
    1100         [ #  # ]:          0 :         aLine.Top();
    1101                 :            : 
    1102                 :          0 :     const SwLineLayout* pLine = aLine.GetCurr();
    1103                 :          0 :     const xub_StrLen nStt = aLine.GetStart();
    1104                 :          0 :     const xub_StrLen nLen = pLine->GetLen();
    1105                 :            : 
    1106                 :            :     // We have to distinguish between an insert and overwrite cursor:
    1107                 :            :     // The insert cursor position depends on the cursor level:
    1108                 :            :     // buffer:  abcXYZdef in LTR paragraph
    1109                 :            :     // display: abcZYXdef
    1110                 :            :     // If cursor is between c and X in the buffer and cursor level is 0,
    1111                 :            :     // the cursor blinks between c and Z and -> sets the cursor between Z and Y.
    1112                 :            :     // If the cursor level is 1, the cursor blinks between X and d and
    1113                 :            :     // -> sets the cursor between d and e.
    1114                 :            :     // The overwrite cursor simply travels to the next visual character.
    1115         [ #  # ]:          0 :     if ( bInsertCrsr )
    1116                 :            :     {
    1117                 :            :         lcl_VisualMoveRecursion( *pLine, nStt, nPos, bForward,
    1118 [ #  # ][ #  # ]:          0 :                                  nCrsrLevel, IsRightToLeft() ? 1 : 0 );
                 [ #  # ]
    1119                 :            :         return;
    1120                 :            :     }
    1121                 :            : 
    1122 [ #  # ][ #  # ]:          0 :     const sal_uInt8 nDefaultDir = static_cast<sal_uInt8>(IsRightToLeft() ? UBIDI_RTL : UBIDI_LTR);
    1123                 :            :     const sal_Bool bVisualRight = ( nDefaultDir == UBIDI_LTR && bForward ) ||
    1124 [ #  # ][ #  # ]:          0 :                                   ( nDefaultDir == UBIDI_RTL && ! bForward );
         [ #  # ][ #  # ]
    1125                 :            : 
    1126                 :            :     //
    1127                 :            :     // Bidi functions from icu 2.0
    1128                 :            :     //
    1129                 :          0 :     const sal_Unicode* pLineString = GetTxtNode()->GetTxt().GetBuffer();
    1130                 :          0 :     pLine += nStt;
    1131                 :            : 
    1132                 :          0 :     UErrorCode nError = U_ZERO_ERROR;
    1133         [ #  # ]:          0 :     UBiDi* pBidi = ubidi_openSized( nLen, 0, &nError );
    1134         [ #  # ]:          0 :     ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString), nLen, nDefaultDir, NULL, &nError ); // UChar != sal_Unicode in MinGW
    1135                 :            : 
    1136                 :            :     xub_StrLen nTmpPos;
    1137                 :          0 :     sal_Bool bOutOfBounds = sal_False;
    1138                 :            : 
    1139         [ #  # ]:          0 :     if ( nPos < nStt + nLen )
    1140                 :            :     {
    1141         [ #  # ]:          0 :         nTmpPos = (xub_StrLen)ubidi_getVisualIndex( pBidi, nPos, &nError );
    1142                 :            : 
    1143                 :            :         // visual indices are always LTR aligned
    1144         [ #  # ]:          0 :         if ( bVisualRight )
    1145                 :            :         {
    1146         [ #  # ]:          0 :             if ( nTmpPos + 1 < nStt + nLen )
    1147                 :          0 :                 ++nTmpPos;
    1148                 :            :             else
    1149                 :            :             {
    1150         [ #  # ]:          0 :                 nPos = nDefaultDir == UBIDI_RTL ? 0 : nStt + nLen;
    1151                 :          0 :                 bOutOfBounds = sal_True;
    1152                 :            :             }
    1153                 :            :         }
    1154                 :            :         else
    1155                 :            :         {
    1156         [ #  # ]:          0 :             if ( nTmpPos )
    1157                 :          0 :                 --nTmpPos;
    1158                 :            :             else
    1159                 :            :             {
    1160         [ #  # ]:          0 :                 nPos = nDefaultDir == UBIDI_RTL ? nStt + nLen : 0;
    1161                 :          0 :                 bOutOfBounds = sal_True;
    1162                 :            :             }
    1163                 :            :         }
    1164                 :            :     }
    1165                 :            :     else
    1166                 :            :     {
    1167         [ #  # ]:          0 :         nTmpPos = nDefaultDir == UBIDI_LTR ? nPos - 1 : 0;
    1168                 :            :     }
    1169                 :            : 
    1170         [ #  # ]:          0 :     if ( ! bOutOfBounds )
    1171                 :            :     {
    1172         [ #  # ]:          0 :         nPos = (xub_StrLen)ubidi_getLogicalIndex( pBidi, nTmpPos, &nError );
    1173                 :            : 
    1174         [ #  # ]:          0 :         if ( bForward )
    1175                 :            :         {
    1176         [ #  # ]:          0 :             if ( nPos )
    1177                 :          0 :                 --nPos;
    1178                 :            :             else
    1179                 :            :             {
    1180                 :          0 :                 ++nPos;
    1181                 :          0 :                 bForward = ! bForward;
    1182                 :            :             }
    1183                 :            :         }
    1184                 :            :         else
    1185                 :          0 :             ++nPos;
    1186                 :            :     }
    1187                 :            : 
    1188 [ #  # ][ #  # ]:          0 :     ubidi_close( pBidi );
         [ #  # ][ #  # ]
    1189                 :            : }
    1190                 :            : 
    1191                 :            : /*************************************************************************
    1192                 :            :  *                      SwTxtFrm::_UnitDown()
    1193                 :            :  *************************************************************************/
    1194                 :            : 
    1195                 :          2 : sal_Bool SwTxtFrm::_UnitDown(SwPaM *pPam, const SwTwips nOffset,
    1196                 :            :                             sal_Bool bSetInReadOnly ) const
    1197                 :            : {
    1198                 :            : 
    1199         [ +  - ]:          4 :     if ( IsInTab() &&
           [ +  -  -  + ]
                 [ -  + ]
    1200                 :          2 :         pPam->GetNode( sal_True )->StartOfSectionNode() !=
    1201                 :          2 :         pPam->GetNode( sal_False )->StartOfSectionNode() )
    1202                 :            :     {
    1203                 :            :         // If the PaM is located within different boxes, we have a table selection,
    1204                 :            :         // which is handled by the base class.
    1205         [ #  # ]:          0 :         return SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
    1206                 :            :     }
    1207         [ +  - ]:          2 :     ((SwTxtFrm*)this)->GetFormatted();
    1208                 :          2 :     const xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
    1209                 :          2 :     SwRect aCharBox;
    1210                 :          2 :     const SwCntntFrm *pTmpFollow = 0;
    1211                 :            : 
    1212 [ -  + ][ +  - ]:          2 :     if ( IsVertical() )
    1213         [ #  # ]:          0 :         ((SwTxtFrm*)this)->SwapWidthAndHeight();
    1214                 :            : 
    1215 [ +  - ][ +  - ]:          2 :     if ( !IsEmpty() && !IsHiddenNow() )
         [ +  - ][ +  - ]
    1216                 :            :     {
    1217                 :          2 :         xub_StrLen nFormat = STRING_LEN;
    1218                 :          0 :         do
    1219                 :            :         {
    1220 [ -  + ][ #  # ]:          2 :             if( nFormat != STRING_LEN && !IsFollow() &&
         [ #  # ][ +  - ]
    1221         [ #  # ]:          0 :                 !lcl_ChangeOffset( ((SwTxtFrm*)this), nFormat ) )
    1222                 :            :                 break;
    1223                 :            : 
    1224         [ +  - ]:          2 :             SwTxtSizeInfo aInf( (SwTxtFrm*)this );
    1225         [ +  - ]:          2 :             SwTxtCursor  aLine( ((SwTxtFrm*)this), &aInf );
    1226                 :          2 :             nFormat = aLine.GetEnd();
    1227                 :            : 
    1228         [ +  - ]:          2 :             aLine.CharCrsrToLine( nPos );
    1229                 :            : 
    1230         [ +  - ]:          2 :             const SwLineLayout* pNextLine = aLine.GetNextLine();
    1231                 :          2 :             const xub_StrLen nStart = aLine.GetStart();
    1232         [ +  - ]:          2 :             aLine.GetCharRect( &aCharBox, nPos );
    1233                 :            : 
    1234 [ -  + ][ #  # ]:          2 :             sal_Bool bFirstOfDouble = ( aInf.IsMulti() && aInf.IsFirstMulti() );
    1235                 :            : 
    1236 [ +  - ][ -  + ]:          2 :             if( pNextLine || bFirstOfDouble )
    1237                 :            :             {
    1238                 :          0 :                 aCharBox.SSize().Width() /= 2;
    1239                 :            : #if OSL_DEBUG_LEVEL > 0
    1240                 :            :                 // See comment in SwTxtFrm::GetCrsrOfst()
    1241                 :            :                 const sal_uLong nOldNode = pPam->GetPoint()->nNode.GetIndex();
    1242                 :            : #endif
    1243 [ #  # ][ #  # ]:          0 :                 if ( pNextLine && ! bFirstOfDouble )
    1244         [ #  # ]:          0 :                     aLine.NextLine();
    1245                 :            : 
    1246                 :            :                 xub_StrLen nTmpOfst = aLine.GetCrsrOfst( pPam->GetPoint(),
    1247         [ #  # ]:          0 :                                  aCharBox.Pos(), sal_False );
    1248                 :            : #if OSL_DEBUG_LEVEL > 0
    1249                 :            :                 OSL_ENSURE( nOldNode == pPam->GetPoint()->nNode.GetIndex(),
    1250                 :            :                     "SwTxtFrm::UnitDown: illegal node change" );
    1251                 :            : #endif
    1252                 :            : 
    1253                 :            :                 // We make sure that we move down.
    1254 [ #  # ][ #  # ]:          0 :                 if( nTmpOfst <= nStart && ! bFirstOfDouble )
    1255                 :          0 :                     nTmpOfst = nStart + 1;
    1256                 :          0 :                 pPam->GetPoint()->nContent =
    1257         [ #  # ]:          0 :                       SwIndex( ((SwTxtFrm*)this)->GetTxtNode(), nTmpOfst );
           [ #  #  #  # ]
                 [ #  # ]
    1258                 :            : 
    1259 [ #  # ][ #  # ]:          0 :                 if ( IsVertical() )
    1260         [ #  # ]:          0 :                     ((SwTxtFrm*)this)->SwapWidthAndHeight();
    1261                 :            : 
    1262                 :          0 :                 return sal_True;
    1263                 :            :             }
    1264         [ -  + ]:          2 :             if( 0 != ( pTmpFollow = GetFollow() ) )
    1265                 :            :             {   // Skip protected follows
    1266                 :          0 :                 const SwCntntFrm* pTmp = pTmpFollow;
    1267                 :          0 :                 ViewShell *pSh = getRootFrm()->GetCurrShell();
    1268 [ #  # ][ #  # ]:          0 :                 if( !pSh || !pSh->GetViewOptions()->IsCursorInProtectedArea() )
                 [ #  # ]
    1269                 :            :                 {
    1270 [ #  # ][ #  # ]:          0 :                     while( pTmpFollow && pTmpFollow->IsProtected() )
         [ #  # ][ #  # ]
    1271                 :            :                     {
    1272                 :          0 :                         pTmp = pTmpFollow;
    1273                 :          0 :                         pTmpFollow = pTmpFollow->GetFollow();
    1274                 :            :                     }
    1275                 :            :                 }
    1276         [ #  # ]:          0 :                 if( !pTmpFollow ) // Only protected ones left
    1277                 :            :                 {
    1278 [ #  # ][ #  # ]:          0 :                     if ( IsVertical() )
    1279         [ #  # ]:          0 :                         ((SwTxtFrm*)this)->SwapWidthAndHeight();
    1280         [ #  # ]:          0 :                     return pTmp->SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
    1281                 :            :                 }
    1282                 :            : 
    1283         [ #  # ]:          0 :                 aLine.GetCharRect( &aCharBox, nPos );
    1284                 :          0 :                 aCharBox.SSize().Width() /= 2;
    1285                 :            :             }
    1286         [ +  - ]:          2 :             else if( !IsFollow() )
    1287                 :            :             {
    1288                 :          2 :                 xub_StrLen nTmpLen = aInf.GetTxt().Len();
    1289         [ -  + ]:          2 :                 if( aLine.GetEnd() < nTmpLen )
    1290                 :            :                 {
    1291         [ #  # ]:          0 :                     if( nFormat <= GetOfst() )
    1292                 :            :                     {
    1293                 :          0 :                         nFormat = Min( xub_StrLen( GetOfst() + MIN_OFFSET_STEP ),
    1294                 :          0 :                                        nTmpLen );
    1295         [ #  # ]:          0 :                         if( nFormat <= GetOfst() )
    1296                 :            :                             break;
    1297                 :            :                     }
    1298                 :          2 :                     continue;
    1299                 :            :                 }
    1300                 :            :             }
    1301         [ +  - ]:          2 :             break;
              [ -  +  - ]
              [ +  -  - ]
    1302                 :            :         } while( sal_True );
    1303                 :            :     }
    1304                 :            :     else
    1305                 :          0 :         pTmpFollow = GetFollow();
    1306                 :            : 
    1307 [ +  - ][ -  + ]:          2 :     if ( IsVertical() )
    1308         [ #  # ]:          0 :         ((SwTxtFrm*)this)->SwapWidthAndHeight();
    1309                 :            : 
    1310                 :            :     // We take a shortcut for follows
    1311         [ -  + ]:          2 :     if( pTmpFollow )
    1312                 :            :     {
    1313                 :          0 :         aCharBox.Pos().Y() = pTmpFollow->Frm().Top() + 1;
    1314                 :            :         return ((SwTxtFrm*)pTmpFollow)->GetKeyCrsrOfst( pPam->GetPoint(),
    1315         [ #  # ]:          0 :                                                      aCharBox.Pos() );
    1316                 :            :     }
    1317         [ +  - ]:          2 :     return SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
    1318                 :            : }
    1319                 :            : 
    1320                 :            : /*************************************************************************
    1321                 :            :  *                   virtual SwTxtFrm::UnitUp()
    1322                 :            :  *************************************************************************/
    1323                 :            : 
    1324                 :          4 : sal_Bool SwTxtFrm::UnitUp(SwPaM *pPam, const SwTwips nOffset,
    1325                 :            :                             sal_Bool bSetInReadOnly ) const
    1326                 :            : {
    1327                 :            :     /* We call CntntNode::GertFrm() in CrsrSh::Up().
    1328                 :            :      * This _always returns the master.
    1329                 :            :      * In order to not mess with cursor travelling, we correct here
    1330                 :            :      * in SwTxtFrm.
    1331                 :            :      * We calculate UnitUp for pFrm. pFrm is either a master (= this) or a
    1332                 :            :      * follow (!= this).
    1333                 :            :      */
    1334                 :          4 :     const SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *(pPam->GetPoint()),
    1335                 :          8 :                                            SwTxtCursor::IsRightMargin() );
    1336                 :          4 :     const sal_Bool bRet = pFrm->_UnitUp( pPam, nOffset, bSetInReadOnly );
    1337                 :            : 
    1338                 :            :     // No SwTxtCursor::SetRightMargin( sal_False );
    1339                 :            :     // Instead we have a SwSetToRightMargin in _UnitUp
    1340                 :          4 :     return bRet;
    1341                 :            : }
    1342                 :            : 
    1343                 :            : /*************************************************************************
    1344                 :            :  *                   virtual SwTxtFrm::UnitDown()
    1345                 :            :  *************************************************************************/
    1346                 :            : 
    1347                 :          2 : sal_Bool SwTxtFrm::UnitDown(SwPaM *pPam, const SwTwips nOffset,
    1348                 :            :                             sal_Bool bSetInReadOnly ) const
    1349                 :            : {
    1350                 :          2 :     const SwTxtFrm *pFrm = GetAdjFrmAtPos((SwTxtFrm*)this, *(pPam->GetPoint()),
    1351                 :          4 :                                            SwTxtCursor::IsRightMargin() );
    1352                 :          2 :     const sal_Bool bRet = pFrm->_UnitDown( pPam, nOffset, bSetInReadOnly );
    1353                 :          2 :     SwTxtCursor::SetRightMargin( sal_False );
    1354                 :          2 :     return bRet;
    1355                 :            : }
    1356                 :            : 
    1357                 :          0 : void SwTxtFrm::FillCrsrPos( SwFillData& rFill ) const
    1358                 :            : {
    1359 [ #  # ][ #  # ]:          0 :     if( !rFill.bColumn && GetUpper()->IsColBodyFrm() ) // ColumnFrms now with BodyFrm
                 [ #  # ]
    1360                 :            :     {
    1361                 :            :         const SwColumnFrm* pTmp =
    1362                 :          0 :             (SwColumnFrm*)GetUpper()->GetUpper()->GetUpper()->Lower(); // The 1st column
    1363                 :            :         // The first SwFrm in BodyFrm of the first column
    1364                 :          0 :         const SwFrm* pFrm = ((SwLayoutFrm*)pTmp->Lower())->Lower();
    1365                 :          0 :         MSHORT nNextCol = 0;
    1366                 :            :         // In which column do we end up in?
    1367 [ #  # ][ #  # ]:          0 :         while( rFill.X() > pTmp->Frm().Right() && pTmp->GetNext() )
                 [ #  # ]
    1368                 :            :         {
    1369                 :          0 :             pTmp = (SwColumnFrm*)pTmp->GetNext();
    1370         [ #  # ]:          0 :             if( ((SwLayoutFrm*)pTmp->Lower())->Lower() ) // ColumnFrms now with BodyFrm
    1371                 :            :             {
    1372                 :          0 :                 pFrm = ((SwLayoutFrm*)pTmp->Lower())->Lower();
    1373                 :          0 :                 nNextCol = 0;
    1374                 :            :             }
    1375                 :            :             else
    1376                 :          0 :                 ++nNextCol; // Empty columns require column brakes
    1377                 :            :         }
    1378         [ #  # ]:          0 :         if( pTmp != GetUpper()->GetUpper() ) // Did we end up in another column?
    1379                 :            :         {
    1380         [ #  # ]:          0 :             if( !pFrm )
    1381                 :            :                 return;
    1382         [ #  # ]:          0 :             if( nNextCol )
    1383                 :            :             {
    1384         [ #  # ]:          0 :                 while( pFrm->GetNext() )
    1385                 :          0 :                     pFrm = pFrm->GetNext();
    1386                 :            :             }
    1387                 :            :             else
    1388                 :            :             {
    1389 [ #  # ][ #  # ]:          0 :                 while( pFrm->GetNext() && pFrm->Frm().Bottom() < rFill.Y() )
                 [ #  # ]
    1390                 :          0 :                     pFrm = pFrm->GetNext();
    1391                 :            :             }
    1392                 :            :             // No filling, if the last frame in the targeted column does
    1393                 :            :             // not contain a paragraph, but e.g. a table
    1394         [ #  # ]:          0 :             if( pFrm->IsTxtFrm() )
    1395                 :            :             {
    1396                 :          0 :                 rFill.Fill().nColumnCnt = nNextCol;
    1397                 :          0 :                 rFill.bColumn = sal_True;
    1398         [ #  # ]:          0 :                 if( rFill.pPos )
    1399                 :            :                 {
    1400                 :          0 :                     SwTxtNode* pTxtNd = ((SwTxtFrm*)pFrm)->GetTxtNode();
    1401         [ #  # ]:          0 :                     rFill.pPos->nNode = *pTxtNd;
    1402 [ #  # ][ #  # ]:          0 :                     rFill.pPos->nContent.Assign( pTxtNd, pTxtNd->GetTxt().Len() );
    1403                 :            :                 }
    1404         [ #  # ]:          0 :                 if( nNextCol )
    1405                 :            :                 {
    1406                 :          0 :                     rFill.aFrm = pTmp->Prt();
    1407                 :          0 :                     rFill.aFrm += pTmp->Frm().Pos();
    1408                 :            :                 }
    1409                 :            :                 else
    1410                 :          0 :                     rFill.aFrm = pFrm->Frm();
    1411         [ #  # ]:          0 :                 ((SwTxtFrm*)pFrm)->FillCrsrPos( rFill );
    1412                 :            :             }
    1413                 :            :             return;
    1414                 :            :         }
    1415                 :            :     }
    1416                 :          0 :     sal_Bool bFill = sal_True;
    1417                 :            :     SwFont *pFnt;
    1418                 :          0 :     SwTxtFmtColl* pColl = GetTxtNode()->GetTxtColl();
    1419 [ #  # ][ #  # ]:          0 :     MSHORT nFirst = GetTxtNode()->GetSwAttrSet().GetULSpace().GetLower();
    1420                 :          0 :     SwTwips nDiff = rFill.Y() - Frm().Bottom();
    1421         [ #  # ]:          0 :     if( nDiff < nFirst )
    1422                 :          0 :         nDiff = -1;
    1423                 :            :     else
    1424                 :          0 :         pColl = &pColl->GetNextTxtFmtColl();
    1425         [ #  # ]:          0 :     SwAttrSet aSet( ((SwDoc*)GetTxtNode()->GetDoc())->GetAttrPool(), aTxtFmtCollSetRange );
    1426                 :          0 :     const SwAttrSet* pSet = &pColl->GetAttrSet();
    1427                 :          0 :     ViewShell *pSh = getRootFrm()->GetCurrShell();
    1428 [ #  # ][ #  # ]:          0 :     if( GetTxtNode()->HasSwAttrSet() )
    1429                 :            :     {
    1430 [ #  # ][ #  # ]:          0 :         aSet.Put( *GetTxtNode()->GetpSwAttrSet() );
    1431                 :          0 :         aSet.SetParent( pSet );
    1432                 :          0 :         pSet = &aSet;
    1433 [ #  # ][ #  # ]:          0 :         pFnt = new SwFont( pSet, GetNode()->getIDocumentSettingAccess() );
                 [ #  # ]
    1434                 :            :     }
    1435                 :            :     else
    1436                 :            :     {
    1437         [ #  # ]:          0 :         SwFontAccess aFontAccess( pColl, pSh );
    1438 [ #  # ][ #  # ]:          0 :         pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
                 [ #  # ]
    1439 [ #  # ][ #  # ]:          0 :         pFnt->ChkMagic( pSh, pFnt->GetActual() );
    1440                 :            :     }
    1441                 :          0 :     OutputDevice* pOut = pSh->GetOut();
    1442 [ #  # ][ #  # ]:          0 :     if( !pSh->GetViewOptions()->getBrowseMode() || pSh->GetViewOptions()->IsPrtFormat() )
                 [ #  # ]
    1443 [ #  # ][ #  # ]:          0 :         pOut = GetTxtNode()->getIDocumentDeviceAccess()->getReferenceDevice( true );
    1444                 :            : 
    1445                 :          0 :     pFnt->SetFntChg( sal_True );
    1446         [ #  # ]:          0 :     pFnt->ChgPhysFnt( pSh, *pOut );
    1447                 :            : 
    1448         [ #  # ]:          0 :     SwTwips nLineHeight = pFnt->GetHeight( pSh, *pOut );
    1449                 :            : 
    1450         [ #  # ]:          0 :     if( nLineHeight )
    1451                 :            :     {
    1452         [ #  # ]:          0 :         const SvxULSpaceItem &rUL = pSet->GetULSpace();
    1453                 :          0 :         SwTwips nDist = Max( rUL.GetLower(), rUL.GetUpper() );
    1454         [ #  # ]:          0 :         if( rFill.Fill().nColumnCnt )
    1455                 :            :         {
    1456                 :          0 :             rFill.aFrm.Height( nLineHeight );
    1457                 :          0 :             nDiff = rFill.Y() - rFill.Bottom();
    1458                 :          0 :             nFirst = 0;
    1459                 :            :         }
    1460         [ #  # ]:          0 :         else if( nDist < nFirst )
    1461                 :          0 :             nFirst = nFirst - (sal_uInt16)nDist;
    1462                 :            :         else
    1463                 :          0 :             nFirst = 0;
    1464         [ #  # ]:          0 :         nDist = Max( nDist, long( GetLineSpace() ) );
    1465                 :          0 :         nDist += nLineHeight;
    1466                 :          0 :         nDiff -= nFirst;
    1467                 :            : 
    1468         [ #  # ]:          0 :         if( nDiff > 0 )
    1469                 :            :         {
    1470                 :          0 :             nDiff /= nDist;
    1471                 :          0 :             rFill.Fill().nParaCnt = static_cast<sal_uInt16>(nDiff + 1);
    1472                 :          0 :             rFill.nLineWidth = 0;
    1473                 :          0 :             rFill.bInner = sal_False;
    1474                 :          0 :             rFill.bEmpty = sal_True;
    1475                 :          0 :             rFill.SetOrient( text::HoriOrientation::LEFT );
    1476                 :            :         }
    1477                 :            :         else
    1478                 :          0 :             nDiff = -1;
    1479         [ #  # ]:          0 :         if( rFill.bInner )
    1480                 :          0 :             bFill = sal_False;
    1481                 :            :         else
    1482                 :            :         {
    1483         [ #  # ]:          0 :             const SvxTabStopItem &rRuler = pSet->GetTabStops();
    1484         [ #  # ]:          0 :             const SvxLRSpaceItem &rLRSpace = pSet->GetLRSpace();
    1485                 :            : 
    1486                 :          0 :             SwRect &rRect = rFill.Fill().aCrsr;
    1487                 :          0 :             rRect.Top( rFill.Bottom() + (nDiff+1) * nDist - nLineHeight );
    1488 [ #  # ][ #  # ]:          0 :             if( nFirst && nDiff > -1 )
    1489                 :          0 :                 rRect.Top( rRect.Top() + nFirst );
    1490                 :          0 :             rRect.Height( nLineHeight );
    1491                 :          0 :             SwTwips nLeft = rFill.Left() + rLRSpace.GetLeft() +
    1492         [ #  # ]:          0 :                             GetTxtNode()->GetLeftMarginWithNum( sal_False );
    1493                 :          0 :             SwTwips nRight = rFill.Right() - rLRSpace.GetRight();
    1494                 :          0 :             SwTwips nCenter = ( nLeft + nRight ) / 2;
    1495                 :          0 :             rRect.Left( nLeft );
    1496         [ #  # ]:          0 :             if( FILL_MARGIN == rFill.Mode() )
    1497                 :            :             {
    1498         [ #  # ]:          0 :                 if( rFill.bEmpty )
    1499                 :            :                 {
    1500                 :          0 :                     rFill.SetOrient( text::HoriOrientation::LEFT );
    1501         [ #  # ]:          0 :                     if( rFill.X() < nCenter )
    1502                 :            :                     {
    1503         [ #  # ]:          0 :                         if( rFill.X() > ( nLeft + 2 * nCenter ) / 3 )
    1504                 :            :                         {
    1505                 :          0 :                             rFill.SetOrient( text::HoriOrientation::CENTER );
    1506                 :          0 :                             rRect.Left( nCenter );
    1507                 :            :                         }
    1508                 :            :                     }
    1509         [ #  # ]:          0 :                     else if( rFill.X() > ( nRight + 2 * nCenter ) / 3 )
    1510                 :            :                     {
    1511                 :          0 :                         rFill.SetOrient( text::HoriOrientation::RIGHT );
    1512                 :          0 :                         rRect.Left( nRight );
    1513                 :            :                     }
    1514                 :            :                     else
    1515                 :            :                     {
    1516                 :          0 :                         rFill.SetOrient( text::HoriOrientation::CENTER );
    1517                 :          0 :                         rRect.Left( nCenter );
    1518                 :            :                     }
    1519                 :            :                 }
    1520                 :            :                 else
    1521                 :          0 :                     bFill = sal_False;
    1522                 :            :             }
    1523                 :            :             else
    1524                 :            :             {
    1525                 :          0 :                 SwTwips nSpace = 0;
    1526         [ #  # ]:          0 :                 if( FILL_TAB != rFill.Mode() )
    1527                 :            :                 {
    1528                 :            : static sal_Char const sDoubleSpace[] = "  ";
    1529         [ #  # ]:          0 :                     const XubString aTmp( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
    1530                 :            : 
    1531                 :          0 :                     SwDrawTextInfo aDrawInf( pSh, *pOut, 0, aTmp, 0, 2 );
    1532 [ #  # ][ #  # ]:          0 :                     nSpace = pFnt->_GetTxtSize( aDrawInf ).Width()/2;
    1533                 :            :                 }
    1534         [ #  # ]:          0 :                 if( rFill.X() >= nRight )
    1535                 :            :                 {
    1536         [ #  # ]:          0 :                     if( FILL_INDENT != rFill.Mode() && ( rFill.bEmpty ||
           [ #  #  #  # ]
                 [ #  # ]
    1537                 :          0 :                         rFill.X() > rFill.nLineWidth + FILL_MIN_DIST ) )
    1538                 :            :                     {
    1539                 :          0 :                         rFill.SetOrient( text::HoriOrientation::RIGHT );
    1540                 :          0 :                         rRect.Left( nRight );
    1541                 :            :                     }
    1542                 :            :                     else
    1543                 :          0 :                         bFill = sal_False;
    1544                 :            :                 }
    1545         [ #  # ]:          0 :                 else if( FILL_INDENT == rFill.Mode() )
    1546                 :            :                 {
    1547                 :          0 :                     SwTwips nIndent = rFill.X();
    1548 [ #  # ][ #  # ]:          0 :                     if( !rFill.bEmpty || nIndent > nRight )
    1549                 :          0 :                         bFill = sal_False;
    1550                 :            :                     else
    1551                 :            :                     {
    1552                 :          0 :                         nIndent -= rFill.Left();
    1553 [ #  # ][ #  # ]:          0 :                         if( nIndent >= 0 && nSpace )
    1554                 :            :                         {
    1555                 :          0 :                             nIndent /= nSpace;
    1556                 :          0 :                             nIndent *= nSpace;
    1557                 :          0 :                             rFill.SetTab( MSHORT( nIndent ) );
    1558                 :          0 :                             rRect.Left( nIndent + rFill.Left() );
    1559                 :            :                         }
    1560                 :            :                         else
    1561                 :          0 :                             bFill = sal_False;
    1562                 :            :                     }
    1563                 :            :                 }
    1564         [ #  # ]:          0 :                 else if( rFill.X() > nLeft )
    1565                 :            :                 {
    1566                 :          0 :                     SwTwips nTxtLeft = rFill.Left() + rLRSpace.GetTxtLeft() +
    1567         [ #  # ]:          0 :                                     GetTxtNode()->GetLeftMarginWithNum( sal_True );
    1568         [ #  # ]:          0 :                     rFill.nLineWidth += rFill.bFirstLine ? nLeft : nTxtLeft;
    1569                 :          0 :                     SwTwips nLeftTab = nLeft;
    1570                 :          0 :                     SwTwips nRightTab = nLeft;
    1571                 :          0 :                     MSHORT nSpaceCnt = 0;
    1572                 :          0 :                     MSHORT nTabCnt = 0;
    1573                 :          0 :                     MSHORT nIdx = 0;
    1574         [ #  # ]:          0 :                     do
    1575                 :            :                     {
    1576                 :          0 :                         nLeftTab = nRightTab;
    1577         [ #  # ]:          0 :                         if( nIdx < rRuler.Count() )
    1578                 :            :                         {
    1579         [ #  # ]:          0 :                             const SvxTabStop &rTabStop = rRuler.operator[](nIdx);
    1580                 :          0 :                             nRightTab = nTxtLeft + rTabStop.GetTabPos();
    1581 [ #  # ][ #  # ]:          0 :                             if( nLeftTab < nTxtLeft && nRightTab > nTxtLeft )
    1582                 :          0 :                                 nRightTab = nTxtLeft;
    1583                 :            :                             else
    1584                 :          0 :                                 ++nIdx;
    1585         [ #  # ]:          0 :                             if( nRightTab > rFill.nLineWidth )
    1586                 :          0 :                                 ++nTabCnt;
    1587                 :            :                         }
    1588                 :            :                         else
    1589                 :            :                         {
    1590                 :            :                             const SvxTabStopItem& rTab =
    1591                 :            :                                 (const SvxTabStopItem &)pSet->
    1592         [ #  # ]:          0 :                                 GetPool()->GetDefaultItem( RES_PARATR_TABSTOP );
    1593         [ #  # ]:          0 :                             MSHORT nDefTabDist = (MSHORT)rTab[0].GetTabPos();
    1594                 :          0 :                             nRightTab = nLeftTab - nTxtLeft;
    1595                 :          0 :                             nRightTab /= nDefTabDist;
    1596                 :          0 :                             nRightTab = nRightTab * nDefTabDist + nTxtLeft;
    1597         [ #  # ]:          0 :                             while ( nRightTab <= nLeftTab )
    1598                 :          0 :                                 nRightTab += nDefTabDist;
    1599         [ #  # ]:          0 :                             if( nRightTab > rFill.nLineWidth )
    1600                 :          0 :                                 ++nTabCnt;
    1601         [ #  # ]:          0 :                             while ( nRightTab < rFill.X() )
    1602                 :            :                             {
    1603                 :          0 :                                 nRightTab += nDefTabDist;
    1604         [ #  # ]:          0 :                                 if( nRightTab > rFill.nLineWidth )
    1605                 :          0 :                                     ++nTabCnt;
    1606                 :            :                             }
    1607         [ #  # ]:          0 :                             if( nLeftTab < nRightTab - nDefTabDist )
    1608                 :          0 :                                 nLeftTab = nRightTab - nDefTabDist;
    1609                 :            :                         }
    1610         [ #  # ]:          0 :                         if( nRightTab > nRight )
    1611                 :          0 :                             nRightTab = nRight;
    1612                 :            :                     }
    1613                 :          0 :                     while( rFill.X() > nRightTab );
    1614                 :          0 :                     --nTabCnt;
    1615         [ #  # ]:          0 :                     if( FILL_TAB != rFill.Mode() )
    1616                 :            :                     {
    1617         [ #  # ]:          0 :                         if( nSpace > 0 )
    1618                 :            :                         {
    1619         [ #  # ]:          0 :                             if( !nTabCnt )
    1620                 :          0 :                                 nLeftTab = rFill.nLineWidth;
    1621         [ #  # ]:          0 :                             while( nLeftTab < rFill.X() )
    1622                 :            :                             {
    1623                 :          0 :                                 nLeftTab += nSpace;
    1624                 :          0 :                                 ++nSpaceCnt;
    1625                 :            :                             }
    1626         [ #  # ]:          0 :                             if( nSpaceCnt )
    1627                 :            :                             {
    1628                 :          0 :                                 nLeftTab -= nSpace;
    1629                 :          0 :                                 --nSpaceCnt;
    1630                 :            :                             }
    1631         [ #  # ]:          0 :                             if( rFill.X() - nLeftTab > nRightTab - rFill.X() )
    1632                 :            :                             {
    1633                 :          0 :                                 nSpaceCnt = 0;
    1634                 :          0 :                                 ++nTabCnt;
    1635                 :          0 :                                 rRect.Left( nRightTab );
    1636                 :            :                             }
    1637                 :            :                             else
    1638                 :            :                             {
    1639         [ #  # ]:          0 :                                 if( rFill.X() - nLeftTab > nSpace/2 )
    1640                 :            :                                 {
    1641                 :          0 :                                     ++nSpaceCnt;
    1642                 :          0 :                                     rRect.Left( nLeftTab + nSpace );
    1643                 :            :                                 }
    1644                 :            :                                 else
    1645                 :          0 :                                     rRect.Left( nLeftTab );
    1646                 :            :                             }
    1647                 :            :                         }
    1648         [ #  # ]:          0 :                         else if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
    1649                 :          0 :                             rRect.Left( nLeftTab );
    1650                 :            :                         else
    1651                 :            :                         {
    1652         [ #  # ]:          0 :                             if( nRightTab >= nRight )
    1653                 :            :                             {
    1654                 :          0 :                                 rFill.SetOrient( text::HoriOrientation::RIGHT );
    1655                 :          0 :                                 rRect.Left( nRight );
    1656                 :          0 :                                 nTabCnt = 0;
    1657                 :          0 :                                 nSpaceCnt = 0;
    1658                 :            :                             }
    1659                 :            :                             else
    1660                 :            :                             {
    1661                 :          0 :                                 rRect.Left( nRightTab );
    1662                 :          0 :                                 ++nTabCnt;
    1663                 :            :                             }
    1664                 :            :                         }
    1665                 :            :                     }
    1666                 :            :                     else
    1667                 :            :                     {
    1668         [ #  # ]:          0 :                         if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
    1669                 :          0 :                             rRect.Left( nLeftTab );
    1670                 :            :                         else
    1671                 :            :                         {
    1672         [ #  # ]:          0 :                             if( nRightTab >= nRight )
    1673                 :            :                             {
    1674                 :          0 :                                 rFill.SetOrient( text::HoriOrientation::RIGHT );
    1675                 :          0 :                                 rRect.Left( nRight );
    1676                 :          0 :                                 nTabCnt = 0;
    1677                 :          0 :                                 nSpaceCnt = 0;
    1678                 :            :                             }
    1679                 :            :                             else
    1680                 :            :                             {
    1681                 :          0 :                                 rRect.Left( nRightTab );
    1682                 :          0 :                                 ++nTabCnt;
    1683                 :            :                             }
    1684                 :            :                         }
    1685                 :            :                     }
    1686                 :          0 :                     rFill.SetTab( nTabCnt );
    1687                 :          0 :                     rFill.SetSpace( nSpaceCnt );
    1688         [ #  # ]:          0 :                     if( bFill )
    1689                 :            :                     {
    1690         [ #  # ]:          0 :                         if( Abs( rFill.X() - nCenter ) <=
    1691                 :          0 :                             Abs( rFill.X() - rRect.Left() ) )
    1692                 :            :                         {
    1693                 :          0 :                             rFill.SetOrient( text::HoriOrientation::CENTER );
    1694                 :          0 :                             rFill.SetTab( 0 );
    1695                 :          0 :                             rFill.SetSpace( 0 );
    1696                 :          0 :                             rRect.Left( nCenter );
    1697                 :            :                         }
    1698         [ #  # ]:          0 :                         if( !rFill.bEmpty )
    1699                 :          0 :                             rFill.nLineWidth += FILL_MIN_DIST;
    1700         [ #  # ]:          0 :                         if( rRect.Left() < rFill.nLineWidth )
    1701                 :          0 :                             bFill = sal_False;
    1702                 :            :                     }
    1703                 :            :                 }
    1704                 :            :             }
    1705                 :            :             // Do we extend over the page's/column's/etc. lower edge?
    1706                 :          0 :             const SwFrm* pUp = GetUpper();
    1707 [ #  # ][ #  # ]:          0 :             if( pUp->IsInSct() )
    1708                 :            :             {
    1709         [ #  # ]:          0 :                 if( pUp->IsSctFrm() )
    1710                 :          0 :                     pUp = pUp->GetUpper();
    1711   [ #  #  #  # ]:          0 :                 else if( pUp->IsColBodyFrm() &&
                 [ #  # ]
    1712                 :          0 :                          pUp->GetUpper()->GetUpper()->IsSctFrm() )
    1713                 :          0 :                     pUp = pUp->GetUpper()->GetUpper()->GetUpper();
    1714                 :            :             }
    1715 [ #  # ][ #  # ]:          0 :             SWRECTFN( this )
         [ #  # ][ #  # ]
                 [ #  # ]
    1716 [ #  # ][ #  # ]:          0 :             SwTwips nLimit = (pUp->*fnRect->fnGetPrtBottom)();
    1717                 :          0 :             SwTwips nRectBottom = rRect.Bottom();
    1718         [ #  # ]:          0 :             if ( bVert )
    1719         [ #  # ]:          0 :                 nRectBottom = SwitchHorizontalToVertical( nRectBottom );
    1720                 :            : 
    1721 [ #  # ][ #  # ]:          0 :             if( (*fnRect->fnYDiff)( nLimit, nRectBottom ) < 0 )
    1722                 :          0 :                 bFill = sal_False;
    1723                 :            :             else
    1724                 :          0 :                 rRect.Width( 1 );
    1725                 :            :         }
    1726                 :            :     }
    1727                 :            :     else
    1728                 :          0 :         bFill = sal_False;
    1729                 :          0 :     ((SwCrsrMoveState*)rFill.pCMS)->bFillRet = bFill;
    1730 [ #  # ][ #  # ]:          0 :     delete pFnt;
                 [ #  # ]
    1731                 :            : }
    1732                 :            : 
    1733                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10