LCOV - code coverage report
Current view: top level - sw/source/core/text - itrform2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 775 1208 64.2 %
Date: 2012-08-25 Functions: 31 37 83.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 848 1711 49.6 %

           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                 :            : 
      30                 :            : #include "hintids.hxx"
      31                 :            : 
      32                 :            : #include <com/sun/star/i18n/ScriptType.hpp>
      33                 :            : #include <editeng/lspcitem.hxx>
      34                 :            : #include <txtflcnt.hxx>
      35                 :            : #include <txtftn.hxx>
      36                 :            : #include <flyfrms.hxx>
      37                 :            : #include <fmtflcnt.hxx>
      38                 :            : #include <fmtftn.hxx>
      39                 :            : #include <ftninfo.hxx>
      40                 :            : #include <charfmt.hxx>
      41                 :            : #include <editeng/charrotateitem.hxx>
      42                 :            : #include <layfrm.hxx>       // GetFrmRstHeight, etc
      43                 :            : #include <viewsh.hxx>
      44                 :            : #include <viewopt.hxx>      // SwViewOptions
      45                 :            : #include <paratr.hxx>       // SwFmtDrop
      46                 :            : #include <itrform2.hxx>
      47                 :            : #include <porrst.hxx>
      48                 :            : #include <portab.hxx>       // pLastTab->
      49                 :            : #include <porfly.hxx>       // CalcFlyWidth
      50                 :            : #include <portox.hxx>       // WhichTxtPortion
      51                 :            : #include <porref.hxx>       // WhichTxtPortion
      52                 :            : #include <porfld.hxx>       // SwNumberPortion for CalcAscent()
      53                 :            : #include <porftn.hxx>       // SwFtnPortion
      54                 :            : #include <porhyph.hxx>
      55                 :            : #include <guess.hxx>
      56                 :            : #include <blink.hxx>        // pBlink
      57                 :            : #include <ftnfrm.hxx>       // WhichFirstPortion() -> move it
      58                 :            : #include <redlnitr.hxx>     // SwRedlineItr
      59                 :            : #include <pagefrm.hxx>
      60                 :            : #include <pagedesc.hxx>     // SwPageDesc
      61                 :            : #include <tgrditem.hxx>
      62                 :            : #include <doc.hxx>          // SwDoc
      63                 :            : #include <pormulti.hxx>     // SwMultiPortion
      64                 :            : #include <unotools/charclass.hxx>
      65                 :            : 
      66                 :            : #include <vector>
      67                 :            : 
      68                 :            : #if OSL_DEBUG_LEVEL > 1
      69                 :            : #include <ndtxt.hxx>        // pSwpHints, output operator
      70                 :            : #endif
      71                 :            : 
      72                 :            : using namespace ::com::sun::star;
      73                 :            : 
      74                 :            : extern sal_Bool IsUnderlineBreak( const SwLinePortion& rPor, const SwFont& rFnt );
      75                 :            : 
      76                 :            : namespace {
      77                 :            :     //! Calculates and sets optimal repaint offset for the current line
      78                 :            :     static long lcl_CalcOptRepaint( SwTxtFormatter &rThis,
      79                 :            :                                     SwLineLayout &rCurr,
      80                 :            :                                     const xub_StrLen nOldLineEnd,
      81                 :            :                                     const std::vector<long> &rFlyStarts );
      82                 :            :     //! Determine if we need to build hidden portions
      83                 :            :     static bool lcl_BuildHiddenPortion( const SwTxtSizeInfo& rInf, xub_StrLen &rPos );
      84                 :            : }
      85                 :            : 
      86                 :     107496 : inline void ClearFly( SwTxtFormatInfo &rInf )
      87                 :            : {
      88         [ +  + ]:     107496 :     delete rInf.GetFly();
      89                 :     107496 :     rInf.SetFly(0);
      90                 :     107496 : }
      91                 :            : 
      92                 :            : /*************************************************************************
      93                 :            :  *                  SwTxtFormatter::CtorInitTxtFormatter()
      94                 :            :  *************************************************************************/
      95                 :            : 
      96                 :      14873 : void SwTxtFormatter::CtorInitTxtFormatter( SwTxtFrm *pNewFrm, SwTxtFormatInfo *pNewInf )
      97                 :            : {
      98                 :      14873 :     CtorInitTxtPainter( pNewFrm, pNewInf );
      99                 :      14873 :     pInf = pNewInf;
     100                 :      14873 :     pDropFmt = GetInfo().GetDropFmt();
     101                 :      14873 :     pMulti = NULL;
     102                 :            : 
     103                 :      14873 :     bOnceMore = sal_False;
     104                 :      14873 :     bFlyInCntBase = sal_False;
     105                 :      14873 :     bChanges = sal_False;
     106                 :      14873 :     bTruncLines = sal_False;
     107                 :      14873 :     nCntEndHyph = 0;
     108                 :      14873 :     nCntMidHyph = 0;
     109                 :      14873 :     nLeftScanIdx = STRING_LEN;
     110                 :      14873 :     nRightScanIdx = 0;
     111                 :      14873 :     m_nHintEndIndex = 0;
     112                 :            : 
     113         [ -  + ]:      14873 :     if( nStart > GetInfo().GetTxt().Len() )
     114                 :            :     {
     115                 :            :         OSL_ENSURE( !this, "+SwTxtFormatter::CTOR: bad offset" );
     116                 :          0 :         nStart = GetInfo().GetTxt().Len();
     117                 :            :     }
     118                 :            : 
     119                 :      14873 : }
     120                 :            : 
     121                 :            : /*************************************************************************
     122                 :            :  *                      SwTxtFormatter::DTOR
     123                 :            :  *************************************************************************/
     124                 :            : 
     125                 :      14873 : SwTxtFormatter::~SwTxtFormatter()
     126                 :            : {
     127                 :            :     // Extremly unlikely, but still possible
     128                 :            :     // e.g.: field splits up, widows start to matter
     129         [ -  + ]:      14873 :     if( GetInfo().GetRest() )
     130                 :            :     {
     131 [ #  # ][ #  # ]:          0 :         delete GetInfo().GetRest();
     132                 :          0 :         GetInfo().SetRest(0);
     133                 :            :     }
     134         [ -  + ]:      14873 : }
     135                 :            : 
     136                 :            : /*************************************************************************
     137                 :            :  *                      SwTxtFormatter::Insert()
     138                 :            :  *************************************************************************/
     139                 :            : 
     140                 :       6910 : void SwTxtFormatter::Insert( SwLineLayout *pLay )
     141                 :            : {
     142                 :            :     // Insert BEHIND the current element
     143         [ +  - ]:       6910 :     if ( pCurr )
     144                 :            :     {
     145                 :       6910 :         pLay->SetNext( pCurr->GetNext() );
     146                 :       6910 :         pCurr->SetNext( pLay );
     147                 :            :     }
     148                 :            :     else
     149                 :          0 :         pCurr = pLay;
     150                 :       6910 : }
     151                 :            : 
     152                 :            : /*************************************************************************
     153                 :            :  *                  SwTxtFormatter::GetFrmRstHeight()
     154                 :            :  *************************************************************************/
     155                 :            : 
     156                 :          0 : KSHORT SwTxtFormatter::GetFrmRstHeight() const
     157                 :            : {
     158                 :            :     // We want the rest height relative to the page.
     159                 :            :     // If we're in a table, then pFrm->GetUpper() is not the page.
     160                 :            :     //
     161                 :            :     // GetFrmRstHeight() is being called with Ftn.
     162                 :            :     // Wrong: const SwFrm *pUpper = pFrm->GetUpper();
     163                 :          0 :     const SwFrm *pPage = (const SwFrm*)pFrm->FindPageFrm();
     164                 :          0 :     const SwTwips nHeight = pPage->Frm().Top()
     165                 :          0 :                           + pPage->Prt().Top()
     166                 :          0 :                           + pPage->Prt().Height() - Y();
     167         [ #  # ]:          0 :     if( 0 > nHeight )
     168                 :          0 :         return pCurr->Height();
     169                 :            :     else
     170                 :          0 :         return KSHORT( nHeight );
     171                 :            : }
     172                 :            : 
     173                 :            : /*************************************************************************
     174                 :            :  *                  SwTxtFormatter::UnderFlow()
     175                 :            :  *************************************************************************/
     176                 :            : 
     177                 :          0 : SwLinePortion *SwTxtFormatter::UnderFlow( SwTxtFormatInfo &rInf )
     178                 :            : {
     179                 :            :     // Save values and initialize rInf
     180                 :          0 :     SwLinePortion *pUnderFlow = rInf.GetUnderFlow();
     181         [ #  # ]:          0 :     if( !pUnderFlow )
     182                 :          0 :         return 0;
     183                 :            : 
     184                 :            :     // We format backwards, i.e. attribute changes can happen the next
     185                 :            :     // line again.
     186                 :            :     // Can be seen in 8081.sdw, if you enter text in the first line
     187                 :            : 
     188                 :          0 :     const xub_StrLen nSoftHyphPos = rInf.GetSoftHyphPos();
     189                 :          0 :     const xub_StrLen nUnderScorePos = rInf.GetUnderScorePos();
     190                 :            : 
     191                 :            :     // Save flys and set to 0, or else segmentation fault
     192                 :            :     // Not ClearFly(rInf) !
     193                 :          0 :     SwFlyPortion *pFly = rInf.GetFly();
     194                 :          0 :     rInf.SetFly( 0 );
     195                 :            : 
     196                 :          0 :     FeedInf( rInf );
     197                 :          0 :     rInf.SetLast( pCurr );
     198                 :            :     // pUnderFlow does not need to be deleted, because it will drown in the following
     199                 :            :     // Truncate()
     200                 :          0 :     rInf.SetUnderFlow(0);
     201                 :          0 :     rInf.SetSoftHyphPos( nSoftHyphPos );
     202                 :          0 :     rInf.SetUnderScorePos( nUnderScorePos );
     203                 :          0 :     rInf.SetPaintOfst( GetLeftMargin() );
     204                 :            : 
     205                 :            :     // We look for the portion with the under-flow position
     206                 :          0 :     SwLinePortion *pPor = pCurr->GetFirstPortion();
     207         [ #  # ]:          0 :     if( pPor != pUnderFlow )
     208                 :            :     {
     209                 :            :         // pPrev will be the last portion before pUnderFlow,
     210                 :            :         // which still has a real width.
     211                 :            :         // Exception: SoftHyphPortions must not be forgotten, of course!
     212                 :            :         // Although they don't have a width.
     213                 :          0 :         SwLinePortion *pTmpPrev = pPor;
     214 [ #  # ][ #  # ]:          0 :         while( pPor && pPor != pUnderFlow )
                 [ #  # ]
     215                 :            :         {
     216   [ #  #  #  #  :          0 :             if( !pPor->IsKernPortion() &&
           #  # ][ #  # ]
     217                 :          0 :                 ( pPor->Width() || pPor->IsSoftHyphPortion() ) )
     218                 :            :             {
     219         [ #  # ]:          0 :                 while( pTmpPrev != pPor )
     220                 :            :                 {
     221                 :          0 :                     pTmpPrev->Move( rInf );
     222                 :          0 :                     rInf.SetLast( pTmpPrev );
     223                 :          0 :                     pTmpPrev = pTmpPrev->GetPortion();
     224                 :            :                     OSL_ENSURE( pTmpPrev, "UnderFlow: Loosing control!" );
     225                 :            :                 };
     226                 :            :             }
     227                 :          0 :             pPor = pPor->GetPortion();
     228                 :            :         }
     229                 :          0 :         pPor = pTmpPrev;
     230   [ #  #  #  #  :          0 :         if( pPor && // Flies + Initialen werden nicht beim UnderFlow mitgenommen
             #  #  #  # ]
                 [ #  # ]
     231                 :          0 :             ( pPor->IsFlyPortion() || pPor->IsDropPortion() ||
     232                 :          0 :               pPor->IsFlyCntPortion() ) )
     233                 :            :         {
     234                 :          0 :             pPor->Move( rInf );
     235                 :          0 :             rInf.SetLast( pPor );
     236                 :          0 :             rInf.SetStopUnderFlow( sal_True );
     237                 :          0 :             pPor = pUnderFlow;
     238                 :            :         }
     239                 :            :     }
     240                 :            : 
     241                 :            :     // What? The under-flow portion is not in the portion chain?
     242                 :            :     OSL_ENSURE( pPor, "SwTxtFormatter::UnderFlow: overflow but underflow" );
     243                 :            : 
     244                 :            :     // OD 2004-05-26 #i29529# - correction: no delete of footnotes
     245                 :            : //    if( rInf.IsFtnInside() && pPor && !rInf.IsQuick() )
     246                 :            : //    {
     247                 :            : //        SwLinePortion *pTmp = pPor->GetPortion();
     248                 :            : //        while( pTmp )
     249                 :            : //        {
     250                 :            : //            if( pTmp->IsFtnPortion() )
     251                 :            : //                ((SwFtnPortion*)pTmp)->ClearFtn();
     252                 :            : //            pTmp = pTmp->GetPortion();
     253                 :            : //        }
     254                 :            : //    }
     255                 :            : 
     256                 :            :     /*--------------------------------------------------
     257                 :            :      * Snapshot
     258                 :            :      * --------------------------------------------------*/
     259         [ #  # ]:          0 :     if ( pPor==rInf.GetLast() )
     260                 :            :     {
     261                 :            :         // We end up here, if the portion triggering the under-flow
     262                 :            :         // spans over the whole line. E.g. if a word spans across
     263                 :            :         // multiple lines and flows into a fly in the second line.
     264                 :          0 :         rInf.SetFly( pFly );
     265                 :          0 :         pPor->Truncate();
     266                 :          0 :         return pPor; // Is that enough?
     267                 :            :     }
     268                 :            :     /*---------------------------------------------------
     269                 :            :      * End the snapshot
     270                 :            :      * --------------------------------------------------*/
     271                 :            : 
     272                 :            :     // X + Width == 0 with SoftHyph > Line?!
     273 [ #  # ][ #  # ]:          0 :     if( !pPor || !(rInf.X() + pPor->Width()) )
                 [ #  # ]
     274                 :            :     {
     275         [ #  # ]:          0 :         delete pFly;
     276                 :          0 :         return 0;
     277                 :            :     }
     278                 :            : 
     279                 :            :     // Preparing for Format()
     280                 :            :     // We need to chip off the chain behind pLast, because we Insert after the Format()
     281                 :          0 :     SeekAndChg( rInf );
     282                 :            : 
     283                 :            :     // line width is adjusted, so that pPor does not fit to current
     284                 :            :     // line anymore
     285         [ #  # ]:          0 :     rInf.Width( (sal_uInt16)(rInf.X() + (pPor->Width() ? pPor->Width() - 1 : 0)) );
     286                 :          0 :     rInf.SetLen( pPor->GetLen() );
     287                 :          0 :     rInf.SetFull( sal_False );
     288         [ #  # ]:          0 :     if( pFly )
     289                 :            :     {
     290                 :            :         // We need to recalculate the FlyPortion due to the following reason:
     291                 :            :         // If the base line is lowered by a big font in the middle of the line,
     292                 :            :         // causing overlapping with a fly, the FlyPortion has a wrong size/fixed
     293                 :            :         // size.
     294                 :          0 :         rInf.SetFly( pFly );
     295                 :          0 :         CalcFlyWidth( rInf );
     296                 :            :     }
     297                 :          0 :     rInf.GetLast()->SetPortion(0);
     298                 :            : 
     299                 :            :     // The SwLineLayout is an exception to this, which splits at the first
     300                 :            :     // portion change.
     301                 :            :     // Here inly the other way around:
     302         [ #  # ]:          0 :     if( rInf.GetLast() == pCurr )
     303                 :            :     {
     304 [ #  # ][ #  # ]:          0 :         if( pPor->InTxtGrp() && !pPor->InExpGrp() )
                 [ #  # ]
     305                 :            :         {
     306                 :          0 :             MSHORT nOldWhich = pCurr->GetWhichPor();
     307                 :          0 :             *(SwLinePortion*)pCurr = *pPor;
     308                 :          0 :             pCurr->SetPortion( pPor->GetPortion() );
     309                 :          0 :             pCurr->SetWhichPor( nOldWhich );
     310                 :          0 :             pPor->SetPortion( 0 );
     311         [ #  # ]:          0 :             delete pPor;
     312                 :          0 :             pPor = pCurr;
     313                 :            :         }
     314                 :            :     }
     315                 :          0 :     pPor->Truncate();
     316                 :          0 :     SwLinePortion *const pRest( rInf.GetRest() );
     317   [ #  #  #  # ]:          0 :     if (pRest && pRest->InFldGrp() &&
         [ #  # ][ #  # ]
     318                 :          0 :         static_cast<SwFldPortion*>(pRest)->IsNoLength())
     319                 :            :     {
     320                 :            :         // HACK: decrement again, so we pick up the suffix in next line!
     321                 :          0 :         --m_nHintEndIndex;
     322                 :            :     }
     323         [ #  # ]:          0 :     delete pRest;
     324                 :          0 :     rInf.SetRest(0);
     325                 :          0 :     return pPor;
     326                 :            : }
     327                 :            : 
     328                 :            : /*************************************************************************
     329                 :            :  *                      SwTxtFormatter::InsertPortion()
     330                 :            :  *************************************************************************/
     331                 :            : 
     332                 :      55613 : void SwTxtFormatter::InsertPortion( SwTxtFormatInfo &rInf,
     333                 :            :                                     SwLinePortion *pPor ) const
     334                 :            : {
     335                 :            :     // The new portion is inserted, but everything's different for
     336                 :            :     // LineLayout ...
     337         [ +  + ]:      55613 :     if( pPor == pCurr )
     338                 :            :     {
     339         [ +  + ]:      49260 :         if ( pCurr->GetPortion() )
     340                 :            :         {
     341                 :       1380 :             pPor = pCurr->GetPortion();
     342                 :            :         }
     343                 :            : 
     344                 :            :         // #i112181#
     345 [ +  + ][ +  - ]:      49260 :         rInf.SetOtherThanFtnInside( rInf.IsOtherThanFtnInside() || !pPor->IsFtnPortion() );
     346                 :            :     }
     347                 :            :     else
     348                 :            :     {
     349                 :       6353 :         SwLinePortion *pLast = rInf.GetLast();
     350         [ +  + ]:       6353 :         if( pLast->GetPortion() )
     351                 :            :         {
     352         [ +  + ]:        210 :             while( pLast->GetPortion() )
     353                 :        140 :                 pLast = pLast->GetPortion();
     354                 :         70 :             rInf.SetLast( pLast );
     355                 :            :         }
     356                 :       6353 :         pLast->Insert( pPor );
     357                 :            : 
     358 [ +  + ][ +  + ]:       6353 :         rInf.SetOtherThanFtnInside( rInf.IsOtherThanFtnInside() || !pPor->IsFtnPortion() );
     359                 :            : 
     360                 :            :         // Adjust maxima
     361         [ +  + ]:       6353 :         if( pCurr->Height() < pPor->Height() )
     362                 :       1335 :             pCurr->Height( pPor->Height() );
     363         [ +  + ]:       6353 :         if( pCurr->GetAscent() < pPor->GetAscent() )
     364                 :        614 :             pCurr->SetAscent( pPor->GetAscent() );
     365                 :            :     }
     366                 :            : 
     367                 :            :     // Sometimes chains are constructed (e.g. by hyphenate)
     368                 :      55613 :     rInf.SetLast( pPor );
     369         [ +  + ]:     112760 :     while( pPor )
     370                 :            :     {
     371                 :      57147 :         pPor->Move( rInf );
     372                 :      57147 :         rInf.SetLast( pPor );
     373                 :      57147 :         pPor = pPor->GetPortion();
     374                 :            :     }
     375                 :      55613 : }
     376                 :            : 
     377                 :            : /*************************************************************************
     378                 :            :  *                      SwTxtFormatter::BuildPortion()
     379                 :            :  *************************************************************************/
     380                 :            : 
     381                 :      53784 : void SwTxtFormatter::BuildPortions( SwTxtFormatInfo &rInf )
     382                 :            : {
     383                 :            :     OSL_ENSURE( rInf.GetTxt().Len() < STRING_LEN,
     384                 :            :             "SwTxtFormatter::BuildPortions: bad text length in info" );
     385                 :            : 
     386                 :      53784 :     rInf.ChkNoHyph( CntEndHyph(), CntMidHyph() );
     387                 :            : 
     388                 :            :     // First NewTxtPortion() decides whether pCurr ends up in pPor.
     389                 :            :     // We need to make sure that the font is being set in any case.
     390                 :            :     // This is done automatically in CalcAscent.
     391                 :      53784 :     rInf.SetLast( pCurr );
     392                 :      53784 :     rInf.ForcedLeftMargin( 0 );
     393                 :            : 
     394                 :            :     OSL_ENSURE( pCurr->FindLastPortion() == pCurr, "pLast supposed to equal pCurr" );
     395                 :            : 
     396 [ +  - ][ +  - ]:      53784 :     if( !pCurr->GetAscent() && !pCurr->Height() )
                 [ +  - ]
     397                 :      53784 :         CalcAscent( rInf, pCurr );
     398                 :            : 
     399                 :      53784 :     SeekAndChg( rInf );
     400                 :            : 
     401                 :            :     // Width() is shortened in CalcFlyWidth if we have a FlyPortion
     402                 :            :     OSL_ENSURE( !rInf.X() || pMulti, "SwTxtFormatter::BuildPortion X=0?" );
     403                 :      53784 :     CalcFlyWidth( rInf );
     404                 :      53784 :     SwFlyPortion *pFly = rInf.GetFly();
     405         [ +  + ]:      53784 :     if( pFly )
     406                 :            :     {
     407         [ +  + ]:        382 :         if ( 0 < pFly->Fix() )
     408                 :        344 :             ClearFly( rInf );
     409                 :            :         else
     410                 :         38 :             rInf.SetFull(sal_True);
     411                 :            :     }
     412                 :            : 
     413                 :      53784 :     SwLinePortion *pPor = NewPortion( rInf );
     414                 :            : 
     415                 :            :     // Asian grid stuff
     416 [ -  + ][ #  # ]:      53784 :     GETGRID( pFrm->FindPageFrm() )
         [ -  + ][ +  - ]
     417                 :          0 :     const sal_Bool bHasGrid = pGrid && rInf.SnapToGrid() &&
     418   [ -  +  #  # ]:      53784 :                               GRID_LINES_CHARS == pGrid->GetGridType();
                 [ #  # ]
     419                 :            : 
     420                 :      53784 :     const SwDoc *pDoc = rInf.GetTxtFrm()->GetNode()->GetDoc();
     421                 :            :     const sal_uInt16 nGridWidth = bHasGrid ?
     422 [ #  # ][ -  + ]:      53784 :                                 GETGRIDWIDTH(pGrid,pDoc) : 0;   //for textgrid refactor
     423                 :            : 
     424                 :            :     // used for grid mode only:
     425                 :            :     // the pointer is stored, because after formatting of non-asian text,
     426                 :            :     // the width of the kerning portion has to be adjusted
     427                 :      53784 :     SwKernPortion* pGridKernPortion = 0;
     428                 :            : 
     429                 :            :     sal_Bool bFull;
     430                 :      53784 :     SwTwips nUnderLineStart = 0;
     431                 :      53784 :     rInf.Y( Y() );
     432                 :            : 
     433 [ +  + ][ +  - ]:     109397 :     while( pPor && !rInf.IsStop() )
                 [ +  + ]
     434                 :            :     {
     435                 :            :         OSL_ENSURE( rInf.GetLen() < STRING_LEN &&
     436                 :            :                 rInf.GetIdx() <= rInf.GetTxt().Len(),
     437                 :            :                 "SwTxtFormatter::BuildPortions: bad length in info" );
     438                 :            : 
     439                 :            :         // We have to check the script for fields in order to set the
     440                 :            :         // correct nActual value for the font.
     441         [ +  + ]:      55613 :         if( pPor->InFldGrp() )
     442                 :       1753 :             ((SwFldPortion*)pPor)->CheckScript( rInf );
     443                 :            : 
     444 [ +  - ][ +  +  :     223167 :         if( ! bHasGrid && rInf.HasScriptSpace() &&
          +  -  +  +  +  
                +  +  + ]
                 [ +  + ]
     445                 :     111048 :             rInf.GetLast() && rInf.GetLast()->InTxtGrp() &&
     446                 :      56506 :             rInf.GetLast()->Width() && !rInf.GetLast()->InNumberGrp() )
     447                 :            :         {
     448                 :       1544 :             sal_uInt8 nNxtActual = rInf.GetFont()->GetActual();
     449                 :       1544 :             sal_uInt8 nLstActual = nNxtActual;
     450                 :       1544 :             sal_uInt16 nLstHeight = (sal_uInt16)rInf.GetFont()->GetHeight();
     451                 :       1544 :             sal_Bool bAllowBefore = sal_False;
     452                 :       1544 :             sal_Bool bAllowBehind = sal_False;
     453                 :       1544 :             const CharClass& rCC = GetAppCharClass();
     454                 :            : 
     455                 :            :             // are there any punctuation characters on both sides
     456                 :            :             // of the kerning portion?
     457         [ +  + ]:       1544 :             if ( pPor->InFldGrp() )
     458                 :            :             {
     459         [ +  - ]:        555 :                 XubString aAltTxt;
     460         [ +  - ]:       1110 :                 if ( ((SwFldPortion*)pPor)->GetExpTxt( rInf, aAltTxt ) &&
           [ +  -  +  + ]
                 [ +  + ]
     461                 :        555 :                         aAltTxt.Len() )
     462                 :            :                 {
     463         [ +  - ]:        166 :                     bAllowBehind = rCC.isLetterNumeric( aAltTxt, 0 );
     464                 :            : 
     465                 :        166 :                     const SwFont* pTmpFnt = ((SwFldPortion*)pPor)->GetFont();
     466         [ +  + ]:        166 :                     if ( pTmpFnt )
     467                 :          2 :                         nNxtActual = pTmpFnt->GetActual();
     468         [ +  - ]:        555 :                 }
     469                 :            :             }
     470                 :            :             else
     471                 :        989 :                 bAllowBehind = rCC.isLetterNumeric( rInf.GetTxt(), rInf.GetIdx() );
     472                 :            : 
     473                 :       1544 :             const SwLinePortion* pLast = rInf.GetLast();
     474 [ +  - ][ +  + ]:       1544 :             if ( bAllowBehind && pLast )
     475                 :            :             {
     476         [ +  + ]:        854 :                 if ( pLast->InFldGrp() )
     477                 :            :                 {
     478         [ +  - ]:        152 :                     XubString aAltTxt;
     479         [ +  - ]:        304 :                     if ( ((SwFldPortion*)pLast)->GetExpTxt( rInf, aAltTxt ) &&
           [ +  -  +  - ]
                 [ +  - ]
     480                 :        152 :                          aAltTxt.Len() )
     481                 :            :                     {
     482         [ +  - ]:        152 :                         bAllowBefore = rCC.isLetterNumeric( aAltTxt, aAltTxt.Len() - 1 );
     483                 :            : 
     484                 :        152 :                         const SwFont* pTmpFnt = ((SwFldPortion*)pLast)->GetFont();
     485         [ -  + ]:        152 :                         if ( pTmpFnt )
     486                 :            :                         {
     487                 :          0 :                             nLstActual = pTmpFnt->GetActual();
     488         [ #  # ]:          0 :                             nLstHeight = (sal_uInt16)pTmpFnt->GetHeight();
     489                 :            :                         }
     490         [ +  - ]:        152 :                     }
     491                 :            :                 }
     492         [ +  - ]:        702 :                 else if ( rInf.GetIdx() )
     493                 :            :                 {
     494                 :        702 :                     bAllowBefore = rCC.isLetterNumeric( rInf.GetTxt(), rInf.GetIdx() - 1 );
     495                 :            :                     // Note: ScriptType returns values in [1,4]
     496         [ +  + ]:        702 :                     if ( bAllowBefore )
     497                 :        576 :                         nLstActual = pScriptInfo->ScriptType( rInf.GetIdx() - 1 ) - 1;
     498                 :            :                 }
     499                 :            : 
     500                 :        854 :                 nLstHeight /= 5;
     501                 :            :                 // does the kerning portion still fit into the line?
     502 [ +  + ][ -  + ]:        854 :                 if( bAllowBefore && ( nLstActual != nNxtActual ) &&
           [ #  #  #  # ]
                 [ -  + ]
     503                 :          0 :                     nLstHeight && rInf.X() + nLstHeight <= rInf.Width() )
     504                 :            :                 {
     505                 :            :                     SwKernPortion* pKrn =
     506                 :            :                         new SwKernPortion( *rInf.GetLast(), nLstHeight,
     507 [ #  # ][ #  # ]:          0 :                                            pLast->InFldGrp() && pPor->InFldGrp() );
                 [ #  # ]
     508                 :          0 :                     rInf.GetLast()->SetPortion( NULL );
     509                 :          0 :                     InsertPortion( rInf, pKrn );
     510                 :            :                 }
     511                 :            :             }
     512                 :            :         }
     513 [ -  + ][ #  # ]:      54069 :         else if ( bHasGrid && ! pGridKernPortion && ! pMulti )
                 [ #  # ]
     514                 :            :         {
     515                 :            :             // insert a grid kerning portion
     516         [ #  # ]:          0 :             if ( ! pGridKernPortion )
     517                 :          0 :                 pGridKernPortion = pPor->IsKernPortion() ?
     518                 :            :                                    (SwKernPortion*)pPor :
     519 [ #  # ][ #  # ]:          0 :                                    new SwKernPortion( *pCurr );
     520                 :            : 
     521                 :            :             // if we have a new GridKernPortion, we initially calculate
     522                 :            :             // its size so that its ends on the grid
     523                 :          0 :             const SwPageFrm* pPageFrm = pFrm->FindPageFrm();
     524                 :          0 :             const SwLayoutFrm* pBody = pPageFrm->FindBodyCont();
     525 [ #  # ][ #  # ]:          0 :             SWRECTFN( pPageFrm )
         [ #  # ][ #  # ]
     526                 :            : 
     527                 :            :             const long nGridOrigin = pBody ?
     528         [ #  # ]:          0 :                                     (pBody->*fnRect->fnGetPrtLeft)() :
     529 [ #  # ][ #  # ]:          0 :                                     (pPageFrm->*fnRect->fnGetPrtLeft)();
     530                 :            : 
     531                 :          0 :             SwTwips nStartX = rInf.X() + GetLeftMargin();
     532         [ #  # ]:          0 :             if ( bVert )
     533                 :            :             {
     534                 :          0 :                 Point aPoint( nStartX, 0 );
     535         [ #  # ]:          0 :                 pFrm->SwitchHorizontalToVertical( aPoint );
     536                 :          0 :                 nStartX = aPoint.Y();
     537                 :            :             }
     538                 :            : 
     539                 :          0 :             const SwTwips nOfst = nStartX - nGridOrigin;
     540         [ #  # ]:          0 :             if ( nOfst )
     541                 :            :             {
     542                 :            :                 const sal_uLong i = ( nOfst > 0 ) ?
     543                 :            :                                 ( ( nOfst - 1 ) / nGridWidth + 1 ) :
     544         [ #  # ]:          0 :                                 0;
     545                 :          0 :                 const SwTwips nKernWidth = i * nGridWidth - nOfst;
     546                 :          0 :                 const SwTwips nRestWidth = rInf.Width() - rInf.X();
     547                 :            : 
     548         [ #  # ]:          0 :                 if ( nKernWidth <= nRestWidth )
     549                 :          0 :                     pGridKernPortion->Width( (sal_uInt16)nKernWidth );
     550                 :            :             }
     551                 :            : 
     552         [ #  # ]:          0 :             if ( pGridKernPortion != pPor )
     553                 :          0 :                 InsertPortion( rInf, pGridKernPortion );
     554                 :            :         }
     555                 :            : 
     556                 :            :         // the multi-portion has it's own format function
     557 [ +  + ][ -  + ]:      55613 :         if( pPor->IsMultiPortion() && ( !pMulti || pMulti->IsBidi() ) )
         [ #  # ][ +  + ]
     558                 :        356 :             bFull = BuildMultiPortion( rInf, *((SwMultiPortion*)pPor) );
     559                 :            :         else
     560                 :      55257 :             bFull = pPor->Format( rInf );
     561                 :            : 
     562 [ +  + ][ +  - ]:      55613 :         if( rInf.IsRuby() && !rInf.GetRest() )
                 [ +  + ]
     563                 :        336 :             bFull = sal_True;
     564                 :            : 
     565                 :            :         // if we are underlined, we store the beginning of this underlined
     566                 :            :         // segment for repaint optimization
     567 [ +  + ][ +  + ]:      55613 :         if ( UNDERLINE_NONE != pFnt->GetUnderline() && ! nUnderLineStart )
                 [ +  + ]
     568                 :        737 :             nUnderLineStart = GetLeftMargin() + rInf.X();
     569                 :            : 
     570         [ +  + ]:      55613 :         if ( pPor->IsFlyPortion() )
     571                 :        119 :             pCurr->SetFly( sal_True );
     572                 :            :         // some special cases, where we have to take care for the repaint
     573                 :            :         // offset:
     574                 :            :         // 1. Underlined portions due to special underline feature
     575                 :            :         // 2. Right Tab
     576                 :            :         // 3. BidiPortions
     577                 :            :         // 4. other Multiportions
     578                 :            :         // 5. DropCaps
     579                 :            :         // 6. Grid Mode
     580 [ +  + ][ +  + ]:      58289 :         else if ( ( ! rInf.GetPaintOfst() || nUnderLineStart < rInf.GetPaintOfst() ) &&
           [ +  +  +  +  
          +  -  +  +  +  
                +  +  + ]
                 [ +  + ]
     581                 :            :                   // 1. Underlined portions
     582                 :            :                   nUnderLineStart &&
     583                 :            :                      // reformat is at end of an underlined portion and next portion
     584                 :            :                      // is not underlined
     585                 :        619 :                   ( ( rInf.GetReformatStart() == rInf.GetIdx() &&
     586                 :        459 :                       UNDERLINE_NONE == pFnt->GetUnderline()
     587                 :            :                     ) ||
     588                 :            :                      // reformat is inside portion and portion is underlined
     589                 :        619 :                     ( rInf.GetReformatStart() >= rInf.GetIdx() &&
     590                 :        599 :                       rInf.GetReformatStart() <= rInf.GetIdx() + pPor->GetLen() &&
     591                 :        499 :                       UNDERLINE_NONE != pFnt->GetUnderline() ) ) )
     592                 :        495 :             rInf.SetPaintOfst( nUnderLineStart );
     593   [ +  +  +  +  :     273598 :         else if (  ! rInf.GetPaintOfst() &&
          +  +  +  +  +  
          -  +  -  +  +  
             +  +  +  + ]
           [ -  +  #  # ]
                 [ +  + ]
     594                 :            :                    // 2. Right Tab
     595                 :      54680 :                    ( ( pPor->InTabGrp() && !pPor->IsTabLeftPortion() ) ||
     596                 :            :                    // 3. BidiPortions
     597                 :      54643 :                      ( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->IsBidi() ) ||
     598                 :            :                    // 4. Multi Portion and 5. Drop Caps
     599                 :     108954 :                      ( ( pPor->IsDropPortion() || pPor->IsMultiPortion() ) &&
     600                 :        166 :                        rInf.GetReformatStart() >= rInf.GetIdx() &&
     601                 :        156 :                        rInf.GetReformatStart() <= rInf.GetIdx() + pPor->GetLen() )
     602                 :            :                    // 6. Grid Mode
     603                 :          0 :                      || ( bHasGrid && SW_CJK != pFnt->GetActual() )
     604                 :            :                    )
     605                 :            :                 )
     606                 :            :             // we store the beginning of the critical portion as our
     607                 :            :             // paint offset
     608                 :         88 :             rInf.SetPaintOfst( GetLeftMargin() + rInf.X() );
     609                 :            : 
     610                 :            :         // under one of these conditions we are allowed to delete the
     611                 :            :         // start of the underline portion
     612         [ +  + ]:      55613 :         if ( IsUnderlineBreak( *pPor, *pFnt ) )
     613                 :      55304 :             nUnderLineStart = 0;
     614                 :            : 
     615         [ +  + ]:      55969 :         if( pPor->IsFlyCntPortion() || ( pPor->IsMultiPortion() &&
           [ +  +  -  + ]
                 [ +  + ]
     616                 :        356 :             ((SwMultiPortion*)pPor)->HasFlyInCntnt() ) )
     617                 :       1290 :             SetFlyInCntBase();
     618                 :            :         // bUnderFlow needs to be reset or we wrap again at the next softhyphen
     619         [ +  + ]:      55613 :         if ( !bFull )
     620                 :            :         {
     621                 :      14023 :             rInf.ClrUnderFlow();
     622 [ +  + ][ +  +  :      37559 :             if( ! bHasGrid && rInf.HasScriptSpace() && pPor->InTxtGrp() &&
             +  +  +  + ]
         [ +  + ][ +  - ]
     623                 :      23536 :                 pPor->GetLen() && !pPor->InFldGrp() )
     624                 :            :             {
     625                 :            :                 // The distance between two different scripts is set
     626                 :            :                 // to 20% of the fontheight.
     627                 :      10639 :                 xub_StrLen nTmp = rInf.GetIdx() + pPor->GetLen();
     628         [ -  + ]:      19555 :                 if( nTmp == pScriptInfo->NextScriptChg( nTmp - 1 ) &&
           [ +  +  -  + ]
     629                 :       8916 :                     nTmp != rInf.GetTxt().Len() )
     630                 :            :                 {
     631                 :          0 :                     sal_uInt16 nDist = (sal_uInt16)(rInf.GetFont()->GetHeight()/5);
     632                 :            : 
     633         [ #  # ]:          0 :                     if( nDist )
     634                 :            :                     {
     635                 :            :                         // we do not want a kerning portion if any end
     636                 :            :                         // would be a punctuation character
     637                 :          0 :                         const CharClass& rCC = GetAppCharClass();
     638         [ #  # ]:          0 :                         if ( rCC.isLetterNumeric( rInf.GetTxt(), nTmp - 1 ) &&
           [ #  #  #  # ]
     639                 :          0 :                              rCC.isLetterNumeric( rInf.GetTxt(), nTmp ) )
     640                 :            :                         {
     641                 :            :                             // does the kerning portion still fit into the line?
     642         [ #  # ]:          0 :                             if ( rInf.X() + pPor->Width() + nDist <= rInf.Width() )
     643         [ #  # ]:          0 :                                 new SwKernPortion( *pPor, nDist );
     644                 :            :                             else
     645                 :          0 :                                 bFull = sal_True;
     646                 :            :                         }
     647                 :            :                     }
     648                 :            :                 }
     649                 :            :             }
     650                 :            :         }
     651                 :            : 
     652 [ -  + ][ #  # ]:      55613 :         if ( bHasGrid && pPor != pGridKernPortion && ! pMulti )
                 [ #  # ]
     653                 :            :         {
     654                 :          0 :             xub_StrLen nTmp = rInf.GetIdx() + pPor->GetLen();
     655                 :          0 :             const SwTwips nRestWidth = rInf.Width() - rInf.X() - pPor->Width();
     656                 :            : 
     657                 :          0 :             const sal_uInt8 nCurrScript = pFnt->GetActual(); // pScriptInfo->ScriptType( rInf.GetIdx() );
     658                 :          0 :             const sal_uInt8 nNextScript = nTmp >= rInf.GetTxt().Len() ?
     659                 :            :                                      SW_CJK :
     660         [ #  # ]:          0 :                                      SwScriptInfo::WhichFont( nTmp, 0, pScriptInfo );
     661                 :            : 
     662                 :            :             // snap non-asian text to grid if next portion is ASIAN or
     663                 :            :             // there are no more portions in this line
     664                 :            :             // be careful when handling an underflow event: the gridkernportion
     665                 :            :             // could have been deleted
     666         [ #  # ]:          0 :             if ( nRestWidth > 0 && SW_CJK != nCurrScript &&
           [ #  #  #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     667                 :          0 :                 ! rInf.IsUnderFlow() && ( bFull || SW_CJK == nNextScript ) )
     668                 :            :             {
     669                 :            :                 OSL_ENSURE( pGridKernPortion, "No GridKernPortion available" );
     670                 :            : 
     671                 :            :                 // calculate size
     672                 :          0 :                 SwLinePortion* pTmpPor = pGridKernPortion->GetPortion();
     673                 :          0 :                 sal_uInt16 nSumWidth = pPor->Width();
     674         [ #  # ]:          0 :                 while ( pTmpPor )
     675                 :            :                 {
     676                 :          0 :                     nSumWidth = nSumWidth + pTmpPor->Width();
     677                 :          0 :                     pTmpPor = pTmpPor->GetPortion();
     678                 :            :                 }
     679                 :            : 
     680                 :            :                 const sal_uInt16 i = nSumWidth ?
     681                 :            :                                  ( nSumWidth - 1 ) / nGridWidth + 1 :
     682         [ #  # ]:          0 :                                  0;
     683                 :          0 :                 const SwTwips nTmpWidth = i * nGridWidth;
     684                 :            :                 const SwTwips nKernWidth = Min( (SwTwips)(nTmpWidth - nSumWidth),
     685                 :          0 :                                                 nRestWidth );
     686                 :          0 :                 const sal_uInt16 nKernWidth_1 = (sal_uInt16)(nKernWidth / 2);
     687                 :            : 
     688                 :            :                 OSL_ENSURE( nKernWidth <= nRestWidth,
     689                 :            :                         "Not enough space left for adjusting non-asian text in grid mode" );
     690                 :            : 
     691                 :          0 :                 pGridKernPortion->Width( pGridKernPortion->Width() + nKernWidth_1 );
     692                 :          0 :                 rInf.X( rInf.X() + nKernWidth_1 );
     693                 :            : 
     694         [ #  # ]:          0 :                 if ( ! bFull )
     695                 :            :                     new SwKernPortion( *pPor, (short)(nKernWidth - nKernWidth_1),
     696         [ #  # ]:          0 :                                        sal_False, sal_True );
     697                 :            : 
     698                 :          0 :                 pGridKernPortion = 0;
     699                 :            :             }
     700 [ #  # ][ #  #  :          0 :             else if ( pPor->IsMultiPortion() || pPor->InFixMargGrp() ||
          #  #  #  #  #  
              # ][ #  # ]
                 [ #  # ]
     701                 :          0 :                       pPor->IsFlyCntPortion() || pPor->InNumberGrp() ||
     702                 :          0 :                       pPor->InFldGrp() || nCurrScript != nNextScript )
     703                 :            :                 // next portion should snap to grid
     704                 :          0 :                 pGridKernPortion = 0;
     705                 :            :         }
     706                 :            : 
     707                 :      55613 :         rInf.SetFull( bFull );
     708                 :            : 
     709                 :            :         // Restportions from fields with multiple lines don't yet have the right ascent
     710   [ +  +  +  -  :      59013 :         if ( !pPor->GetLen() && !pPor->IsFlyPortion()
             +  +  +  - ]
         [ +  + ][ +  + ]
     711                 :       2624 :             && !pPor->IsGrfNumPortion() && ! pPor->InNumberGrp()
     712                 :        776 :             && !pPor->IsMultiPortion() )
     713                 :        776 :             CalcAscent( rInf, pPor );
     714                 :            : 
     715                 :      55613 :         InsertPortion( rInf, pPor );
     716                 :      55613 :         pPor = NewPortion( rInf );
     717                 :            :     }
     718                 :            : 
     719         [ +  - ]:      53784 :     if( !rInf.IsStop() )
     720                 :            :     {
     721                 :            :         // The last right centered, decimal tab
     722                 :      53784 :         SwTabPortion *pLastTab = rInf.GetLastTab();
     723         [ +  + ]:      53784 :         if( pLastTab )
     724                 :          2 :             pLastTab->FormatEOL( rInf );
     725 [ +  - ][ +  + ]:      53782 :         else if( rInf.GetLast() && rInf.LastKernPortion() )
                 [ +  + ]
     726                 :        256 :             rInf.GetLast()->FormatEOL( rInf );
     727                 :            :     }
     728         [ +  + ]:      54146 :     if( pCurr->GetPortion() && pCurr->GetPortion()->InNumberGrp()
           [ +  +  -  + ]
                 [ -  + ]
     729                 :        362 :         && ((SwNumberPortion*)pCurr->GetPortion())->IsHide() )
     730                 :          0 :         rInf.SetNumDone( sal_False );
     731                 :            : 
     732                 :            :     // Delete fly in any case
     733                 :      53784 :     ClearFly( rInf );
     734                 :            : 
     735                 :            :     // Reinit the tab overflow flag after the line
     736                 :      53784 :     rInf.SetTabOverflow( sal_False );
     737                 :      53784 : }
     738                 :            : 
     739                 :            : /*************************************************************************
     740                 :            :  *                 SwTxtFormatter::CalcAdjustLine()
     741                 :            :  *************************************************************************/
     742                 :            : 
     743                 :      52762 : void SwTxtFormatter::CalcAdjustLine( SwLineLayout *pCurrent )
     744                 :            : {
     745 [ +  + ][ +  - ]:      52762 :     if( SVX_ADJUST_LEFT != GetAdjust() && !pMulti)
                 [ +  + ]
     746                 :            :     {
     747                 :        953 :         pCurrent->SetFormatAdj(sal_True);
     748         [ +  + ]:        953 :         if( IsFlyInCntBase() )
     749                 :            :         {
     750                 :          3 :             CalcAdjLine( pCurrent );
     751                 :            :             // For e.g. centered fly we need to switch the RefPoint
     752                 :            :             // That's why bAllWays = sal_True
     753                 :          3 :             UpdatePos( pCurrent, GetTopLeft(), GetStart(), sal_True );
     754                 :            :         }
     755                 :            :     }
     756                 :      52762 : }
     757                 :            : 
     758                 :            : /*************************************************************************
     759                 :            :  *                      SwTxtFormatter::CalcAscent()
     760                 :            :  *************************************************************************/
     761                 :            : 
     762                 :     108095 : void SwTxtFormatter::CalcAscent( SwTxtFormatInfo &rInf, SwLinePortion *pPor )
     763                 :            : {
     764 [ +  + ][ +  + ]:     108095 :     if ( pPor->InFldGrp() && ((SwFldPortion*)pPor)->GetFont() )
                 [ +  + ]
     765                 :            :     {
     766                 :            :         // Numbering + InterNetFlds can keep an own font, then their size is
     767                 :            :         // independent from hard attribute values
     768                 :       1215 :         SwFont* pFldFnt = ((SwFldPortion*)pPor)->pFnt;
     769         [ +  - ]:       1215 :         SwFontSave aSave( rInf, pFldFnt );
     770         [ +  - ]:       1215 :         ((SwFldPortion*)pPor)->Height( pFldFnt->GetHeight( rInf.GetVsh(), *rInf.GetOut() ) );
     771 [ +  - ][ +  - ]:       1215 :         ((SwFldPortion*)pPor)->SetAscent( pFldFnt->GetAscent( rInf.GetVsh(), *rInf.GetOut() ) );
     772                 :            :     }
     773                 :            :     // #i89179#
     774                 :            :     // tab portion representing the list tab of a list label gets the
     775                 :            :     // same height and ascent as the corresponding number portion
     776 [ +  + ][ +  +  :     107924 :     else if ( pPor->InTabGrp() && pPor->GetLen() == 0 &&
          +  -  +  -  +  
              - ][ +  + ]
     777                 :        696 :               rInf.GetLast() && rInf.GetLast()->InNumberGrp() &&
     778                 :        348 :               static_cast<const SwNumberPortion*>(rInf.GetLast())->HasFont() )
     779                 :            :     {
     780                 :        348 :         const SwLinePortion* pLast = rInf.GetLast();
     781                 :        348 :         pPor->Height( pLast->Height() );
     782                 :        348 :         pPor->SetAscent( pLast->GetAscent() );
     783                 :            :     }
     784                 :            :     else
     785                 :            :     {
     786                 :     106532 :         const SwLinePortion *pLast = rInf.GetLast();
     787                 :            :         sal_Bool bChg;
     788                 :            : 
     789                 :            :         // In empty lines the attributes are switched on via SeekStart
     790                 :     106532 :         const sal_Bool bFirstPor = rInf.GetLineStart() == rInf.GetIdx();
     791         [ -  + ]:     106532 :         if ( pPor->IsQuoVadisPortion() )
     792                 :          0 :             bChg = SeekStartAndChg( rInf, sal_True );
     793                 :            :         else
     794                 :            :         {
     795         [ +  + ]:     106532 :             if( bFirstPor )
     796                 :            :             {
     797         [ +  + ]:     104297 :                 if( rInf.GetTxt().Len() )
     798                 :            :                 {
     799 [ +  + ][ +  + ]:     145184 :                     if ( pPor->GetLen() || !rInf.GetIdx()
           [ -  +  #  #  
           +  - ][ +  - ]
     800                 :          0 :                          || ( pCurr != pLast && !pLast->IsFlyPortion() )
     801                 :      42709 :                          || !pCurr->IsRest() ) // instead of !rInf.GetRest()
     802                 :     102475 :                         bChg = SeekAndChg( rInf );
     803                 :            :                     else
     804                 :          0 :                         bChg = SeekAndChgBefore( rInf );
     805                 :            :                 }
     806         [ -  + ]:       1822 :                 else if ( pMulti )
     807                 :            :                     // do not open attributes starting at 0 in empty multi
     808                 :            :                     // portions (rotated numbering followed by a footnote
     809                 :            :                     // can cause trouble, because the footnote attribute
     810                 :            :                     // starts at 0, but if we open it, the attribute handler
     811                 :            :                     // cannot handle it.
     812                 :          0 :                     bChg = sal_False;
     813                 :            :                 else
     814                 :       1822 :                     bChg = SeekStartAndChg( rInf );
     815                 :            :             }
     816                 :            :             else
     817                 :       2235 :                 bChg = SeekAndChg( rInf );
     818                 :            :         }
     819 [ +  + ][ -  + ]:     106532 :         if( bChg || bFirstPor || !pPor->GetAscent()
           [ #  #  #  # ]
                 [ +  - ]
     820                 :          0 :             || !rInf.GetLast()->InTxtGrp() )
     821                 :            :         {
     822                 :     106532 :             pPor->SetAscent( rInf.GetAscent()  );
     823                 :     106532 :             pPor->Height( rInf.GetTxtHeight() );
     824                 :            :         }
     825                 :            :         else
     826                 :            :         {
     827                 :          0 :             pPor->Height( pLast->Height() );
     828                 :          0 :             pPor->SetAscent( pLast->GetAscent() );
     829                 :            :         }
     830                 :            :     }
     831                 :     108095 : }
     832                 :            : 
     833                 :            : /*************************************************************************
     834                 :            :  *                      class SwMetaPortion
     835                 :            :  *************************************************************************/
     836                 :            : 
     837         [ -  + ]:       1152 : class SwMetaPortion : public SwTxtPortion
     838                 :            : {
     839                 :            : public:
     840                 :        576 :     inline  SwMetaPortion() { SetWhichPor( POR_META ); }
     841                 :            :     virtual void Paint( const SwTxtPaintInfo &rInf ) const;
     842                 :            : //    OUTPUT_OPERATOR
     843                 :            : };
     844                 :            : 
     845                 :            : //CLASSIO( SwMetaPortion )
     846                 :            : 
     847                 :            : /*************************************************************************
     848                 :            :  *               virtual SwMetaPortion::Paint()
     849                 :            :  *************************************************************************/
     850                 :            : 
     851                 :        602 : void SwMetaPortion::Paint( const SwTxtPaintInfo &rInf ) const
     852                 :            : {
     853         [ +  - ]:        602 :     if ( Width() )
     854                 :            :     {
     855                 :        602 :         rInf.DrawViewOpt( *this, POR_META );
     856                 :        602 :         SwTxtPortion::Paint( rInf );
     857                 :            :     }
     858                 :        602 : }
     859                 :            : 
     860                 :            : 
     861                 :            : /*************************************************************************
     862                 :            :  *                      SwTxtFormatter::WhichTxtPor()
     863                 :            :  *************************************************************************/
     864                 :            : 
     865                 :      51271 : SwTxtPortion *SwTxtFormatter::WhichTxtPor( SwTxtFormatInfo &rInf ) const
     866                 :            : {
     867                 :      51271 :     SwTxtPortion *pPor = 0;
     868         [ +  + ]:      51271 :     if( GetFnt()->IsTox() )
     869         [ +  - ]:         42 :         pPor = new SwToxPortion;
     870                 :            :     else
     871                 :            :     {
     872         [ +  + ]:      51229 :         if( GetFnt()->IsRef() )
     873         [ +  - ]:         36 :             pPor = new SwRefPortion;
     874         [ +  + ]:      51193 :         else if (GetFnt()->IsMeta())
     875                 :            :         {
     876         [ +  - ]:        576 :             pPor = new SwMetaPortion;
     877                 :            :         }
     878                 :            :         else
     879                 :            :         {
     880                 :            :             // Only at the End!
     881                 :            :             // If pCurr does not have a width, it can however aready have content.
     882                 :            :             // E.g. for non-displayable characters
     883         [ +  + ]:      50617 :             if( rInf.GetLen() > 0 )
     884                 :            :             {
     885         [ +  + ]:      50052 :                 if( rInf.GetTxt().GetChar(rInf.GetIdx())==CH_TXT_ATR_FIELDSTART )
     886         [ +  - ]:         18 :                     pPor = new SwFieldMarkPortion();
     887         [ +  + ]:      50034 :                 else if( rInf.GetTxt().GetChar(rInf.GetIdx())==CH_TXT_ATR_FIELDEND )
     888         [ +  - ]:         18 :                     pPor = new SwFieldMarkPortion();
     889         [ +  + ]:      50016 :                 else if( rInf.GetTxt().GetChar(rInf.GetIdx())==CH_TXT_ATR_FORMELEMENT )
     890         [ +  - ]:          3 :                     pPor = new SwFieldFormPortion();
     891                 :            :             }
     892         [ +  + ]:      50617 :             if( !pPor )
     893                 :            :             {
     894 [ +  + ][ +  + ]:      50578 :                 if( !rInf.X() && !pCurr->GetPortion() && !pCurr->GetLen() && !GetFnt()->IsURL() )
         [ +  - ][ +  - ]
                 [ +  + ]
     895                 :      49260 :                     pPor = pCurr;
     896                 :            :                 else
     897                 :            :                 {
     898         [ +  - ]:       1318 :                     pPor = new SwTxtPortion;
     899         [ -  + ]:       1318 :                     if( GetFnt()->IsURL() )
     900                 :          0 :                         pPor->SetWhichPor( POR_URL );
     901                 :            :                 }
     902                 :            :             }
     903                 :            :         }
     904                 :            :     }
     905                 :      51271 :     return pPor;
     906                 :            : }
     907                 :            : 
     908                 :            : /*************************************************************************
     909                 :            :  *                      SwTxtFormatter::NewTxtPortion()
     910                 :            :  *************************************************************************/
     911                 :            : // We calculate the length, the following portion limits are defined:
     912                 :            : // 1) Tabs
     913                 :            : // 2) Linebreaks
     914                 :            : // 3) CH_TXTATR_BREAKWORD / CH_TXTATR_INWORD
     915                 :            : // 4) next attribute change
     916                 :            : 
     917                 :      51271 : SwTxtPortion *SwTxtFormatter::NewTxtPortion( SwTxtFormatInfo &rInf )
     918                 :            : {
     919                 :            :     // If we're at the line's beginning, we take pCurr
     920                 :            :     // If pCurr is not derived from SwTxtPortion, we need to duplicate
     921                 :      51271 :     Seek( rInf.GetIdx() );
     922                 :      51271 :     SwTxtPortion *pPor = WhichTxtPor( rInf );
     923                 :            : 
     924                 :            :     // until next attribute change:
     925                 :      51271 :     const xub_StrLen nNextAttr = GetNextAttr();
     926                 :      51271 :     xub_StrLen nNextChg = Min( nNextAttr, rInf.GetTxt().Len() );
     927                 :            : 
     928                 :            :     // end of script type:
     929                 :      51271 :     const xub_StrLen nNextScript = pScriptInfo->NextScriptChg( rInf.GetIdx() );
     930                 :      51271 :     nNextChg = Min( nNextChg, nNextScript );
     931                 :            : 
     932                 :            :     // end of direction:
     933                 :      51271 :     const xub_StrLen nNextDir = pScriptInfo->NextDirChg( rInf.GetIdx() );
     934                 :      51271 :     nNextChg = Min( nNextChg, nNextDir );
     935                 :            : 
     936                 :            :     // Turbo boost:
     937                 :            :     // We assume that a font's characters are not larger than twice
     938                 :            :     // as wide as heigh.
     939                 :            :     // Very crazy: We need to take the ascent into account.
     940                 :            :     //
     941                 :            :     // Mind the trap! GetSize() contains the wished-for height, the real height
     942                 :            :     // is only known in CalcAscent!
     943                 :            :     //
     944                 :            :     // The ratio is even crazier: a blank in Times New Roman has an ascent of
     945                 :            :     // 182, a height of 200 and a width of 53!
     946                 :            :     // It follows that a line with a lot of blanks is processed incorrectly.
     947                 :            :     // Therefore we increase from factor 2 to 8 (due to negative kerning).
     948                 :            : 
     949                 :      51271 :     pPor->SetLen(1);
     950                 :      51271 :     CalcAscent( rInf, pPor );
     951                 :            : 
     952                 :      51271 :     const SwFont* pTmpFnt = rInf.GetFont();
     953                 :      51271 :     KSHORT nExpect = Min( KSHORT( ((Font *)pTmpFnt)->GetSize().Height() ),
     954                 :     102542 :                           KSHORT( pPor->GetAscent() ) ) / 8;
     955         [ -  + ]:      51271 :     if ( !nExpect )
     956                 :          0 :         nExpect = 1;
     957                 :      51271 :     nExpect = (sal_uInt16)(rInf.GetIdx() + ((rInf.Width() - rInf.X()) / nExpect));
     958 [ +  + ][ +  + ]:      51271 :     if( nExpect > rInf.GetIdx() && nNextChg > nExpect )
                 [ +  - ]
     959                 :      28743 :         nNextChg = Min( nExpect, rInf.GetTxt().Len() );
     960                 :            : 
     961                 :            :     // we keep an invariant during method calls:
     962                 :            :     // there are no portion ending characters like hard spaces
     963                 :            :     // or tabs in [ nLeftScanIdx, nRightScanIdx ]
     964 [ +  + ][ +  + ]:      51271 :     if ( nLeftScanIdx <= rInf.GetIdx() && rInf.GetIdx() <= nRightScanIdx )
                 [ +  + ]
     965                 :            :     {
     966         [ +  + ]:      39259 :         if ( nNextChg > nRightScanIdx )
     967                 :            :             nNextChg = nRightScanIdx =
     968                 :      27656 :                 rInf.ScanPortionEnd( nRightScanIdx, nNextChg );
     969                 :            :     }
     970                 :            :     else
     971                 :            :     {
     972                 :      12012 :         nLeftScanIdx = rInf.GetIdx();
     973                 :            :         nNextChg = nRightScanIdx =
     974                 :      12012 :                 rInf.ScanPortionEnd( rInf.GetIdx(), nNextChg );
     975                 :            :     }
     976                 :            : 
     977                 :      51271 :     pPor->SetLen( nNextChg - rInf.GetIdx() );
     978                 :      51271 :     rInf.SetLen( pPor->GetLen() );
     979                 :      51271 :     return pPor;
     980                 :            : }
     981                 :            : 
     982                 :            : 
     983                 :            : /*************************************************************************
     984                 :            :  *                 SwTxtFormatter::WhichFirstPortion()
     985                 :            :  *************************************************************************/
     986                 :            : 
     987                 :     109031 : SwLinePortion *SwTxtFormatter::WhichFirstPortion(SwTxtFormatInfo &rInf)
     988                 :            : {
     989                 :     109031 :     SwLinePortion *pPor = 0;
     990                 :            : 
     991         [ +  + ]:     109031 :     if( rInf.GetRest() )
     992                 :            :     {
     993                 :            :         // Tabs and fields
     994         [ +  + ]:        684 :         if( '\0' != rInf.GetHookChar() )
     995                 :        174 :             return 0;
     996                 :            : 
     997                 :        510 :         pPor = rInf.GetRest();
     998         [ -  + ]:        510 :         if( pPor->IsErgoSumPortion() )
     999                 :          0 :             rInf.SetErgoDone(sal_True);
    1000                 :            :         else
    1001         [ -  + ]:        510 :             if( pPor->IsFtnNumPortion() )
    1002                 :          0 :                 rInf.SetFtnDone(sal_True);
    1003                 :            :             else
    1004         [ +  + ]:        510 :                 if( pPor->InNumberGrp() )
    1005                 :        174 :                     rInf.SetNumDone(sal_True);
    1006                 :            : 
    1007                 :        510 :         rInf.SetRest(0);
    1008                 :        510 :         pCurr->SetRest( sal_True );
    1009                 :        510 :         return pPor;
    1010                 :            :     }
    1011                 :            : 
    1012                 :            :     // We can stand in the follow, it's crucial that
    1013                 :            :     // pFrm->GetOfst() == 0!
    1014         [ +  + ]:     108347 :     if( rInf.GetIdx() )
    1015                 :            :     {
    1016                 :            :         // We now too can elongate FtnPortions and ErgoSumPortions
    1017                 :            : 
    1018                 :            :         // 1. The ErgoSumTexts
    1019         [ +  + ]:      96761 :         if( !rInf.IsErgoDone() )
    1020                 :            :         {
    1021 [ -  + ][ #  # ]:       3917 :             if( pFrm->IsInFtn() && !pFrm->GetIndPrev() )
                 [ -  + ]
    1022                 :          0 :                 pPor = (SwLinePortion*)NewErgoSumPortion( rInf );
    1023                 :       3917 :             rInf.SetErgoDone( sal_True );
    1024                 :            :         }
    1025                 :            : 
    1026                 :            :         // 2. Arrow portions
    1027 [ +  - ][ +  + ]:      96761 :         if( !pPor && !rInf.IsArrowDone() )
                 [ +  + ]
    1028                 :            :         {
    1029         [ +  + ]:      12793 :             if( pFrm->GetOfst() && !pFrm->IsFollow() &&
           [ +  +  +  - ]
                 [ +  + ]
    1030                 :         42 :                 rInf.GetIdx() == pFrm->GetOfst() )
    1031         [ +  - ]:         42 :                 pPor = new SwArrowPortion( *pCurr );
    1032                 :      12751 :             rInf.SetArrowDone( sal_True );
    1033                 :            :         }
    1034                 :            : 
    1035                 :            :         // 3. Kerning portions at beginning of line in grid mode
    1036 [ +  + ][ +  + ]:      96761 :         if ( ! pPor && ! pCurr->GetPortion() )
                 [ +  + ]
    1037                 :            :         {
    1038 [ +  - ][ -  + ]:      90119 :             GETGRID( GetTxtFrm()->FindPageFrm() )
         [ #  # ][ -  + ]
    1039         [ -  + ]:      90119 :             if ( pGrid )
    1040         [ #  # ]:          0 :                 pPor = new SwKernPortion( *pCurr );
    1041                 :            :         }
    1042                 :            : 
    1043                 :            :         // 4. The line rests (multiline fields)
    1044         [ +  + ]:      96761 :         if( !pPor )
    1045                 :            :         {
    1046                 :      96719 :             pPor = rInf.GetRest();
    1047                 :            :             // Only for pPor of course
    1048         [ -  + ]:      96719 :             if( pPor )
    1049                 :            :             {
    1050                 :          0 :                 pCurr->SetRest( sal_True );
    1051                 :          0 :                 rInf.SetRest(0);
    1052                 :            :             }
    1053                 :            :         }
    1054                 :            :     }
    1055                 :            :     else
    1056                 :            :     {
    1057                 :            :         // 5. The foot note count
    1058         [ +  + ]:      11586 :         if( !rInf.IsFtnDone() )
    1059                 :            :         {
    1060                 :            :             OSL_ENSURE( ( ! rInf.IsMulti() && ! pMulti ) || pMulti->HasRotation(),
    1061                 :            :                      "Rotated number portion trouble" );
    1062                 :            : 
    1063                 :      10651 :             sal_Bool bFtnNum = pFrm->IsFtnNumFrm();
    1064                 :      10651 :             rInf.GetParaPortion()->SetFtnNum( bFtnNum );
    1065         [ +  + ]:      10651 :             if( bFtnNum )
    1066                 :        128 :                 pPor = (SwLinePortion*)NewFtnNumPortion( rInf );
    1067                 :      10651 :             rInf.SetFtnDone( sal_True );
    1068                 :            :         }
    1069                 :            : 
    1070                 :            :         // 6. The ErgoSumTexts of course also exist in the TextMaster,
    1071                 :            :         // it's crucial whether the SwFtnFrm is aFollow
    1072 [ +  + ][ +  + ]:      11586 :         if( !rInf.IsErgoDone() && !pPor && ! rInf.IsMulti() )
         [ +  + ][ +  + ]
    1073                 :            :         {
    1074 [ +  + ][ +  + ]:      10642 :             if( pFrm->IsInFtn() && !pFrm->GetIndPrev() )
                 [ +  + ]
    1075                 :        128 :                 pPor = (SwLinePortion*)NewErgoSumPortion( rInf );
    1076                 :      10642 :             rInf.SetErgoDone( sal_True );
    1077                 :            :         }
    1078                 :            : 
    1079                 :            :         // 7. The numbering
    1080 [ +  + ][ +  + ]:      11586 :         if( !rInf.IsNumDone() && !pPor )
                 [ +  + ]
    1081                 :            :         {
    1082                 :            :             OSL_ENSURE( ( ! rInf.IsMulti() && ! pMulti ) || pMulti->HasRotation(),
    1083                 :            :                      "Rotated number portion trouble" );
    1084                 :            : 
    1085                 :            :             // If we're in the follow, then of course not
    1086         [ +  + ]:      10514 :             if( GetTxtFrm()->GetTxtNode()->GetNumRule() )
    1087                 :        240 :                 pPor = (SwLinePortion*)NewNumberPortion( rInf );
    1088                 :      10514 :             rInf.SetNumDone( sal_True );
    1089                 :            :         }
    1090                 :            :         // 8. The DropCaps
    1091 [ +  + ][ -  + ]:      11586 :         if( !pPor && GetDropFmt() && ! rInf.IsMulti() )
         [ #  # ][ -  + ]
    1092                 :          0 :             pPor = (SwLinePortion*)NewDropPortion( rInf );
    1093                 :            : 
    1094                 :            :         // 9. Kerning portions at beginning of line in grid mode
    1095 [ +  + ][ +  + ]:      11586 :         if ( !pPor && !pCurr->GetPortion() )
                 [ +  + ]
    1096                 :            :         {
    1097 [ +  - ][ -  + ]:      10681 :             GETGRID( GetTxtFrm()->FindPageFrm() )
         [ #  # ][ -  + ]
    1098         [ -  + ]:      10681 :             if ( pGrid )
    1099         [ #  # ]:          0 :                 pPor = new SwKernPortion( *pCurr );
    1100                 :            :         }
    1101                 :            :     }
    1102                 :            : 
    1103                 :            :         // 10. Decimal tab portion at the beginning of each line in table cells
    1104 [ +  + ][ +  +  :     211967 :         if ( !pPor && !pCurr->GetPortion() &&
             +  +  +  - ]
                 [ +  + ]
    1105                 :     100800 :              GetTxtFrm()->IsInTab() &&
    1106                 :       2820 :              GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT) )
    1107                 :            :         {
    1108                 :       2820 :             pPor = NewTabPortion( rInf, true );
    1109                 :            :         }
    1110                 :            : 
    1111                 :            :         // 11. suffix of meta-field
    1112         [ +  + ]:     108347 :         if (!pPor)
    1113                 :            :         {
    1114                 :     107943 :             pPor = TryNewNoLengthPortion(rInf);
    1115                 :            :         }
    1116                 :            : 
    1117                 :     109031 :     return pPor;
    1118                 :            : }
    1119                 :            : 
    1120                 :      41262 : sal_Bool lcl_OldFieldRest( const SwLineLayout* pCurr )
    1121                 :            : {
    1122         [ +  + ]:      41262 :     if( !pCurr->GetNext() )
    1123                 :       7446 :         return sal_False;
    1124                 :      33816 :     const SwLinePortion *pPor = pCurr->GetNext()->GetPortion();
    1125                 :      33816 :     sal_Bool bRet = sal_False;
    1126 [ +  + ][ +  - ]:      35756 :     while( pPor && !bRet )
                 [ +  + ]
    1127                 :            :     {
    1128                 :       1946 :         bRet = (pPor->InFldGrp() && ((SwFldPortion*)pPor)->IsFollow()) ||
    1129 [ -  + ][ #  # ]:       1946 :             (pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->IsFollowFld());
           [ -  +  #  # ]
    1130         [ +  + ]:       1946 :         if( !pPor->GetLen() )
    1131                 :          6 :             break;
    1132                 :       1940 :         pPor = pPor->GetPortion();
    1133                 :            :     }
    1134                 :      41262 :     return bRet;
    1135                 :            : }
    1136                 :            : 
    1137                 :            : /*************************************************************************
    1138                 :            :  *                      SwTxtFormatter::NewPortion()
    1139                 :            :  *************************************************************************/
    1140                 :            : 
    1141                 :            : /* NewPortion sets rInf.nLen
    1142                 :            :  * A SwTxtPortion is limited by a tab, break, txtatr or attr change
    1143                 :            :  * We can have three cases:
    1144                 :            :  * 1) The line is full and the wrap was not emulated
    1145                 :            :  *    -> return 0;
    1146                 :            :  * 2) The line is full and a wrap was emulated
    1147                 :            :  *    -> Reset width and return new FlyPortion
    1148                 :            :  * 3) We need to construct a new portion
    1149                 :            :  *    -> CalcFlyWidth emulates the width and return portion, if needed
    1150                 :            :  */
    1151                 :            : 
    1152                 :     109397 : SwLinePortion *SwTxtFormatter::NewPortion( SwTxtFormatInfo &rInf )
    1153                 :            : {
    1154                 :            :     // Underflow takes precedence
    1155                 :     109397 :     rInf.SetStopUnderFlow( sal_False );
    1156         [ -  + ]:     109397 :     if( rInf.GetUnderFlow() )
    1157                 :            :     {
    1158                 :            :         OSL_ENSURE( rInf.IsFull(), "SwTxtFormatter::NewPortion: underflow but not full" );
    1159                 :          0 :         return UnderFlow( rInf );
    1160                 :            :     }
    1161                 :            : 
    1162                 :            :     // If the line is full, flys and UnderFlow portions could be waiting ...
    1163         [ +  + ]:     109397 :     if( rInf.IsFull() )
    1164                 :            :     {
    1165                 :            :         // LineBreaks and Flys (bug05.sdw)
    1166                 :            :         // IsDummy()
    1167 [ +  + ][ +  + ]:      41628 :         if( rInf.IsNewLine() && (!rInf.GetFly() || !pCurr->IsDummy()) )
         [ -  + ][ +  + ]
    1168                 :        233 :             return 0;
    1169                 :            : 
    1170                 :            :         // Wenn der Text an den Fly gestossen ist, oder wenn
    1171                 :            :         // der Fly als erstes drankommt, weil er ueber dem linken
    1172                 :            :         // Rand haengt, wird GetFly() returnt.
    1173                 :            :         // Wenn IsFull() und kein GetFly() vorhanden ist, gibt's
    1174                 :            :         // naturgemaesz eine 0.
    1175         [ +  + ]:      41395 :         if( rInf.GetFly() )
    1176                 :            :         {
    1177         [ +  + ]:        133 :             if( rInf.GetLast()->IsBreakPortion() )
    1178                 :            :             {
    1179         [ +  - ]:         14 :                 delete rInf.GetFly();
    1180                 :         14 :                 rInf.SetFly( 0 );
    1181                 :            :             }
    1182                 :            : 
    1183                 :        133 :             return rInf.GetFly();
    1184                 :            :         }
    1185                 :            :         // Ein fieser Sonderfall: ein Rahmen ohne Umlauf kreuzt den
    1186                 :            :         // Ftn-Bereich. Wir muessen die Ftn-Portion als Zeilenrest
    1187                 :            :         // bekanntgeben, damit SwTxtFrm::Format nicht abbricht
    1188                 :            :         // (die Textmasse wurde ja durchformatiert).
    1189         [ -  + ]:      41262 :         if( rInf.GetRest() )
    1190                 :          0 :             rInf.SetNewLine( sal_True );
    1191                 :            :         else
    1192                 :            :         {
    1193                 :            :             // Wenn die naechste Zeile mit einem Rest eines Feldes beginnt,
    1194                 :            :             // jetzt aber kein Rest mehr anliegt,
    1195                 :            :             // muss sie auf jeden Fall neu formatiert werden!
    1196         [ -  + ]:      41262 :             if( lcl_OldFieldRest( GetCurr() ) )
    1197                 :          0 :                 rInf.SetNewLine( sal_True );
    1198                 :            :             else
    1199                 :            :             {
    1200                 :      41262 :                 SwLinePortion *pFirst = WhichFirstPortion( rInf );
    1201         [ -  + ]:      41262 :                 if( pFirst )
    1202                 :            :                 {
    1203                 :          0 :                     rInf.SetNewLine( sal_True );
    1204         [ #  # ]:          0 :                     if( pFirst->InNumberGrp() )
    1205                 :          0 :                         rInf.SetNumDone( sal_False) ;
    1206         [ #  # ]:          0 :                     delete pFirst;
    1207                 :            :                 }
    1208                 :            :             }
    1209                 :            :         }
    1210                 :            : 
    1211                 :      41262 :         return 0;
    1212                 :            :     }
    1213                 :            : 
    1214                 :      67769 :     SwLinePortion *pPor = WhichFirstPortion( rInf );
    1215                 :            : 
    1216                 :            :     // Check for Hidden Portion:
    1217         [ +  + ]:      67769 :     if ( !pPor )
    1218                 :            :     {
    1219                 :      66815 :         xub_StrLen nEnd = rInf.GetIdx();
    1220 [ -  + ][ +  - ]:      66815 :         if ( ::lcl_BuildHiddenPortion( rInf, nEnd ) )
    1221 [ #  # ][ #  # ]:      66815 :             pPor = new SwHiddenTextPortion( nEnd - rInf.GetIdx() );
    1222                 :            :     }
    1223                 :            : 
    1224         [ +  + ]:      67769 :     if( !pPor )
    1225                 :            :     {
    1226 [ +  + ][ -  +  :     132604 :         if( ( !pMulti || pMulti->IsBidi() ) &&
             +  +  -  + ]
                 [ +  + ]
    1227                 :            :             // #i42734#
    1228                 :            :             // No multi portion if there is a hook character waiting:
    1229                 :      65789 :             ( !rInf.GetRest() || '\0' == rInf.GetHookChar() ) )
    1230                 :            :         {
    1231                 :            :             // We open a multiportion part, if we enter a multi-line part
    1232                 :            :             // of the paragraph.
    1233                 :      65441 :             xub_StrLen nEnd = rInf.GetIdx();
    1234         [ +  - ]:      65441 :             SwMultiCreator* pCreate = rInf.GetMultiCreator( nEnd, pMulti );
    1235         [ +  + ]:      65441 :             if( pCreate )
    1236                 :            :             {
    1237                 :        356 :                 SwMultiPortion* pTmp = NULL;
    1238                 :            : 
    1239         [ -  + ]:        356 :                 if ( SW_MC_BIDI == pCreate->nId )
    1240 [ #  # ][ #  # ]:          0 :                     pTmp = new SwBidiPortion( nEnd, pCreate->nLevel );
    1241         [ +  + ]:        356 :                 else if ( SW_MC_RUBY == pCreate->nId )
    1242                 :            :                 {
    1243         [ +  - ]:        336 :                     Seek( rInf.GetIdx() );
    1244                 :            :                     sal_Bool bRubyTop;
    1245                 :        336 :                     sal_Bool* pRubyPos = 0;
    1246                 :            : 
    1247         [ +  - ]:        336 :                     if ( rInf.SnapToGrid() )
    1248                 :            :                     {
    1249 [ +  - ][ +  - ]:        336 :                         GETGRID( GetTxtFrm()->FindPageFrm() )
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
    1250         [ -  + ]:        336 :                         if ( pGrid )
    1251                 :            :                         {
    1252                 :          0 :                             bRubyTop = ! pGrid->GetRubyTextBelow();
    1253                 :          0 :                             pRubyPos = &bRubyTop;
    1254                 :            :                         }
    1255                 :            :                     }
    1256                 :            : 
    1257                 :        336 :                     pTmp = new SwRubyPortion( *pCreate, *rInf.GetFont(),
    1258                 :        336 :                                               *GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess(),
    1259 [ +  - ][ +  - ]:        672 :                                               nEnd, 0, pRubyPos );
                 [ +  - ]
    1260                 :            :                 }
    1261         [ -  + ]:         20 :                 else if( SW_MC_ROTATE == pCreate->nId )
    1262                 :            :                     pTmp = new SwRotatedPortion( *pCreate, nEnd,
    1263 [ #  # ][ #  # ]:          0 :                                                  GetTxtFrm()->IsRightToLeft() );
                 [ #  # ]
    1264                 :            :                 else
    1265 [ +  - ][ +  - ]:         20 :                     pTmp = new SwDoubleLinePortion( *pCreate, nEnd );
    1266                 :            : 
    1267                 :        356 :                 delete pCreate;
    1268         [ +  - ]:        356 :                 CalcFlyWidth( rInf );
    1269                 :            : 
    1270                 :      65441 :                 return pTmp;
    1271                 :            :             }
    1272                 :            :         }
    1273                 :            :         // 5010: Tabs und Felder
    1274                 :      66459 :         xub_Unicode cChar = rInf.GetHookChar();
    1275                 :            : 
    1276         [ +  + ]:      66459 :         if( cChar )
    1277                 :            :         {
    1278                 :            :             /* Wir holen uns nocheinmal cChar, um sicherzustellen, dass das
    1279                 :            :              * Tab jetzt wirklich ansteht und nicht auf die naechste Zeile
    1280                 :            :              * gewandert ist ( so geschehen hinter Rahmen ).
    1281                 :            :              * Wenn allerdings eine FldPortion im Rest wartet, muessen wir
    1282                 :            :              * das cChar natuerlich aus dem Feldinhalt holen, z.B. bei
    1283                 :            :              * DezimalTabs und Feldern (22615)
    1284                 :            :             */
    1285 [ +  + ][ -  + ]:        302 :             if( !rInf.GetRest() || !rInf.GetRest()->InFldGrp() )
                 [ +  + ]
    1286                 :        128 :                 cChar = rInf.GetChar( rInf.GetIdx() );
    1287                 :        302 :             rInf.ClearHookChar();
    1288                 :            :         }
    1289                 :            :         else
    1290                 :            :         {
    1291         [ +  + ]:      66157 :             if( rInf.GetIdx() >= rInf.GetTxt().Len() )
    1292                 :            :             {
    1293                 :      12275 :                 rInf.SetFull(sal_True);
    1294                 :      12275 :                 CalcFlyWidth( rInf );
    1295                 :      12275 :                 return pPor;
    1296                 :            :             }
    1297                 :      53882 :             cChar = rInf.GetChar( rInf.GetIdx() );
    1298                 :            :         }
    1299                 :            : 
    1300   [ +  +  +  +  :      54184 :         switch( cChar )
             +  -  +  + ]
    1301                 :            :         {
    1302                 :            :             case CH_TAB:
    1303                 :        207 :                 pPor = NewTabPortion( rInf, false ); break;
    1304                 :            : 
    1305                 :            :             case CH_BREAK:
    1306         [ +  - ]:        271 :                 pPor = new SwBreakPortion( *rInf.GetLast() ); break;
    1307                 :            : 
    1308                 :            :             case CHAR_SOFTHYPHEN:                   // soft hyphen
    1309         [ +  - ]:          6 :                 pPor = new SwSoftHyphPortion; break;
    1310                 :            : 
    1311                 :            :             case CHAR_HARDBLANK:                    // no-break space
    1312         [ +  - ]:          6 :                 pPor = new SwBlankPortion( ' ' ); break;
    1313                 :            : 
    1314                 :            :             case CHAR_HARDHYPHEN:               // non-breaking hyphen
    1315         [ +  - ]:         12 :                 pPor = new SwBlankPortion( '-' ); break;
    1316                 :            : 
    1317                 :            :             case CHAR_ZWSP:                     // zero width space
    1318                 :            :             case CHAR_ZWNBSP :                  // word joiner
    1319                 :            : //            case CHAR_RLM :                     // right to left mark
    1320                 :            : //            case CHAR_LRM :                     // left to right mark
    1321         [ #  # ]:          0 :                 pPor = new SwControlCharPortion( cChar ); break;
    1322                 :            : 
    1323                 :            :             case CH_TXTATR_BREAKWORD:
    1324                 :            :             case CH_TXTATR_INWORD:
    1325         [ +  - ]:       2411 :                             if( rInf.HasHint( rInf.GetIdx() ) )
    1326                 :            :                             {
    1327                 :       2411 :                                 pPor = NewExtraPortion( rInf );
    1328                 :       2411 :                                 break;
    1329                 :            :                             }
    1330                 :            :                             // No break
    1331                 :            :             default        :
    1332                 :            :             {
    1333                 :      51271 :                 SwTabPortion* pLastTabPortion = rInf.GetLastTab();
    1334 [ -  + ][ -  + ]:      51271 :                 if ( pLastTabPortion && cChar == rInf.GetTabDecimal() )
                 [ +  + ]
    1335                 :            :                 {
    1336                 :            :                     // #127428# Abandon dec. tab position if line is full
    1337                 :            :                     // We have a decimal tab portion in the line and the next character has to be
    1338                 :            :                     // aligned at the tab stop position. We store the width from the beginning of
    1339                 :            :                     // the tab stop portion up to the portion containint the decimal separator:
    1340   [ #  #  #  # ]:          0 :                   if ( GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT) /*rInf.GetVsh()->IsTabCompat();*/ &&
                 [ #  # ]
    1341                 :          0 :                          POR_TABDECIMAL == pLastTabPortion->GetWhichPor() )
    1342                 :            :                     {
    1343                 :            :                         OSL_ENSURE( rInf.X() >= pLastTabPortion->Fix(), "Decimal tab stop position cannot be calculated" );
    1344                 :          0 :                         const sal_uInt16 nWidthOfPortionsUpToDecimalPosition = (sal_uInt16)(rInf.X() - pLastTabPortion->Fix() );
    1345                 :          0 :                         static_cast<SwTabDecimalPortion*>(pLastTabPortion)->SetWidthOfPortionsUpToDecimalPosition( nWidthOfPortionsUpToDecimalPosition );
    1346                 :          0 :                         rInf.SetTabDecimal( 0 );
    1347                 :            :                     }
    1348                 :            :                     else
    1349                 :          0 :                         rInf.SetFull( rInf.GetLastTab()->Format( rInf ) );
    1350                 :            :                 }
    1351                 :            : 
    1352         [ -  + ]:      51271 :                 if( rInf.GetRest() )
    1353                 :            :                 {
    1354         [ #  # ]:          0 :                     if( rInf.IsFull() )
    1355                 :            :                     {
    1356                 :          0 :                         rInf.SetNewLine(sal_True);
    1357                 :          0 :                         return 0;
    1358                 :            :                     }
    1359                 :          0 :                     pPor = rInf.GetRest();
    1360                 :          0 :                     rInf.SetRest(0);
    1361                 :            :                 }
    1362                 :            :                 else
    1363                 :            :                 {
    1364         [ -  + ]:      51271 :                     if( rInf.IsFull() )
    1365                 :          0 :                         return 0;
    1366                 :      51271 :                     pPor = NewTxtPortion( rInf );
    1367                 :            :                 }
    1368                 :      51271 :                 break;
    1369                 :            :             }
    1370                 :            :         }
    1371                 :            : 
    1372                 :            :         // if a portion is created despite there being a pending RestPortion,
    1373                 :            :         // then it is a field which has been split (e.g. because it contains a Tab)
    1374 [ +  - ][ +  + ]:      54184 :         if( pPor && rInf.GetRest() )
                 [ +  + ]
    1375                 :        174 :             pPor->SetLen( 0 );
    1376                 :            : 
    1377                 :            :         // robust:
    1378 [ +  - ][ -  + ]:      54184 :         if( !pPor || rInf.IsStop() )
                 [ -  + ]
    1379                 :            :         {
    1380         [ #  # ]:          0 :             delete pPor;
    1381                 :          0 :             return 0;
    1382                 :            :         }
    1383                 :            :     }
    1384                 :            : 
    1385                 :            :     // Special portions containing numbers (footnote anchor, footnote number,
    1386                 :            :     // numbering) can be contained in a rotated portion, if the user
    1387                 :            :     // choose a rotated character attribute.
    1388 [ +  - ][ +  + ]:      55138 :     if ( pPor && ! pMulti )
    1389                 :            :     {
    1390         [ +  + ]:      54032 :         if ( pPor->IsFtnPortion() )
    1391                 :            :         {
    1392                 :        132 :             const SwTxtFtn* pTxtFtn = ((SwFtnPortion*)pPor)->GetTxtFtn();
    1393                 :            : 
    1394         [ +  - ]:        132 :             if ( pTxtFtn )
    1395                 :            :             {
    1396                 :        132 :                 SwFmtFtn& rFtn = (SwFmtFtn&)pTxtFtn->GetFtn();
    1397                 :        132 :                 const SwDoc *pDoc = rInf.GetTxtFrm()->GetNode()->GetDoc();
    1398                 :            :                 const SwEndNoteInfo* pInfo;
    1399         [ +  + ]:        132 :                 if( rFtn.IsEndNote() )
    1400                 :         33 :                     pInfo = &pDoc->GetEndNoteInfo();
    1401                 :            :                 else
    1402                 :         99 :                     pInfo = &pDoc->GetFtnInfo();
    1403         [ +  - ]:        132 :                 const SwAttrSet& rSet = pInfo->GetAnchorCharFmt((SwDoc&)*pDoc)->GetAttrSet();
    1404                 :            : 
    1405                 :            :                 const SfxPoolItem* pItem;
    1406                 :        132 :                 sal_uInt16 nDir = 0;
    1407         [ -  + ]:        132 :                 if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_ROTATE,
    1408         [ +  - ]:        132 :                     sal_True, &pItem ))
    1409                 :          0 :                     nDir = ((SvxCharRotateItem*)pItem)->GetValue();
    1410                 :            : 
    1411         [ -  + ]:        132 :                 if ( 0 != nDir )
    1412                 :            :                 {
    1413 [ #  # ][ #  # ]:          0 :                     delete pPor;
    1414                 :          0 :                     pPor = new SwRotatedPortion( rInf.GetIdx() + 1, 900 == nDir ?
    1415                 :            :                                                     DIR_BOTTOM2TOP :
    1416 [ #  # ][ #  # ]:        132 :                                                     DIR_TOP2BOTTOM );
                 [ #  # ]
    1417                 :            :                 }
    1418                 :            :             }
    1419                 :            :         }
    1420         [ +  + ]:      53900 :         else if ( pPor->InNumberGrp() )
    1421                 :            :         {
    1422                 :        536 :             const SwFont* pNumFnt = ((SwFldPortion*)pPor)->GetFont();
    1423                 :            : 
    1424         [ +  - ]:        536 :             if ( pNumFnt )
    1425                 :            :             {
    1426                 :        536 :                 sal_uInt16 nDir = pNumFnt->GetOrientation( rInf.GetTxtFrm()->IsVertical() );
    1427         [ -  + ]:        536 :                 if ( 0 != nDir )
    1428                 :            :                 {
    1429         [ #  # ]:          0 :                     delete pPor;
    1430                 :            :                     pPor = new SwRotatedPortion( 0, 900 == nDir ?
    1431                 :            :                                                     DIR_BOTTOM2TOP :
    1432 [ #  # ][ #  # ]:          0 :                                                     DIR_TOP2BOTTOM );
    1433                 :            : 
    1434                 :          0 :                     rInf.SetNumDone( sal_False );
    1435                 :          0 :                     rInf.SetFtnDone( sal_False );
    1436                 :            :                 }
    1437                 :            :             }
    1438                 :            :         }
    1439                 :            :     }
    1440                 :            : 
    1441                 :            :     // Der Font wird im Outputdevice eingestellt,
    1442                 :            :     // der Ascent und die Hoehe werden berechnet.
    1443 [ +  + ][ +  + ]:      55138 :     if( !pPor->GetAscent() && !pPor->Height() )
                 [ +  + ]
    1444                 :       2264 :         CalcAscent( rInf, pPor );
    1445                 :      55138 :     rInf.SetLen( pPor->GetLen() );
    1446                 :            : 
    1447                 :            :     // In CalcFlyWidth wird Width() verkuerzt, wenn eine FlyPortion vorliegt.
    1448                 :      55138 :     CalcFlyWidth( rInf );
    1449                 :            : 
    1450                 :            :     // Man darf nicht vergessen, dass pCurr als GetLast() vernuenftige
    1451                 :            :     // Werte bereithalten muss:
    1452         [ -  + ]:      55138 :     if( !pCurr->Height() )
    1453                 :            :     {
    1454                 :            :         OSL_ENSURE( pCurr->Height(), "SwTxtFormatter::NewPortion: limbo dance" );
    1455                 :          0 :         pCurr->Height( pPor->Height() );
    1456                 :          0 :         pCurr->SetAscent( pPor->GetAscent() );
    1457                 :            :     }
    1458                 :            : 
    1459                 :            :     OSL_ENSURE( !pPor || pPor->Height(),
    1460                 :            :             "SwTxtFormatter::NewPortion: something went wrong");
    1461 [ +  + ][ -  + ]:      55138 :     if( pPor->IsPostItsPortion() && rInf.X() >= rInf.Width() && rInf.GetFly() )
         [ #  # ][ -  + ]
    1462                 :            :     {
    1463         [ #  # ]:          0 :         delete pPor;
    1464                 :          0 :         pPor = rInf.GetFly();
    1465                 :            :     }
    1466                 :     109397 :     return pPor;
    1467                 :            : }
    1468                 :            : 
    1469                 :            : /*************************************************************************
    1470                 :            :  *                      SwTxtFormatter::FormatLine()
    1471                 :            :  *************************************************************************/
    1472                 :            : 
    1473                 :      52762 : xub_StrLen SwTxtFormatter::FormatLine( const xub_StrLen nStartPos )
    1474                 :            : {
    1475                 :            :     OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
    1476                 :            :             "SwTxtFormatter::FormatLine( nStartPos ) with unswapped frame" );
    1477                 :            : 
    1478                 :            :     // For the formatting routines, we set pOut to the reference device.
    1479         [ +  - ]:      52762 :     SwHookOut aHook( GetInfo() );
    1480         [ +  + ]:      52762 :     if( GetInfo().GetLen() < GetInfo().GetTxt().Len() )
    1481                 :      37778 :         GetInfo().SetLen( GetInfo().GetTxt().Len() );
    1482                 :            : 
    1483                 :      52762 :     sal_Bool bBuild = sal_True;
    1484                 :      52762 :     SetFlyInCntBase( sal_False );
    1485                 :      52762 :     GetInfo().SetLineHeight( 0 );
    1486                 :      52762 :     GetInfo().SetLineNettoHeight( 0 );
    1487                 :            : 
    1488                 :            :     // Recycling muss bei geaenderter Zeilenhoehe unterdrueckt werden
    1489                 :            :     // und auch bei geaendertem Ascent (Absenken der Grundlinie).
    1490                 :      52762 :     const KSHORT nOldHeight = pCurr->Height();
    1491                 :      52762 :     const KSHORT nOldAscent = pCurr->GetAscent();
    1492                 :            : 
    1493                 :      52762 :     pCurr->SetEndHyph( sal_False );
    1494                 :      52762 :     pCurr->SetMidHyph( sal_False );
    1495                 :            : 
    1496                 :            :     // fly positioning can make it necessary format a line several times
    1497                 :            :     // for this, we have to keep a copy of our rest portion
    1498                 :      52762 :     SwLinePortion* pFld = GetInfo().GetRest();
    1499                 :      52762 :     SwFldPortion* pSaveFld = 0;
    1500                 :            : 
    1501 [ #  # ][ #  # ]:      52762 :     if ( pFld && pFld->InFldGrp() && !pFld->IsFtnPortion() )
         [ -  + ][ -  + ]
    1502 [ #  # ][ #  # ]:          0 :         pSaveFld = new SwFldPortion( *((SwFldPortion*)pFld) );
    1503                 :            : 
    1504                 :            :     // for an optimal repaint rectangle, we want to compare fly portions
    1505                 :            :     // before and after the BuildPortions call
    1506         [ +  - ]:      52762 :     const sal_Bool bOptimizeRepaint = AllowRepaintOpt();
    1507                 :      52762 :     const xub_StrLen nOldLineEnd = nStartPos + pCurr->GetLen();
    1508         [ +  - ]:      52762 :     std::vector<long> flyStarts;
    1509                 :            : 
    1510                 :            :     // these are the conditions for a fly position comparison
    1511 [ +  + ][ -  + ]:      52762 :     if ( bOptimizeRepaint && pCurr->IsFly() )
                 [ -  + ]
    1512                 :            :     {
    1513                 :          0 :         SwLinePortion* pPor = pCurr->GetFirstPortion();
    1514                 :          0 :         long nPOfst = 0;
    1515         [ #  # ]:          0 :         while ( pPor )
    1516                 :            :         {
    1517         [ #  # ]:          0 :             if ( pPor->IsFlyPortion() )
    1518                 :            :                 // insert start value of fly portion
    1519         [ #  # ]:          0 :                 flyStarts.push_back( nPOfst );
    1520                 :            : 
    1521                 :          0 :             nPOfst += pPor->Width();
    1522                 :          0 :             pPor = pPor->GetPortion();
    1523                 :            :         }
    1524                 :            :     }
    1525                 :            : 
    1526                 :            :     // Hier folgt bald die Unterlaufpruefung.
    1527         [ +  + ]:     105524 :     while( bBuild )
    1528                 :            :     {
    1529                 :      52762 :         GetInfo().SetFtnInside( sal_False );
    1530                 :      52762 :         GetInfo().SetOtherThanFtnInside( sal_False );
    1531                 :            : 
    1532                 :            :         // These values must not be reset by FormatReset();
    1533                 :      52762 :         sal_Bool bOldNumDone = GetInfo().IsNumDone();
    1534                 :      52762 :         sal_Bool bOldArrowDone = GetInfo().IsArrowDone();
    1535                 :      52762 :         sal_Bool bOldErgoDone = GetInfo().IsErgoDone();
    1536                 :            : 
    1537                 :            :         // besides other things, this sets the repaint offset to 0
    1538         [ +  - ]:      52762 :         FormatReset( GetInfo() );
    1539                 :            : 
    1540                 :      52762 :         GetInfo().SetNumDone( bOldNumDone );
    1541                 :      52762 :         GetInfo().SetArrowDone( bOldArrowDone );
    1542                 :      52762 :         GetInfo().SetErgoDone( bOldErgoDone );
    1543                 :            : 
    1544                 :            :         // build new portions for this line
    1545         [ +  - ]:      52762 :         BuildPortions( GetInfo() );
    1546                 :            : 
    1547         [ -  + ]:      52762 :         if( GetInfo().IsStop() )
    1548                 :            :         {
    1549                 :          0 :             pCurr->SetLen( 0 );
    1550         [ #  # ]:          0 :             pCurr->Height( GetFrmRstHeight() + 1 );
    1551         [ #  # ]:          0 :             pCurr->SetRealHeight( GetFrmRstHeight() + 1 );
    1552                 :          0 :             pCurr->Width(0);
    1553         [ #  # ]:          0 :             pCurr->Truncate();
    1554                 :          0 :             return nStartPos;
    1555                 :            :         }
    1556         [ -  + ]:      52762 :         else if( GetInfo().IsDropInit() )
    1557                 :            :         {
    1558         [ #  # ]:          0 :             DropInit();
    1559                 :          0 :             GetInfo().SetDropInit( sal_False );
    1560                 :            :         }
    1561                 :            : 
    1562         [ +  - ]:      52762 :         pCurr->CalcLine( *this, GetInfo() );
    1563         [ +  - ]:      52762 :         CalcRealHeight( GetInfo().IsNewLine() );
    1564                 :            : 
    1565 [ +  + ][ +  - ]:      52762 :         if ( IsFlyInCntBase() && !IsQuick() )
         [ +  - ][ +  + ]
    1566                 :            :         {
    1567                 :            :             KSHORT nTmpAscent, nTmpHeight;
    1568         [ +  - ]:        939 :             CalcAscentAndHeight( nTmpAscent, nTmpHeight );
    1569         [ +  - ]:        939 :             AlignFlyInCntBase( Y() + long( nTmpAscent ) );
    1570         [ +  - ]:        939 :             pCurr->CalcLine( *this, GetInfo() );
    1571         [ +  - ]:        939 :             CalcRealHeight();
    1572                 :            :         }
    1573                 :            : 
    1574                 :            :         // bBuild entscheidet, ob noch eine Ehrenrunde gedreht wird
    1575         [ -  + ]:      52762 :         if ( pCurr->GetRealHeight() <= GetInfo().GetLineHeight() )
    1576                 :            :         {
    1577                 :          0 :             pCurr->SetRealHeight( GetInfo().GetLineHeight() );
    1578                 :          0 :             bBuild = sal_False;
    1579                 :            :         }
    1580                 :            :         else
    1581                 :            :         {
    1582         [ +  - ]:      53378 :             bBuild = ( GetInfo().GetTxtFly()->IsOn() && ChkFlyUnderflow(GetInfo()) )
    1583 [ +  - ][ +  - ]:      53378 :                      || GetInfo().CheckFtnPortion(pCurr);
         [ -  + ][ +  + ]
    1584         [ -  + ]:      52762 :             if( bBuild )
    1585                 :            :             {
    1586                 :          0 :                 GetInfo().SetNumDone( bOldNumDone );
    1587                 :          0 :                 GetInfo().ResetMaxWidthDiff();
    1588                 :            : 
    1589                 :            :                 // delete old rest
    1590         [ #  # ]:          0 :                 if ( GetInfo().GetRest() )
    1591                 :            :                 {
    1592 [ #  # ][ #  # ]:          0 :                     delete GetInfo().GetRest();
    1593                 :          0 :                     GetInfo().SetRest( 0 );
    1594                 :            :                 }
    1595                 :            : 
    1596                 :            :                 // set original rest portion
    1597         [ #  # ]:          0 :                 if ( pSaveFld )
    1598 [ #  # ][ #  # ]:          0 :                     GetInfo().SetRest( new SwFldPortion( *pSaveFld ) );
    1599                 :            : 
    1600                 :          0 :                 pCurr->SetLen( 0 );
    1601                 :          0 :                 pCurr->Width(0);
    1602         [ #  # ]:          0 :                 pCurr->Truncate();
    1603                 :            :             }
    1604                 :            :         }
    1605                 :            :     }
    1606                 :            : 
    1607                 :            :     // calculate optimal repaint rectangle
    1608         [ +  + ]:      52762 :     if ( bOptimizeRepaint )
    1609                 :            :     {
    1610         [ +  - ]:       3304 :         GetInfo().SetPaintOfst( ::lcl_CalcOptRepaint( *this, *pCurr, nOldLineEnd, flyStarts ) );
    1611                 :       3304 :         flyStarts.clear();
    1612                 :            :     }
    1613                 :            :     else
    1614                 :            :         // Special case: We do not allow an optimitation of the repaint
    1615                 :            :         // area, but during formatting the repaint offset is set to indicate
    1616                 :            :         // a maximum value for the offset. This value has to be reset:
    1617                 :      49458 :         GetInfo().SetPaintOfst( 0 );
    1618                 :            : 
    1619                 :            :     // This corrects the start of the reformat range if something has
    1620                 :            :     // moved to the next line. Otherwise IsFirstReformat in AllowRepaintOpt
    1621                 :            :     // will give us a wrong result if we have to reformat another line
    1622                 :      52762 :     GetInfo().GetParaPortion()->GetReformat()->LeftMove( GetInfo().GetIdx() );
    1623                 :            : 
    1624                 :            :     // delete master copy of rest portion
    1625 [ #  # ][ -  + ]:      52762 :     delete pSaveFld;
    1626                 :            : 
    1627                 :      52762 :     xub_StrLen nNewStart = nStartPos + pCurr->GetLen();
    1628                 :            : 
    1629                 :            :     // adjust text if kana compression is enabled
    1630         [ -  + ]:      52762 :     if ( GetInfo().CompressLine() )
    1631                 :            :     {
    1632         [ #  # ]:          0 :         SwTwips nRepaintOfst = CalcKanaAdj( pCurr );
    1633                 :            : 
    1634                 :            :         // adjust repaint offset
    1635         [ #  # ]:          0 :         if ( nRepaintOfst < GetInfo().GetPaintOfst() )
    1636                 :          0 :             GetInfo().SetPaintOfst( nRepaintOfst );
    1637                 :            :     }
    1638                 :            : 
    1639         [ +  - ]:      52762 :     CalcAdjustLine( pCurr );
    1640                 :            : 
    1641 [ +  + ][ +  + ]:      52762 :     if( nOldHeight != pCurr->Height() || nOldAscent != pCurr->GetAscent() )
                 [ +  + ]
    1642                 :            :     {
    1643                 :      12049 :         SetFlyInCntBase();
    1644                 :      12049 :         GetInfo().SetPaintOfst( 0 ); //geaenderte Zeilenhoehe => kein Recycling
    1645                 :            :         // alle weiteren Zeilen muessen gepaintet und, wenn Flys im Spiel sind
    1646                 :            :         // auch formatiert werden.
    1647                 :      12049 :         GetInfo().SetShift( sal_True );
    1648                 :            :     }
    1649                 :            : 
    1650 [ +  + ][ +  - ]:      52762 :     if ( IsFlyInCntBase() && !IsQuick() )
         [ +  + ][ +  + ]
    1651 [ +  - ][ +  - ]:      12078 :         UpdatePos( pCurr, GetTopLeft(), GetStart() );
    1652                 :            : 
    1653         [ +  - ]:      52762 :     return nNewStart;
    1654                 :            : }
    1655                 :            : 
    1656                 :            : /*************************************************************************
    1657                 :            :  *                      SwTxtFormatter::RecalcRealHeight()
    1658                 :            :  *************************************************************************/
    1659                 :            : 
    1660                 :          0 : void SwTxtFormatter::RecalcRealHeight()
    1661                 :            : {
    1662                 :          0 :     sal_Bool bMore = sal_True;
    1663         [ #  # ]:          0 :     while(bMore)
    1664                 :            :     {
    1665                 :          0 :         CalcRealHeight();
    1666                 :          0 :         bMore = Next() != 0;
    1667                 :            :     }
    1668                 :          0 : }
    1669                 :            : 
    1670                 :            : /*************************************************************************
    1671                 :            :  *                    SwTxtFormatter::CalcRealHeight()
    1672                 :            :  *************************************************************************/
    1673                 :            : 
    1674                 :      54963 : void SwTxtFormatter::CalcRealHeight( sal_Bool bNewLine )
    1675                 :            : {
    1676                 :      54963 :     KSHORT nLineHeight = pCurr->Height();
    1677                 :      54963 :     pCurr->SetClipping( sal_False );
    1678                 :            : 
    1679 [ -  + ][ #  # ]:      54963 :     GETGRID( pFrm->FindPageFrm() )
         [ -  + ][ +  - ]
    1680 [ -  + ][ #  # ]:      54963 :     if ( pGrid && GetInfo().SnapToGrid() )
                 [ -  + ]
    1681                 :            :     {
    1682                 :          0 :         const sal_uInt16 nGridWidth = pGrid->GetBaseHeight();
    1683                 :          0 :         const sal_uInt16 nRubyHeight = pGrid->GetRubyHeight();
    1684                 :          0 :         const sal_Bool bRubyTop = ! pGrid->GetRubyTextBelow();
    1685                 :            : 
    1686                 :          0 :         nLineHeight = nGridWidth + nRubyHeight;
    1687                 :          0 :         sal_uInt16 nLineDist = nLineHeight;
    1688                 :            : 
    1689         [ #  # ]:          0 :         while ( pCurr->Height() > nLineHeight )
    1690                 :          0 :             nLineHeight = nLineHeight + nLineDist;
    1691                 :            : 
    1692                 :          0 :         KSHORT nAsc = pCurr->GetAscent() +
    1693                 :            :                       ( bRubyTop ?
    1694                 :          0 :                        ( nLineHeight - pCurr->Height() + nRubyHeight ) / 2 :
    1695         [ #  # ]:          0 :                        ( nLineHeight - pCurr->Height() - nRubyHeight ) / 2 );
    1696                 :            : 
    1697                 :          0 :         pCurr->Height( nLineHeight );
    1698                 :          0 :         pCurr->SetAscent( nAsc );
    1699                 :          0 :         pInf->GetParaPortion()->SetFixLineHeight();
    1700                 :            : 
    1701                 :            :         // we ignore any line spacing options except from ...
    1702                 :          0 :         const SvxLineSpacingItem* pSpace = aLineInf.GetLineSpacing();
    1703   [ #  #  #  # ]:          0 :         if ( ! IsParaLine() && pSpace &&
         [ #  # ][ #  # ]
    1704                 :          0 :              SVX_INTER_LINE_SPACE_PROP == pSpace->GetInterLineSpaceRule() )
    1705                 :            :         {
    1706                 :          0 :             sal_uLong nTmp = pSpace->GetPropLineSpace();
    1707                 :            : 
    1708         [ #  # ]:          0 :             if( nTmp < 100 )
    1709                 :          0 :                 nTmp = 100;
    1710                 :            : 
    1711                 :          0 :             nTmp *= nLineHeight;
    1712                 :          0 :             nLineHeight = (sal_uInt16)(nTmp / 100);
    1713                 :            :         }
    1714                 :            : 
    1715                 :          0 :         pCurr->SetRealHeight( nLineHeight );
    1716                 :      54963 :         return;
    1717                 :            :     }
    1718                 :            : 
    1719                 :            :     // Das Dummyflag besitzen Zeilen, die nur Flyportions enthalten, diese
    1720                 :            :     // sollten kein Register etc. beachten. Dummerweise hat kann es eine leere
    1721                 :            :     // Zeile am Absatzende geben (bei leeren Abs?tzen oder nach einem
    1722                 :            :     // Shift-Return), die das Register durchaus beachten soll.
    1723         [ +  + ]:      56822 :     if( !pCurr->IsDummy() || ( !pCurr->GetNext() &&
           [ +  +  +  + ]
         [ +  + ][ +  + ]
    1724                 :       1859 :         GetStart() >= GetTxtFrm()->GetTxt().Len() && !bNewLine ) )
    1725                 :            :     {
    1726                 :      54918 :         const SvxLineSpacingItem *pSpace = aLineInf.GetLineSpacing();
    1727         [ +  - ]:      54918 :         if( pSpace )
    1728                 :            :         {
    1729   [ +  +  -  - ]:      54918 :             switch( pSpace->GetLineSpaceRule() )
    1730                 :            :             {
    1731                 :            :                 case SVX_LINE_SPACE_AUTO:
    1732         [ +  + ]:      54906 :             if (pSpace->GetInterLineSpaceRule()==SVX_INTER_LINE_SPACE_PROP) {
    1733                 :        543 :                         long nTmp = pSpace->GetPropLineSpace();
    1734         [ -  + ]:        543 :                         if (nTmp<100) { // code adaped from fixed line height
    1735                 :          0 :                             nTmp *= nLineHeight;
    1736                 :          0 :                             nTmp /= 100;
    1737         [ #  # ]:          0 :                             if( !nTmp )
    1738                 :          0 :                                 ++nTmp;
    1739                 :          0 :                             nLineHeight = (KSHORT)nTmp;
    1740                 :            : /*
    1741                 :            :                             //@TODO figure out how WW maps ascent and descent
    1742                 :            :                             //in case of prop  line spacing <100%
    1743                 :            :                             KSHORT nAsc = ( 4 * nLineHeight ) / 5;  // 80%
    1744                 :            :                             if( nAsc < pCurr->GetAscent() ||
    1745                 :            :                                 nLineHeight - nAsc < pCurr->Height() -
    1746                 :            : pCurr->GetAscent() )
    1747                 :            :                                 pCurr->SetClipping( sal_True );
    1748                 :            :                             pCurr->SetAscent( nAsc );
    1749                 :            : */
    1750                 :          0 :                             pCurr->Height( nLineHeight );
    1751                 :          0 :                             pInf->GetParaPortion()->SetFixLineHeight();
    1752                 :            :                         }
    1753                 :            :                     }
    1754                 :      54906 :                 break;
    1755                 :            :                 case SVX_LINE_SPACE_MIN:
    1756                 :            :                 {
    1757         [ -  + ]:         12 :                     if( nLineHeight < KSHORT( pSpace->GetLineHeight() ) )
    1758                 :          0 :                         nLineHeight = pSpace->GetLineHeight();
    1759                 :         12 :                     break;
    1760                 :            :                 }
    1761                 :            :                 case SVX_LINE_SPACE_FIX:
    1762                 :            :                 {
    1763                 :          0 :                     nLineHeight = pSpace->GetLineHeight();
    1764                 :          0 :                     KSHORT nAsc = ( 4 * nLineHeight ) / 5;  // 80%
    1765         [ #  # ]:          0 :                     if( nAsc < pCurr->GetAscent() ||
           [ #  #  #  # ]
    1766                 :          0 :                         nLineHeight - nAsc < pCurr->Height() - pCurr->GetAscent() )
    1767                 :          0 :                         pCurr->SetClipping( sal_True );
    1768                 :          0 :                     pCurr->Height( nLineHeight );
    1769                 :          0 :                     pCurr->SetAscent( nAsc );
    1770                 :          0 :                     pInf->GetParaPortion()->SetFixLineHeight();
    1771                 :            :                 }
    1772                 :          0 :                 break;
    1773                 :            :                 default: OSL_FAIL( ": unknown LineSpaceRule" );
    1774                 :            :             }
    1775         [ +  + ]:      54918 :             if( !IsParaLine() )
    1776   [ +  +  -  - ]:      41676 :                 switch( pSpace->GetInterLineSpaceRule() )
    1777                 :            :                 {
    1778                 :            :                     case SVX_INTER_LINE_SPACE_OFF:
    1779                 :      41562 :                     break;
    1780                 :            :                     case SVX_INTER_LINE_SPACE_PROP:
    1781                 :            :                     {
    1782                 :        114 :                         long nTmp = pSpace->GetPropLineSpace();
    1783                 :            :                         // 50% ist das Minimum, bei 0% schalten wir auf
    1784                 :            :                         // den Defaultwert 100% um ...
    1785         [ -  + ]:        114 :                         if( nTmp < 50 )
    1786         [ #  # ]:          0 :                             nTmp = nTmp ? 50 : 100;
    1787                 :            : 
    1788                 :        114 :                         nTmp *= nLineHeight;
    1789                 :        114 :                         nTmp /= 100;
    1790         [ -  + ]:        114 :                         if( !nTmp )
    1791                 :          0 :                             ++nTmp;
    1792                 :        114 :                         nLineHeight = (KSHORT)nTmp;
    1793                 :        114 :                         break;
    1794                 :            :                     }
    1795                 :            :                     case SVX_INTER_LINE_SPACE_FIX:
    1796                 :            :                     {
    1797                 :          0 :                         nLineHeight = nLineHeight + pSpace->GetInterLineSpace();
    1798                 :      41676 :                         break;
    1799                 :            :                     }
    1800                 :            :                     default: OSL_FAIL( ": unknown InterLineSpaceRule" );
    1801                 :            :                 }
    1802                 :            :         }
    1803                 :            : #if OSL_DEBUG_LEVEL > 1
    1804                 :            :         KSHORT nDummy = nLineHeight + 1;
    1805                 :            :         (void)nDummy;
    1806                 :            : #endif
    1807                 :            : 
    1808         [ -  + ]:      54918 :         if( IsRegisterOn() )
    1809                 :            :         {
    1810                 :          0 :             SwTwips nTmpY = Y() + pCurr->GetAscent() + nLineHeight - pCurr->Height();
    1811 [ #  # ][ #  # ]:          0 :             SWRECTFN( pFrm )
         [ #  # ][ #  # ]
    1812         [ #  # ]:          0 :             if ( bVert )
    1813                 :          0 :                 nTmpY = pFrm->SwitchHorizontalToVertical( nTmpY );
    1814                 :          0 :             nTmpY = (*fnRect->fnYDiff)( nTmpY, RegStart() );
    1815                 :          0 :             KSHORT nDiff = KSHORT( nTmpY % RegDiff() );
    1816         [ #  # ]:          0 :             if( nDiff )
    1817                 :          0 :                 nLineHeight += RegDiff() - nDiff;
    1818                 :            :         }
    1819                 :            :     }
    1820                 :      54963 :     pCurr->SetRealHeight( nLineHeight );
    1821                 :            : }
    1822                 :            : 
    1823                 :            : /*************************************************************************
    1824                 :            :  *                      SwTxtFormatter::FeedInf()
    1825                 :            :  *************************************************************************/
    1826                 :            : 
    1827                 :      53368 : void SwTxtFormatter::FeedInf( SwTxtFormatInfo &rInf ) const
    1828                 :            : {
    1829                 :            :     // 3260, 3860: Fly auf jeden Fall loeschen!
    1830                 :      53368 :     ClearFly( rInf );
    1831                 :      53368 :     rInf.Init();
    1832                 :            : 
    1833                 :      53368 :     rInf.ChkNoHyph( CntEndHyph(), CntMidHyph() );
    1834                 :      53368 :     rInf.SetRoot( pCurr );
    1835                 :      53368 :     rInf.SetLineStart( nStart );
    1836                 :      53368 :     rInf.SetIdx( nStart );
    1837                 :            : 
    1838                 :            :     // Handle overflows:
    1839                 :            :     // #i34348# Changed type from sal_uInt16 to SwTwips
    1840                 :      53368 :     SwTwips nTmpLeft = Left();
    1841                 :      53368 :     SwTwips nTmpRight = Right();
    1842                 :      53368 :     SwTwips nTmpFirst = FirstLeft();
    1843                 :            : 
    1844 [ +  + ][ -  + ]:      53368 :     if ( nTmpLeft > USHRT_MAX ||
                 [ +  - ]
    1845                 :            :          nTmpRight > USHRT_MAX ||
    1846                 :            :          nTmpFirst > USHRT_MAX )
    1847                 :            :     {
    1848 [ -  + ][ #  # ]:          1 :         SWRECTFN( rInf.GetTxtFrm() )
         [ #  # ][ -  + ]
    1849         [ +  - ]:          1 :         nTmpLeft = (rInf.GetTxtFrm()->Frm().*fnRect->fnGetLeft)();
    1850         [ +  - ]:          1 :         nTmpRight = (rInf.GetTxtFrm()->Frm().*fnRect->fnGetRight)();
    1851                 :          1 :         nTmpFirst = nTmpLeft;
    1852                 :            :     }
    1853                 :            : 
    1854                 :      53368 :     rInf.Left(  nTmpLeft  );
    1855                 :      53368 :     rInf.Right( nTmpRight );
    1856                 :      53368 :     rInf.First( nTmpFirst );
    1857                 :            : 
    1858                 :      53368 :     rInf.RealWidth( KSHORT(rInf.Right()) - KSHORT(GetLeftMargin()) );
    1859                 :      53368 :     rInf.Width( rInf.RealWidth() );
    1860         [ -  + ]:      53368 :     if( ((SwTxtFormatter*)this)->GetRedln() )
    1861                 :            :     {
    1862                 :          0 :         ((SwTxtFormatter*)this)->GetRedln()->Clear( ((SwTxtFormatter*)this)->GetFnt() );
    1863                 :          0 :         ((SwTxtFormatter*)this)->GetRedln()->Reset();
    1864                 :            :     }
    1865                 :      53368 : }
    1866                 :            : 
    1867                 :            : /*************************************************************************
    1868                 :            :  *                      SwTxtFormatter::FormatReset()
    1869                 :            :  *************************************************************************/
    1870                 :            : 
    1871                 :      53368 : void SwTxtFormatter::FormatReset( SwTxtFormatInfo &rInf )
    1872                 :            : {
    1873                 :      53368 :     pCurr->Truncate();
    1874                 :      53368 :     pCurr->Init();
    1875 [ -  + ][ -  + ]:      53368 :     if( pBlink && pCurr->IsBlinking() )
                 [ +  + ]
    1876                 :          0 :         pBlink->Delete( pCurr );
    1877                 :            : 
    1878                 :            :     // delete pSpaceAdd und pKanaComp
    1879                 :      53368 :     pCurr->FinishSpaceAdd();
    1880                 :      53368 :     pCurr->FinishKanaComp();
    1881                 :      53368 :     pCurr->ResetFlags();
    1882                 :      53368 :     FeedInf( rInf );
    1883                 :      53368 : }
    1884                 :            : 
    1885                 :            : /*************************************************************************
    1886                 :            :  *                SwTxtFormatter::CalcOnceMore()
    1887                 :            :  *************************************************************************/
    1888                 :            : 
    1889                 :          0 : sal_Bool SwTxtFormatter::CalcOnceMore()
    1890                 :            : {
    1891         [ #  # ]:          0 :     if( pDropFmt )
    1892                 :            :     {
    1893                 :          0 :         const KSHORT nOldDrop = GetDropHeight();
    1894                 :          0 :         CalcDropHeight( pDropFmt->GetLines() );
    1895                 :          0 :         bOnceMore = nOldDrop != GetDropHeight();
    1896                 :            :     }
    1897                 :            :     else
    1898                 :          0 :         bOnceMore = sal_False;
    1899                 :          0 :     return bOnceMore;
    1900                 :            : }
    1901                 :            : 
    1902                 :            : /*************************************************************************
    1903                 :            :  *                SwTxtFormatter::CalcBottomLine()
    1904                 :            :  *************************************************************************/
    1905                 :            : 
    1906                 :      14711 : SwTwips SwTxtFormatter::CalcBottomLine() const
    1907                 :            : {
    1908                 :      14711 :     SwTwips nRet = Y() + GetLineHeight();
    1909                 :      14711 :     SwTwips nMin = GetInfo().GetTxtFly()->GetMinBottom();
    1910 [ #  # ][ -  + ]:      14711 :     if( nMin && ++nMin > nRet )
                 [ -  + ]
    1911                 :            :     {
    1912                 :          0 :         SwTwips nDist = pFrm->Frm().Height() - pFrm->Prt().Height()
    1913                 :          0 :                         - pFrm->Prt().Top();
    1914         [ #  # ]:          0 :         if( nRet + nDist < nMin )
    1915                 :            :         {
    1916                 :          0 :             sal_Bool bRepaint = HasTruncLines() &&
    1917 [ #  # ][ #  # ]:          0 :                 GetInfo().GetParaPortion()->GetRepaint()->Bottom() == nRet-1;
    1918                 :          0 :             nRet = nMin - nDist;
    1919         [ #  # ]:          0 :             if( bRepaint )
    1920                 :            :             {
    1921                 :          0 :                 ((SwRepaint*)GetInfo().GetParaPortion()
    1922                 :          0 :                     ->GetRepaint())->Bottom( nRet-1 );
    1923                 :          0 :                 ((SwTxtFormatInfo&)GetInfo()).SetPaintOfst( 0 );
    1924                 :            :             }
    1925                 :            :         }
    1926                 :            :     }
    1927                 :      14711 :     return nRet;
    1928                 :            : }
    1929                 :            : 
    1930                 :            : /*************************************************************************
    1931                 :            :  *                SwTxtFormatter::_CalcFitToContent()
    1932                 :            :  *
    1933                 :            :  * FME/OD: This routine does a limited text formatting.
    1934                 :            :  *************************************************************************/
    1935                 :            : 
    1936                 :         90 : SwTwips SwTxtFormatter::_CalcFitToContent()
    1937                 :            : {
    1938                 :         90 :     FormatReset( GetInfo() );
    1939                 :         90 :     BuildPortions( GetInfo() );
    1940                 :         90 :     pCurr->CalcLine( *this, GetInfo() );
    1941                 :         90 :     return pCurr->Width();
    1942                 :            : }
    1943                 :            : 
    1944                 :            : /*************************************************************************
    1945                 :            :  *                      SwTxtFormatter::AllowRepaintOpt()
    1946                 :            :  *
    1947                 :            :  * determines if the calculation of a repaint offset is allowed
    1948                 :            :  * otherwise each line is painted from 0 (this is a copy of the beginning
    1949                 :            :  * of the former SwTxtFormatter::Recycle() function
    1950                 :            :  *************************************************************************/
    1951                 :      52762 : sal_Bool SwTxtFormatter::AllowRepaintOpt() const
    1952                 :            : {
    1953                 :            :     // reformat position in front of current line? Only in this case
    1954                 :            :     // we want to set the repaint offset
    1955                 :      52762 :     sal_Bool bOptimizeRepaint = nStart < GetInfo().GetReformatStart() &&
    1956 [ +  - ][ +  + ]:      52762 :                                 pCurr->GetLen();
    1957                 :            : 
    1958                 :            :     // a special case is the last line of a block adjusted paragraph:
    1959         [ +  + ]:      52762 :     if ( bOptimizeRepaint )
    1960                 :            :     {
    1961      [ -  +  + ]:       3748 :         switch( GetAdjust() )
    1962                 :            :         {
    1963                 :            :         case SVX_ADJUST_BLOCK:
    1964                 :            :         {
    1965 [ #  # ][ #  # ]:          0 :             if( IsLastBlock() || IsLastCenter() )
                 [ #  # ]
    1966                 :          0 :                 bOptimizeRepaint = sal_False;
    1967                 :            :             else
    1968                 :            :             {
    1969                 :            :                 // ????: Blank in der letzten Masterzeile (blocksat.sdw)
    1970 [ #  # ][ #  # ]:          0 :                 bOptimizeRepaint = 0 == pCurr->GetNext() && !pFrm->GetFollow();
    1971         [ #  # ]:          0 :                 if ( bOptimizeRepaint )
    1972                 :            :                 {
    1973                 :          0 :                     SwLinePortion *pPos = pCurr->GetFirstPortion();
    1974 [ #  # ][ #  # ]:          0 :                     while ( pPos && !pPos->IsFlyPortion() )
                 [ #  # ]
    1975                 :          0 :                         pPos = pPos->GetPortion();
    1976                 :          0 :                     bOptimizeRepaint = !pPos;
    1977                 :            :                 }
    1978                 :            :             }
    1979                 :          0 :             break;
    1980                 :            :         }
    1981                 :            :         case SVX_ADJUST_CENTER:
    1982                 :            :         case SVX_ADJUST_RIGHT:
    1983                 :          4 :             bOptimizeRepaint = sal_False;
    1984                 :       3748 :             break;
    1985                 :            :         default: ;
    1986                 :            :         }
    1987                 :            :     }
    1988                 :            : 
    1989                 :            :     // Schon wieder ein Sonderfall: unsichtbare SoftHyphs
    1990                 :      52762 :     const xub_StrLen nReformat = GetInfo().GetReformatStart();
    1991 [ +  - ][ +  + ]:      52762 :     if( bOptimizeRepaint && STRING_LEN != nReformat )
    1992                 :            :     {
    1993                 :       3744 :         const xub_Unicode cCh = GetInfo().GetTxt().GetChar( nReformat );
    1994                 :            :         bOptimizeRepaint = ( CH_TXTATR_BREAKWORD != cCh && CH_TXTATR_INWORD != cCh )
    1995 [ +  + ][ -  + ]:       3744 :                             || ! GetInfo().HasHint( nReformat );
                 [ +  + ]
    1996                 :            :     }
    1997                 :            : 
    1998                 :      52762 :     return bOptimizeRepaint;
    1999                 :            : }
    2000                 :            : 
    2001                 :          0 : void SwTxtFormatter::CalcUnclipped( SwTwips& rTop, SwTwips& rBottom )
    2002                 :            : {
    2003                 :            :     OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
    2004                 :            :             "SwTxtFormatter::CalcUnclipped with unswapped frame" );
    2005                 :            : 
    2006                 :            :     long nFlyAsc, nFlyDesc;
    2007         [ #  # ]:          0 :     pCurr->MaxAscentDescent( rTop, rBottom, nFlyAsc, nFlyDesc );
    2008                 :          0 :     rTop = Y() + GetCurr()->GetAscent();
    2009                 :          0 :     rBottom = rTop + nFlyDesc;
    2010                 :          0 :     rTop -= nFlyAsc;
    2011                 :          0 : }
    2012                 :            : 
    2013                 :            : 
    2014                 :      12081 : void SwTxtFormatter::UpdatePos( SwLineLayout *pCurrent, Point aStart,
    2015                 :            :     xub_StrLen nStartIdx, sal_Bool bAllWays ) const
    2016                 :            : {
    2017                 :            :     OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
    2018                 :            :             "SwTxtFormatter::UpdatePos with unswapped frame" );
    2019                 :            : 
    2020         [ +  - ]:      12081 :     if( GetInfo().IsTest() )
    2021                 :      12081 :         return;
    2022                 :      12081 :     SwLinePortion *pFirst = pCurrent->GetFirstPortion();
    2023                 :      12081 :     SwLinePortion *pPos = pFirst;
    2024         [ +  - ]:      12081 :     SwTxtPaintInfo aTmpInf( GetInfo() );
    2025                 :      12081 :     aTmpInf.SetpSpaceAdd( pCurrent->GetpLLSpaceAdd() );
    2026                 :      12081 :     aTmpInf.ResetSpaceIdx();
    2027                 :      12081 :     aTmpInf.SetKanaComp( pCurrent->GetpKanaComp() );
    2028                 :      12081 :     aTmpInf.ResetKanaIdx();
    2029                 :            : 
    2030                 :            :     // The frame's size
    2031                 :      12081 :     aTmpInf.SetIdx( nStartIdx );
    2032                 :      12081 :     aTmpInf.SetPos( aStart );
    2033                 :            : 
    2034                 :            :     long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
    2035         [ +  - ]:      12081 :     pCurrent->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
    2036                 :            : 
    2037                 :      12081 :     KSHORT nTmpHeight = pCurrent->GetRealHeight();
    2038                 :      12081 :     KSHORT nAscent = pCurrent->GetAscent() + nTmpHeight - pCurrent->Height();
    2039                 :      12081 :     objectpositioning::AsCharFlags nFlags = AS_CHAR_ULSPACE;
    2040         [ -  + ]:      12081 :     if( GetMulti() )
    2041                 :            :     {
    2042                 :          0 :         aTmpInf.SetDirection( GetMulti()->GetDirection() );
    2043         [ #  # ]:          0 :         if( GetMulti()->HasRotation() )
    2044                 :            :         {
    2045                 :          0 :             nFlags |= AS_CHAR_ROTATE;
    2046         [ #  # ]:          0 :             if( GetMulti()->IsRevers() )
    2047                 :            :             {
    2048                 :          0 :                 nFlags |= AS_CHAR_REVERSE;
    2049                 :          0 :                 aTmpInf.X( aTmpInf.X() - nAscent );
    2050                 :            :             }
    2051                 :            :             else
    2052                 :          0 :                 aTmpInf.X( aTmpInf.X() + nAscent );
    2053                 :            :         }
    2054                 :            :         else
    2055                 :            :         {
    2056         [ #  # ]:          0 :             if ( GetMulti()->IsBidi() )
    2057                 :          0 :                 nFlags |= AS_CHAR_BIDI;
    2058                 :          0 :             aTmpInf.Y( aTmpInf.Y() + nAscent );
    2059                 :            :         }
    2060                 :            :     }
    2061                 :            :     else
    2062                 :      12081 :         aTmpInf.Y( aTmpInf.Y() + nAscent );
    2063                 :            : 
    2064         [ +  + ]:      25610 :     while( pPos )
    2065                 :            :     {
    2066                 :            :         // We only know one case where changing the position (caused by the
    2067                 :            :         // adjustment) could be relevant for a portion: We need to SetRefPoint
    2068                 :            :         // for FlyCntPortions.
    2069 [ +  + ][ -  + ]:      14795 :         if( ( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
         [ +  + ][ +  - ]
                 [ +  + ]
    2070         [ +  - ]:       1266 :             && ( bAllWays || !IsQuick() ) )
    2071                 :            :         {
    2072         [ +  - ]:       1269 :             pCurrent->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, pPos );
    2073                 :            : 
    2074         [ -  + ]:       1269 :             if( pPos->IsGrfNumPortion() )
    2075                 :            :             {
    2076 [ #  # ][ #  # ]:          0 :                 if( !nFlyAsc && !nFlyDesc )
    2077                 :            :                 {
    2078                 :          0 :                     nTmpAscent = nAscent;
    2079                 :          0 :                     nFlyAsc = nAscent;
    2080                 :          0 :                     nTmpDescent = nTmpHeight - nAscent;
    2081                 :          0 :                     nFlyDesc = nTmpDescent;
    2082                 :            :                 }
    2083                 :            :                 ((SwGrfNumPortion*)pPos)->SetBase( nTmpAscent, nTmpDescent,
    2084         [ #  # ]:          0 :                                                    nFlyAsc, nFlyDesc );
    2085                 :            :             }
    2086                 :            :             else
    2087                 :            :             {
    2088                 :       1269 :                 Point aBase( aTmpInf.GetPos() );
    2089 [ -  + ][ +  - ]:       1269 :                 if ( GetInfo().GetTxtFrm()->IsVertical() )
    2090         [ #  # ]:          0 :                     GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aBase );
    2091                 :            : 
    2092                 :       1269 :                 ((SwFlyCntPortion*)pPos)->SetBase( *aTmpInf.GetTxtFrm(),
    2093                 :            :                     aBase, nTmpAscent, nTmpDescent, nFlyAsc,
    2094         [ +  - ]:       1269 :                     nFlyDesc, nFlags );
    2095                 :            :             }
    2096                 :            :         }
    2097 [ +  + ][ -  + ]:      13529 :         if( pPos->IsMultiPortion() && ((SwMultiPortion*)pPos)->HasFlyInCntnt() )
                 [ -  + ]
    2098                 :            :         {
    2099                 :            :             OSL_ENSURE( !GetMulti(), "Too much multi" );
    2100                 :          0 :             ((SwTxtFormatter*)this)->pMulti = (SwMultiPortion*)pPos;
    2101                 :          0 :             SwLineLayout *pLay = &GetMulti()->GetRoot();
    2102                 :          0 :             Point aSt( aTmpInf.X(), aStart.Y() );
    2103                 :            : 
    2104 [ #  # ][ #  # ]:          0 :             if ( GetMulti()->HasBrackets() )
    2105                 :            :             {
    2106                 :            :                 OSL_ENSURE( GetMulti()->IsDouble(), "Brackets only for doubles");
    2107                 :          0 :                 aSt.X() += ((SwDoubleLinePortion*)GetMulti())->PreWidth();
    2108                 :            :             }
    2109         [ #  # ]:          0 :             else if( GetMulti()->HasRotation() )
    2110                 :            :             {
    2111                 :          0 :                 aSt.Y() += pCurrent->GetAscent() - GetMulti()->GetAscent();
    2112         [ #  # ]:          0 :                 if( GetMulti()->IsRevers() )
    2113                 :          0 :                     aSt.X() += GetMulti()->Width();
    2114                 :            :                 else
    2115                 :          0 :                     aSt.Y() += GetMulti()->Height();
    2116                 :            :                }
    2117         [ #  # ]:          0 :             else if ( GetMulti()->IsBidi() )
    2118                 :            :                 // jump to end of the bidi portion
    2119                 :          0 :                 aSt.X() += pLay->Width();
    2120                 :            : 
    2121                 :          0 :             xub_StrLen nStIdx = aTmpInf.GetIdx();
    2122         [ #  # ]:          0 :             do
    2123                 :            :             {
    2124         [ #  # ]:          0 :                 UpdatePos( pLay, aSt, nStIdx, bAllWays );
    2125                 :          0 :                 nStIdx = nStIdx + pLay->GetLen();
    2126                 :          0 :                 aSt.Y() += pLay->Height();
    2127                 :          0 :                 pLay = pLay->GetNext();
    2128                 :            :             } while ( pLay );
    2129                 :          0 :             ((SwTxtFormatter*)this)->pMulti = NULL;
    2130                 :            :         }
    2131         [ +  - ]:      13529 :         pPos->Move( aTmpInf );
    2132                 :      13529 :         pPos = pPos->GetPortion();
    2133         [ +  - ]:      12081 :     }
    2134                 :            : }
    2135                 :            : 
    2136                 :            : 
    2137                 :        939 : void SwTxtFormatter::AlignFlyInCntBase( long nBaseLine ) const
    2138                 :            : {
    2139                 :            :     OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
    2140                 :            :             "SwTxtFormatter::AlignFlyInCntBase with unswapped frame" );
    2141                 :            : 
    2142         [ +  - ]:        939 :     if( GetInfo().IsTest() )
    2143                 :        939 :         return;
    2144                 :        939 :     SwLinePortion *pFirst = pCurr->GetFirstPortion();
    2145                 :        939 :     SwLinePortion *pPos = pFirst;
    2146                 :        939 :     objectpositioning::AsCharFlags nFlags = AS_CHAR_NOFLAG;
    2147 [ #  # ][ -  + ]:        939 :     if( GetMulti() && GetMulti()->HasRotation() )
                 [ -  + ]
    2148                 :            :     {
    2149                 :          0 :         nFlags |= AS_CHAR_ROTATE;
    2150         [ #  # ]:          0 :         if( GetMulti()->IsRevers() )
    2151                 :          0 :             nFlags |= AS_CHAR_REVERSE;
    2152                 :            :     }
    2153                 :            : 
    2154                 :            :     long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
    2155                 :            : 
    2156         [ +  + ]:       2233 :     while( pPos )
    2157                 :            :     {
    2158 [ +  + ][ -  + ]:       1294 :         if( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
                 [ +  + ]
    2159                 :            :         {
    2160         [ +  - ]:       1266 :             pCurr->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, pPos );
    2161                 :            : 
    2162         [ -  + ]:       1266 :             if( pPos->IsGrfNumPortion() )
    2163                 :            :                 ((SwGrfNumPortion*)pPos)->SetBase( nTmpAscent, nTmpDescent,
    2164         [ #  # ]:          0 :                                                    nFlyAsc, nFlyDesc );
    2165                 :            :             else
    2166                 :            :             {
    2167                 :       1266 :                 Point aBase;
    2168 [ -  + ][ +  - ]:       1266 :                 if ( GetInfo().GetTxtFrm()->IsVertical() )
    2169                 :            :                 {
    2170         [ #  # ]:          0 :                     nBaseLine = GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( nBaseLine );
    2171                 :          0 :                     aBase = Point( nBaseLine, ((SwFlyCntPortion*)pPos)->GetRefPoint().Y() );
    2172                 :            :                 }
    2173                 :            :                 else
    2174                 :       1266 :                     aBase = Point( ((SwFlyCntPortion*)pPos)->GetRefPoint().X(), nBaseLine );
    2175                 :            : 
    2176                 :       1266 :                 ((SwFlyCntPortion*)pPos)->SetBase( *GetInfo().GetTxtFrm(), aBase, nTmpAscent, nTmpDescent,
    2177         [ +  - ]:       1266 :                     nFlyAsc, nFlyDesc, nFlags );
    2178                 :            :             }
    2179                 :            :         }
    2180                 :       1294 :         pPos = pPos->GetPortion();
    2181                 :            :     }
    2182                 :            : }
    2183                 :            : 
    2184                 :            : 
    2185                 :        616 : sal_Bool SwTxtFormatter::ChkFlyUnderflow( SwTxtFormatInfo &rInf ) const
    2186                 :            : {
    2187                 :            :     OSL_ENSURE( rInf.GetTxtFly()->IsOn(), "SwTxtFormatter::ChkFlyUnderflow: why?" );
    2188         [ +  - ]:        616 :     if( GetCurr() )
    2189                 :            :     {
    2190                 :            :         // First we check, whether a fly overlaps with the line.
    2191                 :            :         // = GetLineHeight()
    2192                 :        616 :         const long nHeight = GetCurr()->GetRealHeight();
    2193         [ +  - ]:        616 :         SwRect aLine( GetLeftMargin(), Y(), rInf.RealWidth(), nHeight );
    2194                 :            : 
    2195                 :        616 :         SwRect aLineVert( aLine );
    2196 [ -  + ][ +  - ]:        616 :         if ( pFrm->IsVertical() )
    2197         [ #  # ]:          0 :             pFrm->SwitchHorizontalToVertical( aLineVert );
    2198         [ +  - ]:        616 :         SwRect aInter( rInf.GetTxtFly()->GetFrm( aLineVert ) );
    2199 [ +  - ][ -  + ]:        616 :         if ( pFrm->IsVertical() )
    2200         [ #  # ]:          0 :             pFrm->SwitchVerticalToHorizontal( aInter );
    2201                 :            : 
    2202 [ +  - ][ +  + ]:        616 :         if( !aInter.HasArea() )
    2203                 :        234 :             return sal_False;
    2204                 :            : 
    2205                 :            :         // We now check every portion that could have lowered for overlapping
    2206                 :            :         // with the fly.
    2207                 :        382 :         const SwLinePortion *pPos = GetCurr()->GetFirstPortion();
    2208                 :        382 :         aLine.Pos().Y() = Y() + GetCurr()->GetRealHeight() - GetCurr()->Height();
    2209                 :        382 :         aLine.Height( GetCurr()->Height() );
    2210                 :            : 
    2211         [ +  + ]:       1264 :         while( pPos )
    2212                 :            :         {
    2213                 :        648 :             aLine.Width( pPos->Width() );
    2214                 :            : 
    2215                 :        648 :             aLineVert = aLine;
    2216 [ -  + ][ +  - ]:        648 :             if ( pFrm->IsVertical() )
    2217         [ #  # ]:          0 :                 pFrm->SwitchHorizontalToVertical( aLineVert );
    2218         [ +  - ]:        648 :             aInter = rInf.GetTxtFly()->GetFrm( aLineVert );
    2219 [ -  + ][ +  - ]:        648 :             if ( pFrm->IsVertical() )
    2220         [ #  # ]:          0 :                 pFrm->SwitchVerticalToHorizontal( aInter );
    2221                 :            : 
    2222                 :            :             // New flys from below?
    2223         [ +  + ]:        648 :             if( !pPos->IsFlyPortion() )
    2224                 :            :             {
    2225 [ +  - ][ -  + ]:        529 :                 if( aInter.IsOver( aLine ) )
    2226                 :            :                 {
    2227         [ #  # ]:          0 :                     aInter._Intersection( aLine );
    2228 [ #  # ][ #  # ]:          0 :                     if( aInter.HasArea() )
    2229                 :            :                     {
    2230                 :            :                         // To be evaluated during reformat of this line:
    2231                 :            :                         // RealHeight including spacing
    2232                 :          0 :                         rInf.SetLineHeight( KSHORT(nHeight) );
    2233                 :            :                         // Height without extra spacing
    2234                 :          0 :                         rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
    2235                 :          0 :                         return sal_True;
    2236                 :            :                     }
    2237                 :            :                 }
    2238                 :            :             }
    2239                 :            :             else
    2240                 :            :             {
    2241                 :            :                 // The fly portion is not intersected by a fly anymore
    2242 [ +  - ][ -  + ]:        119 :                 if ( ! aInter.IsOver( aLine ) )
    2243                 :            :                 {
    2244                 :          0 :                     rInf.SetLineHeight( KSHORT(nHeight) );
    2245                 :          0 :                     rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
    2246                 :          0 :                     return sal_True;
    2247                 :            :                 }
    2248                 :            :                 else
    2249                 :            :                 {
    2250         [ +  - ]:        119 :                     aInter._Intersection( aLine );
    2251                 :            : 
    2252                 :            :                     // No area means a fly has become invalid because of
    2253                 :            :                     // lowering the line => reformat the line
    2254                 :            :                     // we also have to reformat the line, if the fly size
    2255                 :            :                     // differs from the intersection interval's size.
    2256         [ +  - ]:        238 :                     if( ! aInter.HasArea() ||
           [ +  -  -  + ]
                 [ -  + ]
    2257                 :        119 :                         ((SwFlyPortion*)pPos)->GetFixWidth() != aInter.Width() )
    2258                 :            :                     {
    2259                 :          0 :                         rInf.SetLineHeight( KSHORT(nHeight) );
    2260                 :          0 :                         rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) );
    2261                 :          0 :                         return sal_True;
    2262                 :            :                     }
    2263                 :            :                 }
    2264                 :            :             }
    2265                 :            : 
    2266                 :        648 :             aLine.Left( aLine.Left() + pPos->Width() );
    2267                 :        648 :             pPos = pPos->GetPortion();
    2268                 :            :         }
    2269                 :            :     }
    2270                 :        616 :     return sal_False;
    2271                 :            : }
    2272                 :            : 
    2273                 :     121553 : void SwTxtFormatter::CalcFlyWidth( SwTxtFormatInfo &rInf )
    2274                 :            : {
    2275 [ +  + ][ +  + ]:     121553 :     if( GetMulti() || rInf.GetFly() )
                 [ +  + ]
    2276                 :            :         return;
    2277                 :            : 
    2278                 :     118848 :     SwTxtFly *pTxtFly = rInf.GetTxtFly();
    2279 [ +  + ][ +  + ]:     118848 :     if( !pTxtFly->IsOn() || rInf.IsIgnoreFly() )
                 [ +  + ]
    2280                 :            :         return;
    2281                 :            : 
    2282                 :       1856 :     const SwLinePortion *pLast = rInf.GetLast();
    2283                 :            : 
    2284                 :            :     long nAscent;
    2285                 :       1856 :     long nTop = Y();
    2286                 :            :     long nHeight;
    2287                 :            : 
    2288         [ -  + ]:       1856 :     if( rInf.GetLineHeight() )
    2289                 :            :     {
    2290                 :            :         // Real line height has already been calculated, we only have to
    2291                 :            :         // search for intersections in the lower part of the strip
    2292                 :          0 :         nAscent = pCurr->GetAscent();
    2293                 :          0 :         nHeight = rInf.GetLineNettoHeight();
    2294                 :          0 :         nTop += rInf.GetLineHeight() - nHeight;
    2295                 :            :     }
    2296                 :            :     else
    2297                 :            :     {
    2298                 :       1856 :         nAscent = pLast->GetAscent();
    2299                 :       1856 :         nHeight = pLast->Height();
    2300                 :            : 
    2301                 :            :         // We make a first guess for the lines real height
    2302         [ +  + ]:       1856 :         if ( ! pCurr->GetRealHeight() )
    2303         [ +  - ]:       1120 :             CalcRealHeight();
    2304                 :            : 
    2305         [ +  + ]:       1856 :         if ( pCurr->GetRealHeight() > nHeight )
    2306                 :          5 :             nTop += pCurr->GetRealHeight() - nHeight;
    2307                 :            :         else
    2308                 :            :             // Important for fixed space between lines
    2309                 :       1851 :             nHeight = pCurr->GetRealHeight();
    2310                 :            :     }
    2311                 :            : 
    2312         [ +  - ]:       1856 :     const long nLeftMar = GetLeftMargin();
    2313 [ +  + ][ +  - ]:       1856 :     const long nLeftMin = (rInf.X() || GetDropLeft()) ? nLeftMar : GetLeftMin();
    2314                 :            : 
    2315                 :       1856 :     SwRect aLine( rInf.X() + nLeftMin, nTop, rInf.RealWidth() - rInf.X()
    2316                 :       1856 :                   + nLeftMar - nLeftMin , nHeight );
    2317                 :            : 
    2318                 :       1856 :     SwRect aLineVert( aLine );
    2319 [ -  + ][ +  - ]:       1856 :     if ( pFrm->IsRightToLeft() )
    2320         [ #  # ]:          0 :         pFrm->SwitchLTRtoRTL( aLineVert );
    2321                 :            : 
    2322 [ +  - ][ -  + ]:       1856 :     if ( pFrm->IsVertical() )
    2323         [ #  # ]:          0 :         pFrm->SwitchHorizontalToVertical( aLineVert );
    2324         [ +  - ]:       1856 :     SwRect aInter( pTxtFly->GetFrm( aLineVert ) );
    2325                 :            : 
    2326 [ +  - ][ -  + ]:       1856 :     if ( pFrm->IsRightToLeft() )
    2327         [ #  # ]:          0 :         pFrm->SwitchRTLtoLTR( aInter );
    2328                 :            : 
    2329 [ +  - ][ -  + ]:       1856 :     if ( pFrm->IsVertical() )
    2330         [ #  # ]:          0 :         pFrm->SwitchVerticalToHorizontal( aInter );
    2331                 :            : 
    2332 [ +  - ][ +  + ]:       1856 :     if( aInter.IsOver( aLine ) )
    2333                 :            :     {
    2334                 :        729 :         aLine.Left( rInf.X() + nLeftMar );
    2335                 :        729 :         sal_Bool bForced = sal_False;
    2336         [ +  + ]:        729 :         if( aInter.Left() <= nLeftMin )
    2337                 :            :         {
    2338                 :         38 :             SwTwips nFrmLeft = GetTxtFrm()->Frm().Left();
    2339         [ -  + ]:         38 :             if( GetTxtFrm()->Prt().Left() < 0 )
    2340                 :          0 :                 nFrmLeft += GetTxtFrm()->Prt().Left();
    2341         [ +  + ]:         38 :             if( aInter.Left() < nFrmLeft )
    2342                 :         25 :                 aInter.Left( nFrmLeft );
    2343                 :            : 
    2344                 :         38 :             long nAddMar = 0;
    2345 [ +  - ][ -  + ]:         38 :             if ( pFrm->IsRightToLeft() )
    2346                 :            :             {
    2347                 :          0 :                 nAddMar = pFrm->Frm().Right() - Right();
    2348         [ #  # ]:          0 :                 if ( nAddMar < 0 )
    2349                 :          0 :                     nAddMar = 0;
    2350                 :            :             }
    2351                 :            :             else
    2352                 :         38 :                 nAddMar = nLeftMar - nFrmLeft;
    2353                 :            : 
    2354                 :         38 :             aInter.Width( aInter.Width() + nAddMar );
    2355                 :            :             // For a negative first line indent, we set this flag to show
    2356                 :            :             // that the indentation/margin has been moved.
    2357                 :            :             // This needs to be respected by the DefaultTab at the zero position.
    2358 [ +  - ][ -  + ]:         38 :             if( IsFirstTxtLine() && HasNegFirst() )
         [ -  + ][ +  - ]
    2359                 :          0 :                 bForced = sal_True;
    2360                 :            :         }
    2361         [ +  - ]:        729 :         aInter.Intersection( aLine );
    2362 [ +  - ][ +  - ]:        729 :         if( !aInter.HasArea() )
    2363                 :            :             return;
    2364                 :            : 
    2365                 :        729 :         const sal_Bool bFullLine =  aLine.Left()  == aInter.Left() &&
    2366 [ +  + ][ +  + ]:        729 :                                 aLine.Right() == aInter.Right();
    2367                 :            : 
    2368                 :            :         // Although no text is left, we need to format another line,
    2369                 :            :         // because also empty lines need to avoid a Fly with no wrapping.
    2370 [ +  + ][ +  - ]:        729 :         if( bFullLine && rInf.GetIdx() == rInf.GetTxt().Len() )
                 [ +  + ]
    2371                 :            :         {
    2372                 :         14 :             rInf.SetNewLine( sal_True );
    2373                 :            :             // 8221: We know that for dummies, it holds ascent == height
    2374                 :         14 :             pCurr->SetDummy(sal_True);
    2375                 :            :         }
    2376                 :            : 
    2377                 :            :         // aInter becomes frame-local
    2378                 :        729 :         aInter.Pos().X() -= nLeftMar;
    2379 [ +  - ][ +  - ]:        729 :         SwFlyPortion *pFly = new SwFlyPortion( aInter );
    2380         [ -  + ]:        729 :         if( bForced )
    2381                 :            :         {
    2382                 :          0 :             pCurr->SetForcedLeftMargin( sal_True );
    2383                 :          0 :             rInf.ForcedLeftMargin( (sal_uInt16)aInter.Width() );
    2384                 :            :         }
    2385                 :            : 
    2386         [ +  + ]:        729 :         if( bFullLine )
    2387                 :            :         {
    2388                 :            :             // 8110: In order to properly flow around Flys with different
    2389                 :            :             // wrapping attributes, we need to increase by units of line height.
    2390                 :            :             // The last avoiding line should be adjusted in height, so that
    2391                 :            :             // we don't get a frame spacing effect.
    2392                 :            :             // 8221: It is important that ascent == height, because the FlyPortion
    2393                 :            :             // values are transferred to pCurr in CalcLine and IsDummy() relies
    2394                 :            :             // on this behaviour.
    2395                 :            :             // To my knowledge we only have two places where DummyLines can be
    2396                 :            :             // created: here and in MakeFlyDummies.
    2397                 :            :             // IsDummy() is evaluated in IsFirstTxtLine(), when moving lines
    2398                 :            :             // and in relation with DropCaps.
    2399                 :         14 :             pFly->Height( KSHORT(aInter.Height()) );
    2400                 :            : 
    2401                 :            :             // nNextTop now contains the margin's bottom edge, which we avoid
    2402                 :            :             // or the next margin's top edge, which we need to respect.
    2403                 :            :             // That means we can comfortably grow up to this value; that's how
    2404                 :            :             // we save a few empty lines.
    2405                 :         14 :             long nNextTop = pTxtFly->GetNextTop();
    2406 [ -  + ][ +  - ]:         14 :             if ( pFrm->IsVertical() )
    2407         [ #  # ]:          0 :                 nNextTop = pFrm->SwitchVerticalToHorizontal( nNextTop );
    2408         [ +  - ]:         14 :             if( nNextTop > aInter.Bottom() )
    2409                 :            :             {
    2410                 :         14 :                 SwTwips nH = nNextTop - aInter.Top();
    2411         [ +  - ]:         14 :                 if( nH < KSHRT_MAX )
    2412                 :         14 :                     pFly->Height( KSHORT( nH ) );
    2413                 :            :             }
    2414         [ +  - ]:         14 :             if( nAscent < pFly->Height() )
    2415                 :         14 :                 pFly->SetAscent( KSHORT(nAscent) );
    2416                 :            :             else
    2417                 :          0 :                 pFly->SetAscent( pFly->Height() );
    2418                 :            :         }
    2419                 :            :         else
    2420                 :            :         {
    2421         [ +  + ]:        715 :             if( rInf.GetIdx() == rInf.GetTxt().Len() )
    2422                 :            :             {
    2423                 :            :                 // Don't use nHeight, or we have a huge descent
    2424                 :        263 :                 pFly->Height( pLast->Height() );
    2425                 :        263 :                 pFly->SetAscent( pLast->GetAscent() );
    2426                 :            :             }
    2427                 :            :             else
    2428                 :            :             {
    2429                 :        452 :                 pFly->Height( KSHORT(aInter.Height()) );
    2430         [ +  + ]:        452 :                 if( nAscent < pFly->Height() )
    2431                 :        414 :                     pFly->SetAscent( KSHORT(nAscent) );
    2432                 :            :                 else
    2433                 :         38 :                     pFly->SetAscent( pFly->Height() );
    2434                 :            :             }
    2435                 :            :         }
    2436                 :            : 
    2437                 :        729 :         rInf.SetFly( pFly );
    2438                 :            : 
    2439         [ +  + ]:        729 :         if( pFly->Fix() < rInf.Width() )
    2440                 :        385 :             rInf.Width( pFly->Fix() );
    2441                 :            : 
    2442 [ +  - ][ +  - ]:        729 :         GETGRID( pFrm->FindPageFrm() )
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
    2443         [ -  + ]:        729 :         if ( pGrid )
    2444                 :            :         {
    2445         [ #  # ]:          0 :             const SwPageFrm* pPageFrm = pFrm->FindPageFrm();
    2446         [ #  # ]:          0 :             const SwLayoutFrm* pBody = pPageFrm->FindBodyCont();
    2447                 :            : 
    2448 [ #  # ][ #  # ]:          0 :             SWRECTFN( pPageFrm )
         [ #  # ][ #  # ]
                 [ #  # ]
    2449                 :            : 
    2450                 :            :             const long nGridOrigin = pBody ?
    2451         [ #  # ]:          0 :                                     (pBody->*fnRect->fnGetPrtLeft)() :
    2452 [ #  # ][ #  # ]:          0 :                                     (pPageFrm->*fnRect->fnGetPrtLeft)();
         [ #  # ][ #  # ]
    2453                 :            : 
    2454                 :          0 :             const SwDoc *pDoc = rInf.GetTxtFrm()->GetNode()->GetDoc();
    2455 [ #  # ][ #  # ]:          0 :             const sal_uInt16 nGridWidth = GETGRIDWIDTH( pGrid, pDoc);   //For textgrid refactor
    2456                 :            : 
    2457         [ #  # ]:          0 :             SwTwips nStartX = GetLeftMargin();
    2458         [ #  # ]:          0 :             if ( bVert )
    2459                 :            :             {
    2460                 :          0 :                 Point aPoint( nStartX, 0 );
    2461         [ #  # ]:          0 :                 pFrm->SwitchHorizontalToVertical( aPoint );
    2462                 :          0 :                 nStartX = aPoint.Y();
    2463                 :            :             }
    2464                 :            : 
    2465                 :          0 :             const SwTwips nOfst = nStartX - nGridOrigin;
    2466                 :          0 :             const SwTwips nTmpWidth = rInf.Width() + nOfst;
    2467                 :            : 
    2468                 :          0 :             const sal_uLong i = nTmpWidth / nGridWidth + 1;
    2469                 :            : 
    2470                 :          0 :             const long nNewWidth = ( i - 1 ) * nGridWidth - nOfst;
    2471         [ #  # ]:          0 :             if ( nNewWidth > 0 )
    2472                 :          0 :                 rInf.Width( (sal_uInt16)nNewWidth );
    2473                 :            :             else
    2474                 :     121553 :                 rInf.Width( 0 );
    2475                 :            :         }
    2476                 :            :     }
    2477                 :            : }
    2478                 :            : 
    2479                 :            : 
    2480                 :       1290 : SwFlyCntPortion *SwTxtFormatter::NewFlyCntPortion( SwTxtFormatInfo &rInf,
    2481                 :            :                                                    SwTxtAttr *pHint ) const
    2482                 :            : {
    2483                 :       1290 :     SwFlyCntPortion *pRet = 0;
    2484                 :       1290 :     const SwFrm *pFrame = (SwFrm*)pFrm;
    2485                 :            : 
    2486                 :            :     SwFlyInCntFrm *pFly;
    2487                 :       1290 :     SwFrmFmt* pFrmFmt = ((SwTxtFlyCnt*)pHint)->GetFlyCnt().GetFrmFmt();
    2488         [ +  + ]:       1290 :     if( RES_FLYFRMFMT == pFrmFmt->Which() )
    2489         [ +  - ]:        562 :         pFly = ((SwTxtFlyCnt*)pHint)->GetFlyFrm(pFrame);
    2490                 :            :     else
    2491                 :        728 :         pFly = NULL;
    2492                 :            :     // aBase is the document-global position, from which the new extra portion is placed
    2493                 :            :     // aBase.X() = Offset in in the line after the current position
    2494                 :            :     // aBase.Y() = LineIter.Y() + Ascent of the current position
    2495                 :            : 
    2496                 :            :     long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
    2497                 :            :     // OD 08.01.2004 #i11859# - use new method <SwLineLayout::MaxAscentDescent(..)>
    2498                 :            :     //SwLinePortion *pPos = pCurr->GetFirstPortion();
    2499                 :            :     //lcl_MaxAscDescent( pPos, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
    2500         [ +  - ]:       1290 :     pCurr->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
    2501                 :            : 
    2502                 :            :     // If the ascent of the frame is larger than the ascent of the current position,
    2503                 :            :     // we use this one when calculating the base, or the frame would be positioned
    2504                 :            :     // too much to the top, sliding down after all causing a repaint in an area
    2505                 :            :     // he actually never was in.
    2506                 :       1290 :     KSHORT nAscent = 0;
    2507                 :            : 
    2508         [ +  - ]:       1290 :     const bool bTxtFrmVertical = GetInfo().GetTxtFrm()->IsVertical();
    2509                 :            : 
    2510                 :        562 :     const bool bUseFlyAscent = pFly && pFly->GetValidPosFlag() &&
    2511                 :            :                                0 != ( bTxtFrmVertical ?
    2512                 :          0 :                                       pFly->GetRefPoint().X() :
    2513   [ +  +  +  + ]:       1852 :                                       pFly->GetRefPoint().Y() );
           [ -  +  #  # ]
                 [ +  + ]
    2514                 :            : 
    2515         [ +  + ]:       1290 :     if ( bUseFlyAscent )
    2516                 :            :          nAscent = static_cast<sal_uInt16>( Abs( int( bTxtFrmVertical ?
    2517 [ #  # ][ -  + ]:         92 :                                                   pFly->GetRelPos().X() :
                 [ #  # ]
    2518 [ -  + ][ +  - ]:         92 :                                                   pFly->GetRelPos().Y() ) ) );
         [ +  - ][ #  # ]
    2519                 :            : 
    2520                 :            :     // Check if be prefer to use the ascent of the last portion:
    2521 [ +  - ][ +  - ]:       1382 :     if ( IsQuick() ||
           [ +  +  +  + ]
                 [ +  + ]
    2522                 :       1290 :          !bUseFlyAscent ||
    2523                 :         92 :          nAscent < rInf.GetLast()->GetAscent() )
    2524                 :            :     {
    2525                 :       1206 :         nAscent = rInf.GetLast()->GetAscent();
    2526                 :            :     }
    2527         [ +  - ]:         84 :     else if( nAscent > nFlyAsc )
    2528                 :         84 :         nFlyAsc = nAscent;
    2529                 :            : 
    2530         [ +  - ]:       1290 :     Point aBase( GetLeftMargin() + rInf.X(), Y() + nAscent );
    2531 [ -  + ][ +  - ]:       1290 :     objectpositioning::AsCharFlags nMode = IsQuick() ? AS_CHAR_QUICK : 0;
    2532 [ -  + ][ #  # ]:       1290 :     if( GetMulti() && GetMulti()->HasRotation() )
                 [ -  + ]
    2533                 :            :     {
    2534                 :          0 :         nMode |= AS_CHAR_ROTATE;
    2535         [ #  # ]:          0 :         if( GetMulti()->IsRevers() )
    2536                 :          0 :             nMode |= AS_CHAR_REVERSE;
    2537                 :            :     }
    2538                 :            : 
    2539                 :       1290 :     Point aTmpBase( aBase );
    2540 [ +  - ][ -  + ]:       1290 :     if ( GetInfo().GetTxtFrm()->IsVertical() )
    2541         [ #  # ]:          0 :         GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aTmpBase );
    2542                 :            : 
    2543         [ +  + ]:       1290 :     if( pFly )
    2544                 :            :     {
    2545                 :        562 :         pRet = new SwFlyCntPortion( *GetInfo().GetTxtFrm(), pFly, aTmpBase,
    2546 [ +  - ][ +  - ]:        562 :                                     nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode );
    2547                 :            :         // We need to make sure that our font is set again in the OutputDevice
    2548                 :            :         // It could be that the FlyInCnt was added anew and GetFlyFrm() would
    2549                 :            :         // in turn cause, that it'd be created anew again.
    2550                 :            :         // This one's frames get formatted right away, which change the font and
    2551                 :            :         // we have a bug (3322).
    2552         [ +  - ]:        562 :         rInf.SelectFont();
    2553         [ +  + ]:        562 :         if( pRet->GetAscent() > nAscent )
    2554                 :            :         {
    2555                 :        362 :             aBase.Y() = Y() + pRet->GetAscent();
    2556                 :        362 :             nMode |= AS_CHAR_ULSPACE;
    2557         [ +  - ]:        362 :             if( !rInf.IsTest() )
    2558                 :        362 :                 aTmpBase = aBase;
    2559 [ +  - ][ -  + ]:        362 :                 if ( GetInfo().GetTxtFrm()->IsVertical() )
    2560         [ #  # ]:          0 :                     GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aTmpBase );
    2561                 :            : 
    2562                 :        362 :                 pRet->SetBase( *rInf.GetTxtFrm(), aTmpBase, nTmpAscent,
    2563         [ +  - ]:        362 :                                nTmpDescent, nFlyAsc, nFlyDesc, nMode );
    2564                 :            :         }
    2565                 :            :     }
    2566                 :            :     else
    2567                 :            :     {
    2568                 :        728 :         pRet = new SwFlyCntPortion( *rInf.GetTxtFrm(), (SwDrawContact*)pFrmFmt->FindContactObj(),
    2569 [ +  - ][ +  - ]:        728 :            aTmpBase, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode );
                 [ +  - ]
    2570                 :            :     }
    2571                 :       1290 :     return pRet;
    2572                 :            : }
    2573                 :            : 
    2574                 :            : namespace {
    2575                 :            :     /*************************************************************************
    2576                 :            :     *                      ::CalcOptRepaint()
    2577                 :            :     *
    2578                 :            :     * calculates and sets optimal repaint offset for the current line
    2579                 :            :     *************************************************************************/
    2580                 :       3304 :     long lcl_CalcOptRepaint( SwTxtFormatter &rThis,
    2581                 :            :                          SwLineLayout &rCurr,
    2582                 :            :                          const xub_StrLen nOldLineEnd,
    2583                 :            :                          const std::vector<long> &rFlyStarts )
    2584                 :            :     {
    2585         [ +  - ]:       3304 :         SwTxtFormatInfo txtFmtInfo = rThis.GetInfo();
    2586         [ +  + ]:       3304 :         if ( txtFmtInfo.GetIdx() < txtFmtInfo.GetReformatStart() )
    2587                 :            :         // the reformat position is behind our new line, that means
    2588                 :            :         // something of our text has moved to the next line
    2589                 :        186 :             return 0;
    2590                 :            : 
    2591                 :       3118 :         xub_StrLen nReformat = Min( txtFmtInfo.GetReformatStart(), nOldLineEnd );
    2592                 :            : 
    2593                 :            :         // in case we do not have any fly in our line, our repaint position
    2594                 :            :         // is the changed position - 1
    2595 [ +  - ][ +  - ]:       3118 :         if ( rFlyStarts.empty() && ! rCurr.IsFly() )
                 [ +  - ]
    2596                 :            :         {
    2597                 :            :             // this is the maximum repaint offset determined during formatting
    2598                 :            :             // for example: the beginning of the first right tab stop
    2599                 :            :             // if this value is 0, this means that we do not have an upper
    2600                 :            :             // limit for the repaint offset
    2601                 :       3118 :             const long nFormatRepaint = txtFmtInfo.GetPaintOfst();
    2602                 :            : 
    2603         [ +  + ]:       3118 :             if ( nReformat < txtFmtInfo.GetLineStart() + 3 )
    2604                 :         50 :                 return 0;
    2605                 :            : 
    2606                 :            :             // step back two positions for smoother repaint
    2607                 :       3068 :             nReformat -= 2;
    2608                 :            : 
    2609                 :            :     #ifndef QUARTZ
    2610                 :            :     #ifndef ENABLE_GRAPHITE
    2611                 :            :             // #i28795#, #i34607#, #i38388#
    2612                 :            :             // step back six(!) more characters for complex scripts
    2613                 :            :             // this is required e.g., for Khmer (thank you, Javier!)
    2614                 :            :             const SwScriptInfo& rSI = txtFmtInfo.GetParaPortion()->GetScriptInfo();
    2615                 :            :             xub_StrLen nMaxContext = 0;
    2616                 :            :             if( ::i18n::ScriptType::COMPLEX == rSI.ScriptType( nReformat ) )
    2617                 :            :                 nMaxContext = 6;
    2618                 :            :     #else
    2619                 :            :             // Some Graphite fonts need context for scripts not marked as complex
    2620                 :            :             static const xub_StrLen nMaxContext = 10;
    2621                 :            :     #endif
    2622                 :            :     #else
    2623                 :            :             // some fonts like Quartz's Zapfino need more context
    2624                 :            :             // TODO: query FontInfo for maximum unicode context
    2625                 :            :             static const xub_StrLen nMaxContext = 8;
    2626                 :            :     #endif
    2627                 :            :             if( nMaxContext > 0 )
    2628                 :            :             {
    2629         [ +  + ]:       3068 :                 if ( nReformat > txtFmtInfo.GetLineStart() + nMaxContext )
    2630                 :       2786 :                     nReformat = nReformat - nMaxContext;
    2631                 :            :                 else
    2632                 :        282 :                     nReformat = txtFmtInfo.GetLineStart();
    2633                 :            :             }
    2634                 :            : 
    2635                 :            :             // Weird situation: Our line used to end with a hole portion
    2636                 :            :             // and we delete some characters at the end of our line. We have
    2637                 :            :             // to take care for repainting the blanks which are not anymore
    2638                 :            :             // covered by the hole portion
    2639   [ +  +  +  + ]:       5942 :             while ( nReformat > txtFmtInfo.GetLineStart() &&
                 [ +  + ]
    2640                 :       2830 :                     CH_BLANK == txtFmtInfo.GetChar( nReformat ) )
    2641                 :         44 :                 --nReformat;
    2642                 :            : 
    2643                 :            :             OSL_ENSURE( nReformat < txtFmtInfo.GetIdx(), "Reformat too small for me!" );
    2644                 :       3068 :             SwRect aRect;
    2645                 :            : 
    2646                 :            :             // Note: GetChareRect is not const. It definitely changes the
    2647                 :            :             // bMulti flag. We have to save and resore the old value.
    2648                 :       3068 :             sal_Bool bOldMulti = txtFmtInfo.IsMulti();
    2649         [ +  - ]:       3068 :             rThis.GetCharRect( &aRect, nReformat );
    2650                 :       3068 :             txtFmtInfo.SetMulti( bOldMulti );
    2651                 :            : 
    2652                 :         52 :             return nFormatRepaint ? Min( aRect.Left(), nFormatRepaint ) :
    2653         [ +  + ]:       3170 :                                     aRect.Left();
    2654                 :            :         }
    2655                 :            :         else
    2656                 :            :         {
    2657                 :            :             // nReformat may be wrong, if something around flys has changed:
    2658                 :            :             // we compare the former and the new fly positions in this line
    2659                 :            :             // if anything has changed, we carefully have to adjust the right
    2660                 :            :             // repaint position
    2661                 :          0 :             long nPOfst = 0;
    2662                 :          0 :             sal_uInt16 nCnt = 0;
    2663                 :          0 :             sal_uInt16 nX = 0;
    2664                 :          0 :             sal_uInt16 nIdx = rThis.GetInfo().GetLineStart();
    2665                 :          0 :             SwLinePortion* pPor = rCurr.GetFirstPortion();
    2666                 :            : 
    2667         [ #  # ]:          0 :             while ( pPor )
    2668                 :            :             {
    2669         [ #  # ]:          0 :                 if ( pPor->IsFlyPortion() )
    2670                 :            :                 {
    2671                 :            :                     // compare start of fly with former start of fly
    2672 [ #  # ][ #  # ]:          0 :                     if (nCnt < rFlyStarts.size() &&
         [ #  # ][ #  # ]
    2673         [ #  # ]:          0 :                         nX == rFlyStarts[ nCnt ] &&
    2674                 :            :                         nIdx < nReformat
    2675                 :            :                     )
    2676                 :            :                         // found fix position, nothing has changed left from nX
    2677                 :          0 :                         nPOfst = nX + pPor->Width();
    2678                 :            :                     else
    2679                 :          0 :                         break;
    2680                 :            : 
    2681                 :          0 :                     nCnt++;
    2682                 :            :                 }
    2683                 :          0 :                 nX = nX + pPor->Width();
    2684                 :          0 :                 nIdx = nIdx + pPor->GetLen();
    2685                 :          0 :                 pPor = pPor->GetPortion();
    2686                 :            :             }
    2687                 :            : 
    2688         [ #  # ]:          0 :             return nPOfst + rThis.GetLeftMargin();
    2689         [ +  - ]:       3304 :         }
    2690                 :            :     }
    2691                 :            : 
    2692                 :            :     // Determine if we need to build hidden portions
    2693                 :      66815 :     bool lcl_BuildHiddenPortion( const SwTxtSizeInfo& rInf, xub_StrLen &rPos )
    2694                 :            :     {
    2695                 :            :         // Only if hidden text should not be shown:
    2696                 :            :     //    if ( rInf.GetVsh() && rInf.GetVsh()->GetWin() && rInf.GetOpt().IsShowHiddenChar() )
    2697 [ +  - ][ +  + ]:      66815 :         const bool bShowInDocView = rInf.GetVsh() && rInf.GetVsh()->GetWin() && rInf.GetOpt().IsShowHiddenChar();
                 [ -  + ]
    2698 [ -  + ][ #  # ]:      66815 :         const bool bShowForPrinting = rInf.GetOpt().IsShowHiddenChar( sal_True ) && rInf.GetOpt().IsPrinting();
    2699 [ +  - ][ -  + ]:      66815 :         if (bShowInDocView || bShowForPrinting)
    2700                 :          0 :             return false;
    2701                 :            : 
    2702                 :      66815 :         const SwScriptInfo& rSI = rInf.GetParaPortion()->GetScriptInfo();
    2703                 :            :         xub_StrLen nHiddenStart;
    2704                 :            :         xub_StrLen nHiddenEnd;
    2705         [ +  - ]:      66815 :         rSI.GetBoundsOfHiddenRange( rPos, nHiddenStart, nHiddenEnd );
    2706         [ -  + ]:      66815 :         if ( nHiddenEnd )
    2707                 :            :         {
    2708                 :          0 :             rPos = nHiddenEnd;
    2709                 :          0 :             return true;
    2710                 :            :         }
    2711                 :            : 
    2712                 :      66815 :         return false;
    2713                 :            :     }
    2714                 :            : 
    2715                 :            : } //end unnamed namespace
    2716                 :            : 
    2717                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10