LCOV - code coverage report
Current view: top level - editeng/source/editeng - impedit3.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1324 2283 58.0 %
Date: 2012-08-25 Functions: 43 64 67.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1419 3558 39.9 %

           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 <vcl/wrkwin.hxx>
      31                 :            : #include <vcl/dialog.hxx>
      32                 :            : #include <vcl/msgbox.hxx>
      33                 :            : #include <vcl/svapp.hxx>
      34                 :            : #include <vcl/metaact.hxx>
      35                 :            : #include <vcl/gdimtf.hxx>
      36                 :            : 
      37                 :            : #include <editeng/adjitem.hxx>
      38                 :            : #include <editeng/tstpitem.hxx>
      39                 :            : #include <editeng/lspcitem.hxx>
      40                 :            : #include <editeng/flditem.hxx>
      41                 :            : #include <impedit.hxx>
      42                 :            : #include <editeng/editeng.hxx>
      43                 :            : #include <editeng/editview.hxx>
      44                 :            : #include <editeng/txtrange.hxx>
      45                 :            : #include <editeng/cscoitem.hxx>
      46                 :            : #include <editeng/colritem.hxx>
      47                 :            : #include <editeng/udlnitem.hxx>
      48                 :            : #include <editeng/fhgtitem.hxx>
      49                 :            : #include <editeng/kernitem.hxx>
      50                 :            : #include <editeng/lrspitem.hxx>
      51                 :            : #include <editeng/ulspitem.hxx>
      52                 :            : #include <editeng/fontitem.hxx>
      53                 :            : #include <editeng/wghtitem.hxx>
      54                 :            : #include <editeng/postitem.hxx>
      55                 :            : #include <editeng/langitem.hxx>
      56                 :            : #include <editeng/scriptspaceitem.hxx>
      57                 :            : #include <editeng/charscaleitem.hxx>
      58                 :            : #include <editeng/numitem.hxx>
      59                 :            : #include <editeng/justifyitem.hxx>
      60                 :            : 
      61                 :            : #include <svtools/colorcfg.hxx>
      62                 :            : #include <svl/ctloptions.hxx>
      63                 :            : 
      64                 :            : #include <editeng/forbiddencharacterstable.hxx>
      65                 :            : 
      66                 :            : #include <unotools/localedatawrapper.hxx>
      67                 :            : 
      68                 :            : #include <editeng/unolingu.hxx>
      69                 :            : 
      70                 :            : #include <set>
      71                 :            : #include <math.h>
      72                 :            : #include <vcl/metric.hxx>
      73                 :            : #include <com/sun/star/i18n/ScriptType.hpp>
      74                 :            : #include <com/sun/star/text/CharacterCompressionType.hpp>
      75                 :            : #include <vcl/pdfextoutdevdata.hxx>
      76                 :            : #include <i18npool/mslangid.hxx>
      77                 :            : 
      78                 :            : #include <comphelper/processfactory.hxx>
      79                 :            : #include <rtl/ustrbuf.hxx>
      80                 :            : #include <comphelper/string.hxx>
      81                 :            : 
      82                 :            : using ::rtl::OUString;
      83                 :            : using namespace ::com::sun::star;
      84                 :            : using namespace ::com::sun::star::uno;
      85                 :            : using namespace ::com::sun::star::beans;
      86                 :            : using namespace ::com::sun::star::linguistic2;
      87                 :            : 
      88                 :            : #define CH_HYPH     '-'
      89                 :            : 
      90                 :            : #define RESDIFF     10
      91                 :            : 
      92                 :            : #define WRONG_SHOW_MIN       5
      93                 :            : #define WRONG_SHOW_SMALL    11
      94                 :            : #define WRONG_SHOW_MEDIUM   15
      95                 :            : 
      96                 :            : struct TabInfo
      97                 :            : {
      98                 :            :     sal_Bool        bValid;
      99                 :            : 
     100                 :            :     SvxTabStop  aTabStop;
     101                 :            :     xub_StrLen  nCharPos;
     102                 :            :     sal_uInt16      nTabPortion;
     103                 :            :     long        nStartPosX;
     104                 :            :     long        nTabPos;
     105                 :            : 
     106                 :     114343 :     TabInfo() { bValid = sal_False; }
     107                 :            : };
     108                 :            : 
     109                 :        680 : Point Rotate( const Point& rPoint, short nOrientation, const Point& rOrigin )
     110                 :            : {
     111                 :        680 :     double nRealOrientation = nOrientation*F_PI1800;
     112                 :        680 :     double nCos = cos( nRealOrientation );
     113                 :        680 :     double nSin = sin( nRealOrientation );
     114                 :            : 
     115                 :        680 :     Point aRotatedPos;
     116                 :        680 :     Point aTranslatedPos( rPoint );
     117                 :            : 
     118                 :            :     // Translation
     119                 :        680 :     aTranslatedPos -= rOrigin;
     120                 :            : 
     121                 :            :     // Rotation...
     122                 :        680 :     aRotatedPos.X() = (long)   ( nCos*aTranslatedPos.X() + nSin*aTranslatedPos.Y() );
     123                 :        680 :     aRotatedPos.Y() = (long) - ( nSin*aTranslatedPos.X() - nCos*aTranslatedPos.Y() );
     124                 :        680 :     aTranslatedPos = aRotatedPos;
     125                 :            : 
     126                 :            :     // Translation...
     127                 :        680 :     aTranslatedPos += rOrigin;
     128                 :        680 :     return aTranslatedPos;
     129                 :            : }
     130                 :            : 
     131                 :          0 : sal_uInt8 GetCharTypeForCompression( xub_Unicode cChar )
     132                 :            : {
     133      [ #  #  # ]:          0 :     switch ( cChar )
     134                 :            :     {
     135                 :            :         case 0x3008: case 0x300A: case 0x300C: case 0x300E:
     136                 :            :         case 0x3010: case 0x3014: case 0x3016: case 0x3018:
     137                 :            :         case 0x301A: case 0x301D:
     138                 :            :         {
     139                 :          0 :             return CHAR_PUNCTUATIONRIGHT;
     140                 :            :         }
     141                 :            :         case 0x3001: case 0x3002: case 0x3009: case 0x300B:
     142                 :            :         case 0x300D: case 0x300F: case 0x3011: case 0x3015:
     143                 :            :         case 0x3017: case 0x3019: case 0x301B: case 0x301E:
     144                 :            :         case 0x301F:
     145                 :            :         {
     146                 :          0 :             return CHAR_PUNCTUATIONLEFT;
     147                 :            :         }
     148                 :            :         default:
     149                 :            :         {
     150 [ #  # ][ #  # ]:          0 :             return ( ( 0x3040 <= cChar ) && ( 0x3100 > cChar ) ) ? CHAR_KANA : CHAR_NORMAL;
     151                 :            :         }
     152                 :            :     }
     153                 :            : }
     154                 :            : 
     155                 :        517 : void lcl_DrawRedLines(
     156                 :            :     OutputDevice* pOutDev,
     157                 :            :     long nFontHeight,
     158                 :            :     const Point& rPnt,
     159                 :            :     sal_uInt16 nIndex,
     160                 :            :     sal_uInt16 nMaxEnd,
     161                 :            :     const sal_Int32* pDXArray,
     162                 :            :     WrongList* pWrongs,
     163                 :            :     short nOrientation,
     164                 :            :     const Point& rOrigin,
     165                 :            :     sal_Bool bVertical,
     166                 :            :     sal_Bool bIsRightToLeft )
     167                 :            : {
     168                 :            :     // But only if font is not too small ...
     169         [ +  - ]:        517 :     long nHght = pOutDev->LogicToPixel( Size( 0, nFontHeight ) ).Height();
     170         [ +  - ]:        517 :     if( WRONG_SHOW_MIN < nHght )
     171                 :            :     {
     172                 :            :         sal_uInt16 nStyle;
     173         [ +  + ]:        517 :         if( WRONG_SHOW_MEDIUM < nHght )
     174                 :        431 :             nStyle = WAVE_NORMAL;
     175         [ +  - ]:         86 :         else if( WRONG_SHOW_SMALL < nHght )
     176                 :         86 :             nStyle = WAVE_SMALL;
     177                 :            :         else
     178                 :          0 :             nStyle = WAVE_FLAT;
     179                 :            : 
     180                 :        517 :         sal_uInt16 nEnd, nStart = nIndex;
     181         [ +  - ]:        517 :         sal_Bool bWrong = pWrongs->NextWrong( nStart, nEnd );
     182         [ +  + ]:       1034 :         while ( bWrong )
     183                 :            :         {
     184         [ +  - ]:        517 :             if ( nStart >= nMaxEnd )
     185                 :            :                 break;
     186                 :            : 
     187         [ +  + ]:        517 :             if ( nStart < nIndex )  // Corrected
     188                 :        248 :                 nStart = nIndex;
     189         [ +  + ]:        517 :             if ( nEnd > nMaxEnd )
     190                 :        248 :                 nEnd = nMaxEnd;
     191                 :        517 :             Point aPnt1( rPnt );
     192 [ -  + ][ #  # ]:        517 :             if ( bVertical && ( nStyle != WAVE_FLAT ) )
     193                 :            :             {
     194                 :            :                 // VCL doesn't know that the text is vertical, and is manipulating
     195                 :            :                 // the positions a little bit in y direction...
     196         [ #  # ]:          0 :                 long nOnePixel = pOutDev->PixelToLogic( Size( 0, 1 ) ).Height();
     197         [ #  # ]:          0 :                 long nCorrect = ( nStyle == WAVE_NORMAL ) ? 2*nOnePixel : nOnePixel;
     198                 :          0 :                 aPnt1.Y() -= nCorrect;
     199                 :          0 :                 aPnt1.X() -= nCorrect;
     200                 :            :             }
     201         [ +  + ]:        517 :             if ( nStart > nIndex )
     202                 :            :             {
     203         [ +  - ]:          1 :                 if ( !bVertical )
     204                 :            :                 {
     205                 :            :                     // since for RTL portions rPnt is on the visual right end of the portion
     206                 :            :                     // (i.e. at the start of the first RTL char) we need to subtract the offset
     207                 :            :                     // for RTL portions...
     208         [ -  + ]:          1 :                     aPnt1.X() += (bIsRightToLeft ? -1 : 1) * pDXArray[ nStart - nIndex - 1 ];
     209                 :            :                 }
     210                 :            :                 else
     211                 :          0 :                     aPnt1.Y() += pDXArray[ nStart - nIndex - 1 ];
     212                 :            :             }
     213                 :        517 :             Point aPnt2( rPnt );
     214                 :            :             DBG_ASSERT( nEnd > nIndex, "RedLine: aPnt2?" );
     215         [ +  - ]:        517 :             if ( !bVertical )
     216                 :            :             {
     217                 :            :                 // since for RTL portions rPnt is on the visual right end of the portion
     218                 :            :                 // (i.e. at the start of the first RTL char) we need to subtract the offset
     219                 :            :                 // for RTL portions...
     220         [ -  + ]:        517 :                 aPnt2.X() += (bIsRightToLeft ? -1 : 1) * pDXArray[ nEnd - nIndex - 1 ];
     221                 :            :             }
     222                 :            :             else
     223                 :          0 :                 aPnt2.Y() += pDXArray[ nEnd - nIndex - 1 ];
     224         [ +  + ]:        517 :             if ( nOrientation )
     225                 :            :             {
     226                 :        340 :                 aPnt1 = Rotate( aPnt1, nOrientation, rOrigin );
     227                 :        340 :                 aPnt2 = Rotate( aPnt2, nOrientation, rOrigin );
     228                 :            :             }
     229                 :            : 
     230         [ +  - ]:        517 :             pOutDev->DrawWaveLine( aPnt1, aPnt2, nStyle );
     231                 :            : 
     232                 :        517 :             nStart = nEnd+1;
     233         [ +  + ]:        517 :             if ( nEnd < nMaxEnd )
     234         [ +  - ]:          1 :                 bWrong = pWrongs->NextWrong( nStart, nEnd );
     235                 :            :             else
     236                 :        517 :                 bWrong = sal_False;
     237                 :            :         }
     238                 :            :     }
     239                 :        517 : }
     240                 :            : 
     241                 :       1390 : Point lcl_ImplCalcRotatedPos( Point rPos, Point rOrigin, double nSin, double nCos )
     242                 :            : {
     243                 :       1390 :     Point aRotatedPos;
     244                 :            :     // Translation...
     245                 :       1390 :     Point aTranslatedPos( rPos);
     246                 :       1390 :     aTranslatedPos -= rOrigin;
     247                 :            : 
     248                 :       1390 :     aRotatedPos.X() = (long)   ( nCos*aTranslatedPos.X() + nSin*aTranslatedPos.Y() );
     249                 :       1390 :     aRotatedPos.Y() = (long) - ( nSin*aTranslatedPos.X() - nCos*aTranslatedPos.Y() );
     250                 :       1390 :     aTranslatedPos = aRotatedPos;
     251                 :            :     // Translation...
     252                 :       1390 :     aTranslatedPos += rOrigin;
     253                 :            : 
     254                 :       1390 :     return aTranslatedPos;
     255                 :            : }
     256                 :            : 
     257                 :          0 : sal_Bool lcl_IsLigature( xub_Unicode cCh, xub_Unicode cNextCh ) // For Kashidas from sw/source/core/text/porlay.txt
     258                 :            : {
     259                 :            :             // Lam + Alef
     260                 :            :     return ( 0x644 == cCh && 0x627 == cNextCh ) ||
     261                 :            :             // Beh + Reh
     262 [ #  # ][ #  # ]:          0 :            ( 0x628 == cCh && 0x631 == cNextCh );
         [ #  # ][ #  # ]
     263                 :            : }
     264                 :            : 
     265                 :          0 : sal_Bool lcl_ConnectToPrev( xub_Unicode cCh, xub_Unicode cPrevCh )  // For Kashidas from sw/source/core/text/porlay.txt
     266                 :            : {
     267                 :            :     // Alef, Dal, Thal, Reh, Zain, and Waw do not connect to the left
     268                 :            :     sal_Bool bRet = 0x627 != cPrevCh && 0x62F != cPrevCh && 0x630 != cPrevCh &&
     269 [ #  # ][ #  # ]:          0 :                     0x631 != cPrevCh && 0x632 != cPrevCh && 0x648 != cPrevCh;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     270                 :            : 
     271                 :            :     // check for ligatures cPrevChar + cChar
     272         [ #  # ]:          0 :     if ( bRet )
     273                 :          0 :         bRet = ! lcl_IsLigature( cPrevCh, cCh );
     274                 :            : 
     275                 :          0 :     return bRet;
     276                 :            : }
     277                 :            : 
     278                 :            : 
     279                 :            : //  ----------------------------------------------------------------------
     280                 :            : //  class ImpEditEngine
     281                 :            : //  ----------------------------------------------------------------------
     282                 :    1248995 : void ImpEditEngine::UpdateViews( EditView* pCurView )
     283                 :            : {
     284 [ +  + ][ +  - ]:    1248995 :     if ( !GetUpdateMode() || IsFormatting() || aInvalidRec.IsEmpty() )
         [ +  + ][ +  + ]
     285                 :    1248995 :         return;
     286                 :            : 
     287                 :            :     DBG_ASSERT( IsFormatted(), "UpdateViews: Doc not formatted!" );
     288                 :            : 
     289         [ +  + ]:     315313 :     for (size_t nView = 0; nView < aEditViews.size(); ++nView)
     290                 :            :     {
     291                 :        423 :         EditView* pView = aEditViews[nView];
     292                 :            :         DBG_CHKOBJ( pView, EditView, 0 );
     293         [ +  - ]:        423 :         pView->HideCursor();
     294                 :            : 
     295                 :        423 :         Rectangle aClipRec( aInvalidRec );
     296         [ +  - ]:        423 :         Rectangle aVisArea( pView->GetVisArea() );
     297         [ +  - ]:        423 :         aClipRec.Intersection( aVisArea );
     298                 :            : 
     299 [ +  - ][ +  - ]:        423 :         if ( !aClipRec.IsEmpty() )
     300                 :            :         {
     301                 :            :             // convert to window coordinates ....
     302         [ +  - ]:        423 :             aClipRec = pView->pImpEditView->GetWindowPos( aClipRec );
     303                 :            : 
     304         [ +  + ]:        423 :             if ( pView == pCurView )
     305         [ +  - ]:        271 :                 Paint( pView->pImpEditView, aClipRec, sal_True );
     306                 :            :             else
     307 [ +  - ][ +  - ]:        152 :                 pView->GetWindow()->Invalidate( aClipRec );
     308                 :            :         }
     309                 :            :     }
     310                 :            : 
     311         [ +  + ]:     314890 :     if ( pCurView )
     312                 :            :     {
     313                 :        271 :         sal_Bool bGotoCursor = pCurView->pImpEditView->DoAutoScroll();
     314                 :        271 :         pCurView->ShowCursor( bGotoCursor );
     315                 :            :     }
     316                 :            : 
     317                 :     314890 :     aInvalidRec = Rectangle();
     318                 :     314890 :     CallStatusHdl();
     319                 :            : }
     320                 :            : 
     321                 :        836 : IMPL_LINK_NOARG(ImpEditEngine, OnlineSpellHdl)
     322                 :            : {
     323 [ +  - ][ +  + ]:        836 :     if ( !Application::AnyInput( VCL_INPUT_KEYBOARD ) && GetUpdateMode() && IsFormatted() )
         [ +  + ][ +  + ]
     324                 :          6 :         DoOnlineSpelling();
     325                 :            :     else
     326                 :        830 :         aOnlineSpellTimer.Start();
     327                 :            : 
     328                 :        836 :     return 0;
     329                 :            : }
     330                 :            : 
     331                 :          0 : IMPL_LINK_NOARG_INLINE_START(ImpEditEngine, IdleFormatHdl)
     332                 :            : {
     333                 :          0 :     aIdleFormatter.ResetRestarts();
     334                 :            : 
     335                 :            :     // #i97146# check if that view is still available
     336                 :            :     // else probably the idle format timer fired while we're already
     337                 :            :     // downing
     338                 :          0 :     EditView* pView = aIdleFormatter.GetView();
     339         [ #  # ]:          0 :     for (size_t nView = 0; nView < aEditViews.size(); ++nView)
     340                 :            :     {
     341         [ #  # ]:          0 :         if( aEditViews[nView] == pView )
     342                 :            :         {
     343                 :          0 :             FormatAndUpdate( pView );
     344                 :          0 :             break;
     345                 :            :         }
     346                 :            :     }
     347                 :          0 :     return 0;
     348                 :            : }
     349                 :          0 : IMPL_LINK_NOARG_INLINE_END(ImpEditEngine, IdleFormatHdl)
     350                 :            : 
     351                 :       1283 : void ImpEditEngine::CheckIdleFormatter()
     352                 :            : {
     353                 :       1283 :     aIdleFormatter.ForceTimeout();
     354                 :            :     // If not idle, but still not formatted:
     355         [ +  + ]:       1283 :     if ( !IsFormatted() )
     356                 :         46 :         FormatDoc();
     357                 :       1283 : }
     358                 :            : 
     359                 :     174236 : void ImpEditEngine::FormatFullDoc()
     360                 :            : {
     361         [ +  + ]:     348526 :     for ( sal_uInt16 nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ )
     362                 :     174290 :         GetParaPortions()[nPortion]->MarkSelectionInvalid( 0, GetParaPortions()[nPortion]->GetNode()->Len() );
     363                 :     174236 :     FormatDoc();
     364                 :     174236 : }
     365                 :            : 
     366                 :    1251241 : void ImpEditEngine::FormatDoc()
     367                 :            : {
     368 [ +  + ][ +  + ]:    1251241 :     if ( !GetUpdateMode() || IsFormatting() )
                 [ +  + ]
     369                 :    1251241 :         return;
     370                 :            : 
     371         [ +  - ]:     332033 :     EnterBlockNotifications();
     372                 :            : 
     373                 :     332033 :     bIsFormatting = true;
     374                 :            : 
     375                 :            :     // Then I can also start the spell-timer ...
     376         [ +  + ]:     332033 :     if ( GetStatus().DoOnlineSpelling() )
     377         [ +  - ]:      25043 :         StartOnlineSpellTimer();
     378                 :            : 
     379                 :     332033 :     long nY = 0;
     380                 :     332033 :     sal_Bool bGrow = sal_False;
     381                 :            : 
     382         [ +  - ]:     332033 :     Font aOldFont( GetRefDevice()->GetFont() );
     383                 :            : 
     384                 :            :     // Here already, so that not always in CreateLines...
     385         [ +  - ]:     332033 :     sal_Bool bMapChanged = ImpCheckRefMapMode();
     386                 :            : 
     387         [ +  - ]:     332033 :     aInvalidRec = Rectangle();  // make empty
     388 [ +  - ][ +  + ]:     674413 :     for ( sal_uInt16 nPara = 0; nPara < GetParaPortions().Count(); nPara++ )
     389                 :            :     {
     390         [ +  - ]:     342380 :         ParaPortion* pParaPortion = GetParaPortions()[nPara];
     391 [ +  - ][ +  + ]:     342380 :         if ( pParaPortion->MustRepaint() || ( pParaPortion->IsInvalid() && pParaPortion->IsVisible() ) )
         [ +  - ][ +  + ]
     392                 :            :         {
     393         [ +  - ]:     323744 :             if ( pParaPortion->IsInvalid() )
     394                 :            :             {
     395         [ +  - ]:     323744 :                 sal_Bool bChangedByDerivedClass = GetEditEnginePtr()->FormattingParagraph( nPara );
     396         [ -  + ]:     323744 :                 if ( bChangedByDerivedClass )
     397                 :            :                 {
     398         [ #  # ]:          0 :                     pParaPortion->GetTextPortions().Reset();
     399 [ #  # ][ #  # ]:          0 :                     pParaPortion->MarkSelectionInvalid( 0, pParaPortion->GetNode()->Len() );
     400                 :            :                 }
     401                 :            :             }
     402                 :            :             // No formatting should be necessary for MustRepaint()!
     403 [ -  + ][ #  # ]:     647488 :             if ( ( pParaPortion->MustRepaint() && !pParaPortion->IsInvalid() )
         [ +  + ][ +  + ]
     404         [ +  - ]:     323744 :                     || CreateLines( nPara, nY ) )
     405                 :            :             {
     406 [ +  + ][ -  + ]:     249795 :                 if ( !bGrow && GetTextRanger() )
                 [ -  + ]
     407                 :            :                 {
     408                 :            :                     // For a change in height all below must be reformatted ...
     409 [ #  # ][ #  # ]:          0 :                     for ( sal_uInt16 n = nPara+1; n < GetParaPortions().Count(); n++ )
     410                 :            :                     {
     411         [ #  # ]:          0 :                         ParaPortion* pPP = GetParaPortions()[n];
     412 [ #  # ][ #  # ]:          0 :                         pPP->MarkSelectionInvalid( 0, pPP->GetNode()->Len() );
     413         [ #  # ]:          0 :                         pPP->GetLines().Reset();
     414                 :            :                     }
     415                 :            :                 }
     416                 :     249795 :                 bGrow = sal_True;
     417         [ +  - ]:     249795 :                 if ( IsCallParaInsertedOrDeleted() )
     418         [ +  - ]:     249795 :                     GetEditEnginePtr()->ParagraphHeightChanged( nPara );
     419                 :     249795 :                 pParaPortion->SetMustRepaint( sal_False );
     420                 :            :             }
     421                 :            : 
     422                 :            :             // InvalidRec set only once...
     423 [ +  - ][ +  + ]:     323744 :             if ( aInvalidRec.IsEmpty() )
     424                 :            :             {
     425                 :            :                 // For Paperwidth 0 (AutoPageSize) it would otherwise be Empty()...
     426         [ +  - ]:     314936 :                 long nWidth = Max( (long)1, ( !IsVertical() ? aPaperSize.Width() : aPaperSize.Height() ) );
     427         [ +  - ]:     314936 :                 Range aInvRange( GetInvalidYOffsets( pParaPortion ) );
     428                 :     314936 :                 aInvalidRec = Rectangle( Point( 0, nY+aInvRange.Min() ),
     429         [ +  - ]:     629872 :                     Size( nWidth, aInvRange.Len() ) );
     430                 :            :             }
     431                 :            :             else
     432                 :            :             {
     433                 :       8808 :                 aInvalidRec.Bottom() = nY + pParaPortion->GetHeight();
     434                 :            :             }
     435                 :            :         }
     436         [ +  + ]:      18636 :         else if ( bGrow )
     437                 :            :         {
     438                 :         74 :             aInvalidRec.Bottom() = nY + pParaPortion->GetHeight();
     439                 :            :         }
     440                 :     342380 :         nY += pParaPortion->GetHeight();
     441                 :            :     }
     442                 :            : 
     443                 :            :     // One can also get into the formatting through UpdateMode ON=>OFF=>ON...
     444                 :            :     // enable optimization first after Vobis delivery ...
     445                 :            :     {
     446                 :            :         sal_uInt32 nNewHeightNTP;
     447         [ +  - ]:     332033 :         sal_uInt32 nNewHeight = CalcTextHeight( &nNewHeightNTP );
     448                 :     332033 :         long nDiff = nNewHeight - nCurTextHeight;
     449         [ +  + ]:     332033 :         if ( nDiff )
     450         [ +  - ]:     239154 :             aStatus.GetStatusWord() |= !IsVertical() ? EE_STAT_TEXTHEIGHTCHANGED : EE_STAT_TEXTWIDTHCHANGED;
     451         [ +  + ]:     332033 :         if ( nNewHeight < nCurTextHeight )
     452                 :            :         {
     453                 :        263 :             aInvalidRec.Bottom() = (long)Max( nNewHeight, nCurTextHeight );
     454 [ -  + ][ +  - ]:        263 :             if ( aInvalidRec.IsEmpty() )
     455                 :            :             {
     456                 :          0 :                 aInvalidRec.Top() = 0;
     457                 :            :                 // Left and Right are not evaluated, are however set due to IsEmpty.
     458                 :          0 :                 aInvalidRec.Left() = 0;
     459         [ #  # ]:          0 :                 aInvalidRec.Right() = !IsVertical() ? aPaperSize.Width() : aPaperSize.Height();
     460                 :            :             }
     461                 :            :         }
     462                 :            : 
     463                 :     332033 :         nCurTextHeight = nNewHeight;
     464                 :     332033 :         nCurTextHeightNTP = nNewHeightNTP;
     465                 :            : 
     466         [ +  + ]:     332033 :         if ( aStatus.AutoPageSize() )
     467         [ +  - ]:      27392 :             CheckAutoPageSize();
     468         [ +  + ]:     304641 :         else if ( nDiff )
     469                 :            :         {
     470         [ +  + ]:     212277 :             for (size_t nView = 0; nView < aEditViews.size(); ++nView)
     471                 :            :             {
     472                 :         80 :                 EditView* pView = aEditViews[nView];
     473                 :         80 :                 ImpEditView* pImpView = pView->pImpEditView;
     474         [ -  + ]:         80 :                 if ( pImpView->DoAutoHeight() )
     475                 :            :                 {
     476         [ #  # ]:          0 :                     Size aSz( pImpView->GetOutputArea().GetWidth(), nCurTextHeight );
     477         [ #  # ]:          0 :                     if ( aSz.Height() > aMaxAutoPaperSize.Height() )
     478                 :          0 :                         aSz.Height() = aMaxAutoPaperSize.Height();
     479         [ #  # ]:          0 :                     else if ( aSz.Height() < aMinAutoPaperSize.Height() )
     480                 :          0 :                         aSz.Height() = aMinAutoPaperSize.Height();
     481                 :            :                     pImpView->ResetOutputArea( Rectangle(
     482 [ #  # ][ #  # ]:          0 :                         pImpView->GetOutputArea().TopLeft(), aSz ) );
     483                 :            :                 }
     484                 :            :             }
     485                 :            :         }
     486                 :            :     }
     487                 :            : 
     488         [ -  + ]:     332033 :     if ( aStatus.DoRestoreFont() )
     489         [ #  # ]:          0 :         GetRefDevice()->SetFont( aOldFont );
     490                 :     332033 :     bIsFormatting = false;
     491                 :     332033 :     bFormatted = true;
     492                 :            : 
     493         [ -  + ]:     332033 :     if ( bMapChanged )
     494         [ #  # ]:          0 :         GetRefDevice()->Pop();
     495                 :            : 
     496         [ +  - ]:     332033 :     CallStatusHdl();    // If Modified...
     497                 :            : 
     498 [ +  - ][ +  - ]:    1251241 :     LeaveBlockNotifications();
     499                 :            : }
     500                 :            : 
     501                 :     446376 : sal_Bool ImpEditEngine::ImpCheckRefMapMode()
     502                 :            : {
     503                 :     446376 :     sal_Bool bChange = sal_False;
     504                 :            : 
     505         [ +  + ]:     446376 :     if ( aStatus.DoFormat100() )
     506                 :            :     {
     507         [ +  - ]:     441330 :         MapMode aMapMode( GetRefDevice()->GetMapMode() );
     508         [ -  + ]:     441330 :         if ( aMapMode.GetScaleX().GetNumerator() != aMapMode.GetScaleX().GetDenominator() )
     509                 :          0 :             bChange = sal_True;
     510         [ -  + ]:     441330 :         else if ( aMapMode.GetScaleY().GetNumerator() != aMapMode.GetScaleY().GetDenominator() )
     511                 :          0 :             bChange = sal_True;
     512                 :            : 
     513         [ -  + ]:     441330 :         if ( bChange )
     514                 :            :         {
     515         [ #  # ]:          0 :             Fraction Scale1( 1, 1 );
     516         [ #  # ]:          0 :             aMapMode.SetScaleX( Scale1 );
     517         [ #  # ]:          0 :             aMapMode.SetScaleY( Scale1 );
     518         [ #  # ]:          0 :             GetRefDevice()->Push();
     519         [ #  # ]:          0 :             GetRefDevice()->SetMapMode( aMapMode );
     520         [ +  - ]:     441330 :         }
     521                 :            :     }
     522                 :            : 
     523                 :     446376 :     return bChange;
     524                 :            : }
     525                 :            : 
     526                 :      27392 : void ImpEditEngine::CheckAutoPageSize()
     527                 :            : {
     528                 :      27392 :     Size aPrevPaperSize( GetPaperSize() );
     529         [ +  - ]:      27392 :     if ( GetStatus().AutoPageWidth() )
     530 [ +  - ][ +  - ]:      27392 :         aPaperSize.Width() = (long) !IsVertical() ? CalcTextWidth( sal_True ) : GetTextHeight();
                 [ #  # ]
     531         [ +  - ]:      27392 :     if ( GetStatus().AutoPageHeight() )
     532 [ +  - ][ +  - ]:      27392 :         aPaperSize.Height() = (long) !IsVertical() ? GetTextHeight() : CalcTextWidth( sal_True );
                 [ #  # ]
     533                 :            : 
     534         [ +  - ]:      27392 :     SetValidPaperSize( aPaperSize );    // consider Min, Max
     535                 :            : 
     536         [ +  + ]:      27392 :     if ( aPaperSize != aPrevPaperSize )
     537                 :            :     {
     538 [ +  - ][ +  +  :      31921 :         if ( ( !IsVertical() && ( aPaperSize.Width() != aPrevPaperSize.Width() ) )
             -  +  #  # ]
                 [ +  + ]
     539                 :       4562 :              || ( IsVertical() && ( aPaperSize.Height() != aPrevPaperSize.Height() ) ) )
     540                 :            :         {
     541                 :            :             // If ahead is centered / right or tabs ...
     542         [ +  - ]:      22797 :             aStatus.GetStatusWord() |= !IsVertical() ? EE_STAT_TEXTWIDTHCHANGED : EE_STAT_TEXTHEIGHTCHANGED;
     543 [ +  - ][ +  + ]:      45791 :             for ( sal_uInt16 nPara = 0; nPara < GetParaPortions().Count(); nPara++ )
     544                 :            :             {
     545                 :            :                 // Only paragraphs which are not aligned to the left need to be
     546                 :            :                 // reformatted, the height can not be changed here anymore.
     547         [ +  - ]:      22994 :                 ParaPortion* pParaPortion = GetParaPortions()[nPara];
     548                 :      22994 :                 ContentNode* pNode = pParaPortion->GetNode();
     549         [ +  - ]:      22994 :                 SvxAdjust eJustification = GetJustification( nPara );
     550         [ +  + ]:      22994 :                 if ( eJustification != SVX_ADJUST_LEFT )
     551                 :            :                 {
     552 [ +  - ][ +  - ]:        837 :                     pParaPortion->MarkSelectionInvalid( 0, pNode->Len() );
     553         [ +  - ]:        837 :                     CreateLines( nPara, 0 );  // 0: For AutoPageSize no TextRange!
     554                 :            :                 }
     555                 :            :             }
     556                 :            :         }
     557                 :            : 
     558                 :      27359 :         Size aInvSize = aPaperSize;
     559         [ -  + ]:      27359 :         if ( aPaperSize.Width() < aPrevPaperSize.Width() )
     560                 :          0 :             aInvSize.Width() = aPrevPaperSize.Width();
     561         [ +  + ]:      27359 :         if ( aPaperSize.Height() < aPrevPaperSize.Height() )
     562                 :      11066 :             aInvSize.Height() = aPrevPaperSize.Height();
     563                 :            : 
     564                 :      27359 :         Size aSz( aInvSize );
     565         [ -  + ]:      27359 :         if ( IsVertical() )
     566                 :            :         {
     567                 :          0 :             aSz.Width() = aInvSize.Height();
     568                 :          0 :             aSz.Height() = aInvSize.Width();
     569                 :            :         }
     570         [ +  - ]:      27359 :         aInvalidRec = Rectangle( Point(), aSz );
     571                 :            : 
     572                 :            : 
     573         [ -  + ]:      27359 :         for (size_t nView = 0; nView < aEditViews.size(); ++nView)
     574                 :            :         {
     575                 :          0 :             EditView* pView = aEditViews[nView];
     576         [ #  # ]:          0 :             pView->pImpEditView->RecalcOutputArea();
     577                 :            :         }
     578                 :            :     }
     579                 :      27392 : }
     580                 :            : 
     581                 :       2139 : static sal_Int32 ImplCalculateFontIndependentLineSpacing( const sal_Int32 nFontHeight )
     582                 :            : {
     583                 :       2139 :     return ( nFontHeight * 12 ) / 10;   // + 20%
     584                 :            : }
     585                 :            : 
     586                 :     324581 : sal_Bool ImpEditEngine::CreateLines( sal_uInt16 nPara, sal_uInt32 nStartPosY )
     587                 :            : {
     588         [ +  - ]:     324581 :     ParaPortion* pParaPortion = GetParaPortions()[nPara];
     589                 :            : 
     590                 :            :     // sal_Bool: Changes in the height of paragraph Yes / No - sal_True/sal_False
     591                 :            :     DBG_ASSERT( pParaPortion->GetNode(), "Portion without Node in CreateLines" );
     592                 :            :     DBG_ASSERT( pParaPortion->IsVisible(), "Invisible paragraphs not formatted!" );
     593                 :            :     DBG_ASSERT( pParaPortion->IsInvalid(), "CreateLines: Portion not invalid!" );
     594                 :            : 
     595         [ +  - ]:     324581 :     sal_Bool bProcessingEmptyLine = ( pParaPortion->GetNode()->Len() == 0 );
     596 [ +  - ][ +  + ]:     324581 :     sal_Bool bEmptyNodeWithPolygon = ( pParaPortion->GetNode()->Len() == 0 ) && GetTextRanger();
                 [ -  + ]
     597                 :            : 
     598                 :            :     // ---------------------------------------------------------------
     599                 :            :     // Fast special treatment for empty paragraphs ...
     600                 :            :     // ---------------------------------------------------------------
     601 [ +  - ][ +  + ]:     324581 :     if ( ( pParaPortion->GetNode()->Len() == 0 ) && !GetTextRanger() )
         [ +  - ][ +  + ]
     602                 :            :     {
     603                 :            :         // fast special treatment ...
     604 [ +  - ][ +  + ]:     210238 :         if ( pParaPortion->GetTextPortions().Count() )
     605         [ +  - ]:      72036 :             pParaPortion->GetTextPortions().Reset();
     606 [ +  - ][ +  + ]:     210238 :         if ( pParaPortion->GetLines().Count() )
     607         [ +  - ]:      72036 :             pParaPortion->GetLines().Reset();
     608         [ +  - ]:     210238 :         CreateAndInsertEmptyLine( pParaPortion, nStartPosY );
     609         [ +  - ]:     210238 :         return FinishCreateLines( pParaPortion );
     610                 :            :     }
     611                 :            : 
     612                 :            :     // ---------------------------------------------------------------
     613                 :            :     // Initialization ......
     614                 :            :     // ---------------------------------------------------------------
     615                 :            : 
     616                 :            :     // Always format for 100%:
     617         [ +  - ]:     114343 :     sal_Bool bMapChanged = ImpCheckRefMapMode();
     618                 :            : 
     619 [ +  - ][ +  + ]:     114343 :     if ( pParaPortion->GetLines().Count() == 0 )
     620                 :            :     {
     621 [ +  - ][ +  - ]:     110559 :         EditLine* pL = new EditLine;
     622         [ +  - ]:     110559 :         pParaPortion->GetLines().Append(pL);
     623                 :            :     }
     624                 :            : 
     625                 :            :     // ---------------------------------------------------------------
     626                 :            :     // Get Paragraph attributes  ......
     627                 :            :     // ---------------------------------------------------------------
     628                 :     114343 :     ContentNode* const pNode = pParaPortion->GetNode();
     629                 :            : 
     630         [ +  - ]:     114343 :     sal_Bool bRightToLeftPara = IsRightToLeft( nPara );
     631                 :            : 
     632         [ +  - ]:     114343 :     SvxAdjust eJustification = GetJustification( nPara );
     633         [ +  - ]:     114343 :     sal_Bool bHyphenatePara = ((const SfxBoolItem&)pNode->GetContentAttribs().GetItem( EE_PARA_HYPHENATE )).GetValue();
     634                 :     114343 :     sal_Int32 nSpaceBefore      = 0;
     635                 :     114343 :     sal_Int32 nMinLabelWidth    = 0;
     636         [ +  - ]:     114343 :     sal_Int32 nSpaceBeforeAndMinLabelWidth = GetSpaceBeforeAndMinLabelWidth( pNode, &nSpaceBefore, &nMinLabelWidth );
     637         [ +  - ]:     114343 :     const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( pNode );
     638         [ +  - ]:     114343 :     const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&) pNode->GetContentAttribs().GetItem( EE_PARA_SBL );
     639         [ +  - ]:     114343 :     const sal_Bool bScriptSpace = ((const SvxScriptSpaceItem&) pNode->GetContentAttribs().GetItem( EE_PARA_ASIANCJKSPACING )).GetValue();
     640                 :            : 
     641                 :     114343 :     const short nInvalidDiff = pParaPortion->GetInvalidDiff();
     642                 :     114343 :     const sal_uInt16 nInvalidStart = pParaPortion->GetInvalidPosStart();
     643                 :     114343 :     const sal_uInt16 nInvalidEnd =  nInvalidStart + Abs( nInvalidDiff );
     644                 :            : 
     645                 :     114343 :     sal_Bool bQuickFormat = sal_False;
     646 [ +  - ][ +  - ]:     114343 :     if ( !bEmptyNodeWithPolygon && !HasScriptType( nPara, i18n::ScriptType::COMPLEX ) )
         [ +  - ][ +  - ]
     647                 :            :     {
     648 [ +  + ][ +  + ]:     114399 :         if ( ( pParaPortion->IsSimpleInvalid() ) && ( nInvalidDiff > 0 ) &&
         [ +  - ][ +  + ]
     649 [ +  - ][ +  - ]:         56 :              ( pNode->GetString().Search( CH_FEATURE, nInvalidStart ) > nInvalidEnd ) )
     650                 :            :         {
     651                 :         56 :             bQuickFormat = sal_True;
     652                 :            :         }
     653 [ +  + ][ -  + ]:     114287 :         else if ( ( pParaPortion->IsSimpleInvalid() ) && ( nInvalidDiff < 0 ) )
                 [ -  + ]
     654                 :            :         {
     655                 :            :             // check if delete over the portion boundaries was done ...
     656                 :          0 :             sal_uInt16 nStart = nInvalidStart;  // DOUBLE !!!!!!!!!!!!!!!
     657                 :          0 :             sal_uInt16 nEnd = nStart - nInvalidDiff;  // negative
     658                 :          0 :             bQuickFormat = sal_True;
     659                 :          0 :             sal_uInt16 nPos = 0;
     660         [ #  # ]:          0 :             sal_uInt16 nPortions = pParaPortion->GetTextPortions().Count();
     661         [ #  # ]:          0 :             for ( sal_uInt16 nTP = 0; nTP < nPortions; nTP++ )
     662                 :            :             {
     663                 :            :                 // There must be no start / end in the deleted area.
     664         [ #  # ]:          0 :                 TextPortion* const pTP = pParaPortion->GetTextPortions()[ nTP ];
     665                 :          0 :                 nPos = nPos + pTP->GetLen();
     666 [ #  # ][ #  # ]:          0 :                 if ( ( nPos > nStart ) && ( nPos < nEnd ) )
     667                 :            :                 {
     668                 :          0 :                     bQuickFormat = sal_False;
     669                 :          0 :                     break;
     670                 :            :                 }
     671                 :            :             }
     672                 :            :         }
     673                 :            :     }
     674                 :            : 
     675                 :            :     // SW disables TEXT_LAYOUT_COMPLEX_DISABLED, so maybe I have to enable it...
     676                 :            : 
     677                 :            :     // Saving both layout mode and language (since I'm potentially changing both)
     678         [ +  - ]:     114343 :     GetRefDevice()->Push( PUSH_TEXTLAYOUTMODE|PUSH_TEXTLANGUAGE );
     679                 :            : 
     680         [ +  - ]:     114343 :     ImplInitLayoutMode( GetRefDevice(), nPara, 0xFFFF );
     681                 :            : 
     682                 :     114343 :     sal_uInt16 nRealInvalidStart = nInvalidStart;
     683                 :            : 
     684         [ -  + ]:     114343 :     if ( bEmptyNodeWithPolygon )
     685                 :            :     {
     686         [ #  # ]:          0 :         TextPortion* pDummyPortion = new TextPortion( 0 );
     687         [ #  # ]:          0 :         pParaPortion->GetTextPortions().Reset();
     688         [ #  # ]:          0 :         pParaPortion->GetTextPortions().Append(pDummyPortion);
     689                 :            :     }
     690         [ +  + ]:     114343 :     else if ( bQuickFormat )
     691                 :            :     {
     692                 :            :         // faster Method:
     693         [ +  - ]:         56 :         RecalcTextPortion( pParaPortion, nInvalidStart, nInvalidDiff );
     694                 :            :     }
     695                 :            :     else    // nRealInvalidStart can be before InvalidStart, since Portions were deleted....
     696                 :            :     {
     697         [ +  - ]:     114287 :         CreateTextPortions( pParaPortion, nRealInvalidStart );
     698                 :            :     }
     699                 :            : 
     700                 :            : 
     701                 :            :     // ---------------------------------------------------------------
     702                 :            :     // Search for line with InvalidPos, start one line before
     703                 :            :     // Flag the line => do not remove it !
     704                 :            :     // ---------------------------------------------------------------
     705                 :            : 
     706         [ +  - ]:     114343 :     sal_uInt16 nLine = pParaPortion->GetLines().Count()-1;
     707         [ +  + ]:     225507 :     for ( sal_uInt16 nL = 0; nL <= nLine; nL++ )
     708                 :            :     {
     709         [ +  - ]:     114343 :         EditLine* pLine = pParaPortion->GetLines()[nL];
     710         [ +  + ]:     114343 :         if ( pLine->GetEnd() > nRealInvalidStart )  // not nInvalidStart!
     711                 :            :         {
     712                 :       3179 :             nLine = nL;
     713                 :       3179 :             break;
     714                 :            :         }
     715                 :     111164 :         pLine->SetValid();
     716                 :            :     }
     717                 :            :     // Begin one line before...
     718                 :            :     // If it is typed at the end, the line in front cannot change.
     719 [ -  + ][ #  # ]:     114343 :     if ( nLine && ( !pParaPortion->IsSimpleInvalid() || ( nInvalidEnd < pNode->Len() ) || ( nInvalidDiff <= 0 ) ) )
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
     720                 :          0 :         nLine--;
     721                 :            : 
     722         [ +  - ]:     114343 :     EditLine* pLine = pParaPortion->GetLines()[nLine];
     723                 :            : 
     724 [ +  + ][ +  - ]:     114343 :     static Rectangle aZeroArea = Rectangle( Point(), Point() );
         [ +  - ][ #  # ]
     725                 :     114343 :     Rectangle aBulletArea( aZeroArea );
     726         [ +  - ]:     114343 :     if ( !nLine )
     727                 :            :     {
     728 [ +  - ][ +  - ]:     114343 :         aBulletArea = GetEditEnginePtr()->GetBulletArea( GetParaPortions().GetPos( pParaPortion ) );
     729         [ +  + ]:     114343 :         if ( aBulletArea.Right() > 0 )
     730                 :       2008 :             pParaPortion->SetBulletX( (sal_uInt16) GetXValue( aBulletArea.Right() ) );
     731                 :            :         else
     732                 :     112335 :             pParaPortion->SetBulletX( 0 ); // if Bullet is set incorrectly
     733                 :            :     }
     734                 :            : 
     735                 :            :     // ---------------------------------------------------------------
     736                 :            :     // Reformat all lines from here ...
     737                 :            :     // ---------------------------------------------------------------
     738                 :     114343 :     sal_uInt16 nDelFromLine = 0xFFFF;
     739                 :     114343 :     sal_Bool bLineBreak = sal_False;
     740                 :            : 
     741                 :     114343 :     sal_uInt16 nIndex = pLine->GetStart();
     742         [ +  - ]:     114343 :     EditLine aSaveLine( *pLine );
     743         [ +  - ]:     114343 :     SvxFont aTmpFont( pNode->GetCharAttribs().GetDefFont() );
     744                 :            : 
     745                 :     114343 :     sal_Bool bCalcCharPositions = sal_True;
     746 [ +  - ][ +  - ]:     114343 :     sal_Int32* pBuf = new sal_Int32[ pNode->Len() ];
     747                 :            : 
     748                 :     114343 :     sal_Bool bSameLineAgain = sal_False;    // For TextRanger, if the height changes.
     749         [ +  - ]:     114343 :     TabInfo aCurrentTab;
     750                 :            : 
     751                 :     114343 :     sal_Bool bForceOneRun = bEmptyNodeWithPolygon;
     752                 :     114343 :     sal_Bool bCompressedChars = sal_False;
     753                 :            : 
     754 [ +  - ][ +  + ]:     322895 :     while ( ( nIndex < pNode->Len() ) || bForceOneRun )
         [ -  + ][ +  + ]
     755                 :            :     {
     756                 :     208554 :         bForceOneRun = sal_False;
     757                 :            : 
     758                 :     208554 :         sal_Bool bEOL = sal_False;
     759                 :     208554 :         sal_Bool bEOC = sal_False;
     760                 :     208554 :         sal_uInt16 nPortionStart = 0;
     761                 :     208554 :         sal_uInt16 nPortionEnd = 0;
     762                 :            : 
     763                 :     208554 :         long nStartX = GetXValue( rLRItem.GetTxtLeft() + nSpaceBeforeAndMinLabelWidth );
     764         [ +  + ]:     208554 :         if ( nIndex == 0 )
     765                 :            :         {
     766                 :     114343 :             long nFI = GetXValue( rLRItem.GetTxtFirstLineOfst() );
     767                 :     114343 :             nStartX += nFI;
     768                 :            : 
     769 [ +  + ][ +  + ]:     114343 :             if ( !nLine && ( pParaPortion->GetBulletX() > nStartX ) )
                 [ +  - ]
     770                 :            :             {
     771                 :        175 :                     nStartX = pParaPortion->GetBulletX();
     772                 :            :             }
     773                 :            :         }
     774                 :            : 
     775                 :            :         long nMaxLineWidth;
     776         [ +  - ]:     208554 :         if ( !IsVertical() )
     777         [ +  + ]:     208554 :             nMaxLineWidth = aStatus.AutoPageWidth() ? aMaxAutoPaperSize.Width() : aPaperSize.Width();
     778                 :            :         else
     779         [ #  # ]:          0 :             nMaxLineWidth = aStatus.AutoPageHeight() ? aMaxAutoPaperSize.Height() : aPaperSize.Height();
     780                 :            : 
     781                 :     208554 :         nMaxLineWidth -= GetXValue( rLRItem.GetRight() );
     782                 :     208554 :         nMaxLineWidth -= nStartX;
     783                 :            : 
     784                 :            :         // If PaperSize == long_max, one cannot take away any negative
     785                 :            :         // first line indent. (Overflow)
     786 [ #  # ][ -  + ]:     208554 :         if ( ( nMaxLineWidth < 0 ) && ( nStartX < 0 ) )
     787         [ #  # ]:          0 :             nMaxLineWidth = ( !IsVertical() ? aPaperSize.Width() : aPaperSize.Height() ) - GetXValue( rLRItem.GetRight() );
     788                 :            : 
     789                 :            :         // If still less than 0, it may be just the right edge.
     790         [ -  + ]:     208554 :         if ( nMaxLineWidth <= 0 )
     791                 :          0 :             nMaxLineWidth = 1;
     792                 :            : 
     793                 :            :         // Problem:
     794                 :            :         // Since formatting starts a line _before_ the invalid position,
     795                 :            :      // the positions unfortunately have to be redefined ...
     796                 :            :         // Solution:
     797                 :            :         // The line before can only become longer, not smaller
     798                 :            :         // => ...
     799         [ +  - ]:     208554 :         if ( bCalcCharPositions )
     800         [ +  - ]:     208554 :             pLine->GetCharPosArray().clear();
     801                 :            : 
     802                 :     208554 :         sal_uInt16 nTmpPos = nIndex;
     803                 :     208554 :         sal_uInt16 nTmpPortion = pLine->GetStartPortion();
     804                 :     208554 :         long nTmpWidth = 0;
     805                 :     208554 :         long nXWidth = nMaxLineWidth;
     806         [ -  + ]:     208554 :         if ( nXWidth <= nTmpWidth ) // while has to be looped once
     807                 :          0 :             nXWidth = nTmpWidth+1;
     808                 :            : 
     809                 :     208554 :         LongDqPtr pTextRanges = 0;
     810                 :     208554 :         long nTextExtraYOffset = 0;
     811                 :     208554 :         long nTextXOffset = 0;
     812                 :     208554 :         long nTextLineHeight = 0;
     813         [ -  + ]:     208554 :         if ( GetTextRanger() )
     814                 :            :         {
     815         [ #  # ]:          0 :             GetTextRanger()->SetVertical( IsVertical() );
     816                 :            : 
     817         [ #  # ]:          0 :             long nTextY = nStartPosY + GetEditCursor( pParaPortion, pLine->GetStart() ).Top();
     818         [ #  # ]:          0 :             if ( !bSameLineAgain )
     819                 :            :             {
     820         [ #  # ]:          0 :                 SeekCursor( pNode, nTmpPos+1, aTmpFont );
     821         [ #  # ]:          0 :                 aTmpFont.SetPhysFont( GetRefDevice() );
     822         [ #  # ]:          0 :                 ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
     823                 :            : 
     824         [ #  # ]:          0 :                 if ( IsFixedCellHeight() )
     825         [ #  # ]:          0 :                     nTextLineHeight = ImplCalculateFontIndependentLineSpacing( aTmpFont.GetHeight() );
     826                 :            :                 else
     827 [ #  # ][ #  # ]:          0 :                     nTextLineHeight = aTmpFont.GetPhysTxtSize( GetRefDevice(), String() ).Height();
                 [ #  # ]
     828                 :            :                 // Metrics can be greater
     829                 :          0 :                 FormatterFontMetric aTempFormatterMetrics;
     830         [ #  # ]:          0 :                 RecalcFormatterFontMetrics( aTempFormatterMetrics, aTmpFont );
     831                 :          0 :                 sal_uInt16 nLineHeight = aTempFormatterMetrics.GetHeight();
     832         [ #  # ]:          0 :                 if ( nLineHeight > nTextLineHeight )
     833                 :          0 :                     nTextLineHeight = nLineHeight;
     834                 :            :             }
     835                 :            :             else
     836                 :          0 :                 nTextLineHeight = pLine->GetHeight();
     837                 :            : 
     838                 :          0 :             nXWidth = 0;
     839         [ #  # ]:          0 :             while ( !nXWidth )
     840                 :            :             {
     841                 :          0 :                 long nYOff = nTextY + nTextExtraYOffset;
     842                 :          0 :                 long nYDiff = nTextLineHeight;
     843         [ #  # ]:          0 :                 if ( IsVertical() )
     844                 :            :                 {
     845         [ #  # ]:          0 :                     long nMaxPolygonX = GetTextRanger()->GetBoundRect().Right();
     846                 :          0 :                     nYOff = nMaxPolygonX-nYOff;
     847                 :          0 :                     nYDiff = -nTextLineHeight;
     848                 :            :                 }
     849         [ #  # ]:          0 :                 pTextRanges = GetTextRanger()->GetTextRanges( Range( nYOff, nYOff + nYDiff ) );
     850                 :            :                 DBG_ASSERT( pTextRanges, "GetTextRanges?!" );
     851                 :          0 :                 long nMaxRangeWidth = 0;
     852                 :            :                 // Use the widest range ...
     853                 :            :                 // The widest range could be a bit confusing, so normally it
     854                 :            :                 // is the first one. Best with gaps.
     855         [ #  # ]:          0 :                 if ( pTextRanges->size() )
     856                 :            :                 {
     857                 :          0 :                     sal_uInt16 n = 0;
     858         [ #  # ]:          0 :                     long nA = pTextRanges->at(n++);
     859         [ #  # ]:          0 :                     long nB = pTextRanges->at(n++);
     860                 :            :                     DBG_ASSERT( nA <= nB, "TextRange distorted?" );
     861                 :          0 :                     long nW = nB - nA;
     862         [ #  # ]:          0 :                     if ( nW > nMaxRangeWidth )
     863                 :            :                     {
     864                 :          0 :                         nMaxRangeWidth = nW;
     865                 :          0 :                         nTextXOffset = nA;
     866                 :            :                     }
     867                 :            :                 }
     868                 :          0 :                 nXWidth = nMaxRangeWidth;
     869         [ #  # ]:          0 :                 if ( nXWidth )
     870                 :          0 :                     nMaxLineWidth = nXWidth - nStartX - GetXValue( rLRItem.GetRight() );
     871                 :            :                 else
     872                 :            :                 {
     873                 :            :                     // Try further down in the polygon.
     874                 :            :                     // Below the polygon use the Paper Width.
     875                 :          0 :                     nTextExtraYOffset += Max( (long)(nTextLineHeight / 10), (long)1 );
     876 [ #  # ][ #  # ]:          0 :                     if ( ( nTextY + nTextExtraYOffset  ) > GetTextRanger()->GetBoundRect().Bottom() )
     877                 :            :                     {
     878         [ #  # ]:          0 :                         nXWidth = !IsVertical() ? GetPaperSize().Width() : GetPaperSize().Height();
     879         [ #  # ]:          0 :                         if ( !nXWidth ) // AutoPaperSize
     880                 :          0 :                             nXWidth = 0x7FFFFFFF;
     881                 :            :                     }
     882                 :            :                 }
     883                 :            :             }
     884                 :            :         }
     885                 :            : 
     886                 :            :         // search for Portion that no longer fits in line ....
     887                 :     208554 :         TextPortion* pPortion = 0;
     888                 :     208554 :         sal_Bool bBrokenLine = sal_False;
     889                 :     208554 :         bLineBreak = sal_False;
     890         [ +  - ]:     208554 :         const EditCharAttrib* pNextFeature = pNode->GetCharAttribs().FindFeature( pLine->GetStart() );
     891 [ +  + ][ +  + ]:     418793 :         while ( ( nTmpWidth < nXWidth ) && !bEOL && ( nTmpPortion < pParaPortion->GetTextPortions().Count() ) )
         [ +  - ][ +  + ]
                 [ +  + ]
     892                 :            :         {
     893                 :     210239 :             nPortionStart = nTmpPos;
     894         [ +  - ]:     210239 :             pPortion = pParaPortion->GetTextPortions()[nTmpPortion];
     895         [ -  + ]:     210239 :             if ( pPortion->GetKind() == PORTIONKIND_HYPHENATOR )
     896                 :            :             {
     897                 :            :                 // Throw away a Portion, if necessary correct the one before,
     898                 :            :                 // if the Hyph portion has swallowed a character ...
     899                 :          0 :                 sal_uInt16 nTmpLen = pPortion->GetLen();
     900         [ #  # ]:          0 :                 pParaPortion->GetTextPortions().Remove( nTmpPortion );
     901 [ #  # ][ #  # ]:          0 :                 if (nTmpPortion && nTmpLen)
     902                 :            :                 {
     903                 :          0 :                     nTmpPortion--;
     904         [ #  # ]:          0 :                     TextPortion* pPrev = pParaPortion->GetTextPortions()[nTmpPortion];
     905                 :            :                     DBG_ASSERT( pPrev->GetKind() == PORTIONKIND_TEXT, "Portion?!" );
     906                 :          0 :                     nTmpWidth -= pPrev->GetSize().Width();
     907                 :          0 :                     nTmpPos = nTmpPos - pPrev->GetLen();
     908                 :          0 :                     pPrev->SetLen(pPrev->GetLen() + nTmpLen);
     909                 :          0 :                     pPrev->GetSize().Width() = (-1);
     910                 :            :                 }
     911                 :            : 
     912                 :            :                 DBG_ASSERT( nTmpPortion < pParaPortion->GetTextPortions().Count(), "No more Portions left!" );
     913         [ #  # ]:          0 :                 pPortion = pParaPortion->GetTextPortions()[nTmpPortion];
     914                 :            :             }
     915                 :            :             DBG_ASSERT( pPortion->GetKind() != PORTIONKIND_HYPHENATOR, "CreateLines: Hyphenator-Portion!" );
     916                 :            :             DBG_ASSERT( pPortion->GetLen() || bProcessingEmptyLine, "Empty Portion in CreateLines ?!" );
     917                 :            :             (void)bProcessingEmptyLine;
     918 [ +  + ][ +  + ]:     210239 :             if ( pNextFeature && ( pNextFeature->GetStart() == nTmpPos ) )
                 [ +  + ]
     919                 :            :             {
     920                 :       3366 :                 sal_uInt16 nWhich = pNextFeature->GetItem()->Which();
     921   [ -  +  +  - ]:       3366 :                 switch ( nWhich )
     922                 :            :                 {
     923                 :            :                     case EE_FEATURE_TAB:
     924                 :            :                     {
     925                 :          0 :                         long nOldTmpWidth = nTmpWidth;
     926                 :            : 
     927                 :            :                         // Search for Tab-Pos...
     928                 :          0 :                         long nCurPos = nTmpWidth+nStartX;
     929                 :            :                         // consider scaling
     930 [ #  # ][ #  # ]:          0 :                         if ( aStatus.DoStretch() && ( nStretchX != 100 ) )
                 [ #  # ]
     931         [ #  # ]:          0 :                             nCurPos = nCurPos*100/std::max(static_cast<sal_Int32>(nStretchX), static_cast<sal_Int32>(1));
     932                 :            : 
     933                 :          0 :                         short nAllSpaceBeforeText = static_cast< short >(rLRItem.GetTxtLeft()/* + rLRItem.GetTxtLeft()*/ + nSpaceBeforeAndMinLabelWidth);
     934         [ #  # ]:          0 :                         aCurrentTab.aTabStop = pNode->GetContentAttribs().FindTabStop( nCurPos - nAllSpaceBeforeText /*rLRItem.GetTxtLeft()*/, aEditDoc.GetDefTab() );
     935                 :          0 :                         aCurrentTab.nTabPos = GetXValue( (long) ( aCurrentTab.aTabStop.GetTabPos() + nAllSpaceBeforeText /*rLRItem.GetTxtLeft()*/ ) );
     936                 :          0 :                         aCurrentTab.bValid = sal_False;
     937                 :            : 
     938                 :            :                         // Switch direction in R2L para...
     939         [ #  # ]:          0 :                         if ( bRightToLeftPara )
     940                 :            :                         {
     941         [ #  # ]:          0 :                             if ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_RIGHT )
     942                 :          0 :                                 aCurrentTab.aTabStop.GetAdjustment() = SVX_TAB_ADJUST_LEFT;
     943         [ #  # ]:          0 :                             else if ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_LEFT )
     944                 :          0 :                                 aCurrentTab.aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT;
     945                 :            :                         }
     946                 :            : 
     947   [ #  #  #  #  :          0 :                         if ( ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_RIGHT ) ||
           #  # ][ #  # ]
     948                 :          0 :                              ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_CENTER ) ||
     949                 :          0 :                              ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_DECIMAL ) )
     950                 :            :                         {
     951                 :            :                             // For LEFT / DEFAULT this tab is not considered.
     952                 :          0 :                             aCurrentTab.bValid = sal_True;
     953                 :          0 :                             aCurrentTab.nStartPosX = nTmpWidth;
     954                 :          0 :                             aCurrentTab.nCharPos = nTmpPos;
     955                 :          0 :                             aCurrentTab.nTabPortion = nTmpPortion;
     956                 :            :                         }
     957                 :            : 
     958                 :          0 :                         pPortion->GetKind() = PORTIONKIND_TAB;
     959                 :          0 :                         pPortion->SetExtraValue( aCurrentTab.aTabStop.GetFill() );
     960                 :          0 :                         pPortion->GetSize().Width() = aCurrentTab.nTabPos - (nTmpWidth+nStartX);
     961                 :            : 
     962                 :            :                         // Height needed...
     963         [ #  # ]:          0 :                         SeekCursor( pNode, nTmpPos+1, aTmpFont );
     964 [ #  # ][ #  # ]:          0 :                         pPortion->GetSize().Height() = aTmpFont.QuickGetTextSize( GetRefDevice(), String(), 0, 0, NULL ).Height();
                 [ #  # ]
     965                 :            : 
     966                 :            :                         DBG_ASSERT( pPortion->GetSize().Width() >= 0, "Tab incorrectly calculated!" );
     967                 :            : 
     968                 :          0 :                         nTmpWidth = aCurrentTab.nTabPos-nStartX;
     969                 :            : 
     970                 :            :                         // If this is the first token on the line,
     971                 :            :                         // and nTmpWidth > aPaperSize.Width, => infinite loop!
     972 [ #  # ][ #  # ]:          0 :                         if ( ( nTmpWidth >= nXWidth ) && ( nTmpPortion == pLine->GetStartPortion() ) )
                 [ #  # ]
     973                 :            :                         {
     974                 :            :                             // What now?
     975                 :            :                             // make the tab fitting
     976                 :          0 :                             pPortion->GetSize().Width() = nXWidth-nOldTmpWidth;
     977                 :          0 :                             nTmpWidth = nXWidth-1;
     978                 :          0 :                             bEOL = sal_True;
     979                 :          0 :                             bBrokenLine = sal_True;
     980                 :            :                         }
     981         [ #  # ]:          0 :                         EditLine::CharPosArrayType& rArray = pLine->GetCharPosArray();
     982                 :          0 :                         size_t nPos = nTmpPos - pLine->GetStart();
     983 [ #  # ][ #  # ]:          0 :                         rArray.insert(rArray.begin()+nPos, pPortion->GetSize().Width());
     984                 :          0 :                         bCompressedChars = sal_False;
     985                 :            :                     }
     986                 :          0 :                     break;
     987                 :            :                     case EE_FEATURE_LINEBR:
     988                 :            :                     {
     989                 :            :                         DBG_ASSERT( pPortion, "?!" );
     990                 :         31 :                         pPortion->GetSize().Width() = 0;
     991                 :         31 :                         bEOL = sal_True;
     992                 :         31 :                         bLineBreak = sal_True;
     993                 :         31 :                         pPortion->GetKind() = PORTIONKIND_LINEBREAK;
     994                 :         31 :                         bCompressedChars = sal_False;
     995         [ +  - ]:         31 :                         EditLine::CharPosArrayType& rArray = pLine->GetCharPosArray();
     996                 :         31 :                         size_t nPos = nTmpPos - pLine->GetStart();
     997 [ +  - ][ +  - ]:         31 :                         rArray.insert(rArray.begin()+nPos, pPortion->GetSize().Width());
     998                 :            :                     }
     999                 :         31 :                     break;
    1000                 :            :                     case EE_FEATURE_FIELD:
    1001                 :            :                     {
    1002         [ +  - ]:       3335 :                         SeekCursor( pNode, nTmpPos+1, aTmpFont );
    1003                 :       3335 :                         sal_Unicode cChar = 0;  // later: NBS?
    1004         [ +  - ]:       3335 :                         aTmpFont.SetPhysFont( GetRefDevice() );
    1005         [ +  - ]:       3335 :                         ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
    1006                 :            : 
    1007 [ -  + ][ +  - ]:       3335 :                         rtl::OUString aFieldValue = cChar ? rtl::OUString(cChar) : ((EditCharAttribField*)pNextFeature)->GetFieldValue();
    1008 [ -  + ][ #  # ]:       3335 :                         if ( bCalcCharPositions || !pPortion->HasValidSize() )
                 [ +  - ]
    1009                 :            :                         {
    1010 [ +  - ][ +  - ]:       3335 :                             pPortion->GetSize() = aTmpFont.QuickGetTextSize( GetRefDevice(), aFieldValue, 0, aFieldValue.getLength(), 0 );
                 [ +  - ]
    1011                 :            :                             // So no scrolling for oversized fields
    1012         [ -  + ]:       3335 :                             if ( pPortion->GetSize().Width() > nXWidth )
    1013                 :            :                             {
    1014                 :          0 :                                 sal_Int32 nWidthOrg         = pPortion->GetSize().Width();
    1015                 :          0 :                                 sal_Int32 nChars            = aFieldValue.getLength();
    1016                 :          0 :                                 sal_Int32 nApproxWC         = nXWidth / ( nWidthOrg / nChars );
    1017                 :          0 :                                 ExtraPortionInfo *pExtraInfo= pPortion->GetExtraInfos();
    1018         [ #  # ]:          0 :                                 if( !nApproxWC ) nApproxWC++;
    1019         [ #  # ]:          0 :                                 if( pExtraInfo == NULL )
    1020                 :            :                                 {
    1021 [ #  # ][ #  # ]:          0 :                                     pExtraInfo = new ExtraPortionInfo();
    1022                 :          0 :                                     pExtraInfo->nOrgWidth = nXWidth;
    1023         [ #  # ]:          0 :                                     pPortion->SetExtraInfos( pExtraInfo );
    1024                 :            :                                 }
    1025                 :            :                                 else
    1026                 :            :                                 {
    1027                 :          0 :                                     pExtraInfo->lineBreaksList.clear();
    1028                 :            :                                 }
    1029                 :            : 
    1030                 :          0 :                                 pPortion->GetSize().Width() = nXWidth;
    1031                 :            : 
    1032         [ #  # ]:          0 :                                 while( nChars > 0 )
    1033                 :            :                                 {
    1034         [ #  # ]:          0 :                                     pExtraInfo->lineBreaksList.push_back( aFieldValue.getLength() - nChars );
    1035                 :          0 :                                     nChars -= nApproxWC;
    1036                 :            :                                 }
    1037                 :            :                             }
    1038                 :            :                         }
    1039                 :       3335 :                         nTmpWidth += pPortion->GetSize().Width();
    1040         [ +  - ]:       3335 :                         EditLine::CharPosArrayType& rArray = pLine->GetCharPosArray();
    1041                 :       3335 :                         size_t nPos = nTmpPos - pLine->GetStart();
    1042 [ +  - ][ +  - ]:       3335 :                         rArray.insert(rArray.begin()+nPos, pPortion->GetSize().Width());
    1043         [ -  + ]:       3335 :                         pPortion->GetKind() = cChar ? PORTIONKIND_TEXT : PORTIONKIND_FIELD;
    1044                 :            :                         // If this is the first token on the line,
    1045                 :            :                         // and nTmpWidth > aPaperSize.Width, => infinite loop!
    1046 [ +  + ][ -  + ]:       3335 :                         if ( ( nTmpWidth >= nXWidth ) && ( nTmpPortion == pLine->GetStartPortion() ) )
                 [ -  + ]
    1047                 :            :                         {
    1048                 :          0 :                             nTmpWidth = nXWidth-1;
    1049                 :          0 :                             bEOL = sal_True;
    1050                 :          0 :                             bBrokenLine = sal_True;
    1051                 :            :                         }
    1052                 :            :                         // Compression in Fields????
    1053                 :            :                         // I think this could be a little bit difficult and is not very usefull
    1054                 :       3335 :                         bCompressedChars = sal_False;
    1055                 :            :                     }
    1056                 :       3335 :                     break;
    1057                 :            :                     default:    OSL_FAIL( "What feature?" );
    1058                 :            :                 }
    1059         [ +  - ]:       3366 :                 pNextFeature = pNode->GetCharAttribs().FindFeature( pNextFeature->GetStart() + 1  );
    1060                 :            :             }
    1061                 :            :             else
    1062                 :            :             {
    1063                 :            :                 DBG_ASSERT( pPortion->GetLen() || bProcessingEmptyLine, "Empty Portion - Extra Space?!" );
    1064                 :            :                 (void)bProcessingEmptyLine;
    1065         [ +  - ]:     206873 :                 SeekCursor( pNode, nTmpPos+1, aTmpFont );
    1066         [ +  - ]:     206873 :                 aTmpFont.SetPhysFont( GetRefDevice() );
    1067         [ +  - ]:     206873 :                 ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
    1068                 :            : 
    1069 [ -  + ][ #  # ]:     206873 :                 if ( bCalcCharPositions || !pPortion->HasValidSize() )
                 [ +  - ]
    1070                 :            :                 {
    1071 [ +  - ][ +  - ]:     206873 :                     pPortion->GetSize() = aTmpFont.QuickGetTextSize( GetRefDevice(), pParaPortion->GetNode()->GetString(), nTmpPos, pPortion->GetLen(), pBuf );
    1072                 :            : 
    1073                 :            :                     // #i9050# Do Kerning also behind portions...
    1074 [ +  + ][ +  - ]:     206873 :                     if ( ( aTmpFont.GetFixKerning() > 0 ) && ( ( nTmpPos + pPortion->GetLen() ) < pNode->Len() ) )
         [ -  + ][ -  + ]
    1075                 :          0 :                         pPortion->GetSize().Width() += aTmpFont.GetFixKerning();
    1076         [ +  + ]:     206873 :                     if ( IsFixedCellHeight() )
    1077         [ +  - ]:        351 :                         pPortion->GetSize().Height() = ImplCalculateFontIndependentLineSpacing( aTmpFont.GetHeight() );
    1078                 :            :                 }
    1079         [ +  - ]:     206873 :                 if ( bCalcCharPositions )
    1080                 :            :                 {
    1081                 :     206873 :                     sal_uInt16 nLen = pPortion->GetLen();
    1082                 :            :                     // The array is  generally flattened at the beginning
    1083                 :            :                     // => Always simply quick inserts.
    1084                 :     206873 :                     size_t nPos = nTmpPos - pLine->GetStart();
    1085         [ +  - ]:     206873 :                     EditLine::CharPosArrayType& rArray = pLine->GetCharPosArray();
    1086 [ +  - ][ +  - ]:     206873 :                     rArray.insert(rArray.begin()+nPos, pBuf, pBuf+nLen);
    1087                 :            :                 }
    1088                 :            : 
    1089                 :            :                 // And now check for Compression:
    1090 [ +  - ][ -  + ]:     206873 :                 if ( pPortion->GetLen() && GetAsianCompressionMode() )
                 [ -  + ]
    1091                 :            :                 {
    1092         [ #  # ]:          0 :                     EditLine::CharPosArrayType& rArray = pLine->GetCharPosArray();
    1093         [ #  # ]:          0 :                     sal_Int32* pDXArray = &rArray[0] + nTmpPos - pLine->GetStart();
    1094                 :            :                     bCompressedChars |= ImplCalcAsianCompression(
    1095         [ #  # ]:          0 :                         pNode, pPortion, nTmpPos, pDXArray, 10000, false);
    1096                 :            :                 }
    1097                 :            : 
    1098                 :     206873 :                 nTmpWidth += pPortion->GetSize().Width();
    1099                 :            : 
    1100         [ +  - ]:     206873 :                 pPortion->SetRightToLeft( GetRightToLeft( nPara, nTmpPos+1 ) );
    1101                 :            : 
    1102                 :     206873 :                 sal_uInt16 _nPortionEnd = nTmpPos + pPortion->GetLen();
    1103 [ +  - ][ +  + ]:     206873 :                 if( bScriptSpace && ( _nPortionEnd < pNode->Len() ) && ( nTmpWidth < nXWidth ) && IsScriptChange( EditPaM( pNode, _nPortionEnd ) ) )
         [ +  + ][ +  - ]
         [ +  - ][ +  + ]
                 [ +  + ]
           [ +  +  #  # ]
                 [ +  + ]
    1104                 :            :                 {
    1105                 :         16 :                     sal_Bool bAllow = sal_False;
    1106 [ +  - ][ +  - ]:         16 :                     sal_uInt16 nScriptTypeLeft = GetScriptType( EditPaM( pNode, _nPortionEnd ) );
    1107 [ +  - ][ +  - ]:         16 :                     sal_uInt16 nScriptTypeRight = GetScriptType( EditPaM( pNode, _nPortionEnd+1 ) );
    1108 [ +  - ][ -  + ]:         16 :                     if ( ( nScriptTypeLeft == i18n::ScriptType::ASIAN ) || ( nScriptTypeRight == i18n::ScriptType::ASIAN ) )
    1109                 :          0 :                         bAllow = sal_True;
    1110                 :            : 
    1111                 :            :                     // No spacing within L2R/R2L nesting
    1112         [ -  + ]:         16 :                     if ( bAllow )
    1113                 :            :                     {
    1114                 :          0 :                         long nExtraSpace = pPortion->GetSize().Height()/5;
    1115                 :          0 :                         nExtraSpace = GetXValue( nExtraSpace );
    1116                 :          0 :                         pPortion->GetSize().Width() += nExtraSpace;
    1117                 :          0 :                         nTmpWidth += nExtraSpace;
    1118                 :            :                     }
    1119                 :            :                 }
    1120                 :            :             }
    1121                 :            : 
    1122 [ -  + ][ #  # ]:     210239 :             if ( aCurrentTab.bValid && ( nTmpPortion != aCurrentTab.nTabPortion ) )
    1123                 :            :             {
    1124                 :          0 :                 long nWidthAfterTab = 0;
    1125         [ #  # ]:          0 :                 for ( sal_uInt16 n = aCurrentTab.nTabPortion+1; n <= nTmpPortion; n++  )
    1126                 :            :                 {
    1127         [ #  # ]:          0 :                     const TextPortion* pTP = pParaPortion->GetTextPortions()[n];
    1128                 :          0 :                     nWidthAfterTab += pTP->GetSize().Width();
    1129                 :            :                 }
    1130                 :          0 :                 long nW = nWidthAfterTab;   // Length before tab position
    1131         [ #  # ]:          0 :                 if ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_RIGHT )
    1132                 :            :                 {
    1133                 :            :                 }
    1134         [ #  # ]:          0 :                 else if ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_CENTER )
    1135                 :            :                 {
    1136                 :          0 :                     nW = nWidthAfterTab/2;
    1137                 :            :                 }
    1138         [ #  # ]:          0 :                 else if ( aCurrentTab.aTabStop.GetAdjustment() == SVX_TAB_ADJUST_DECIMAL )
    1139                 :            :                 {
    1140                 :            :                     String aText = GetSelected( EditSelection(  EditPaM( pParaPortion->GetNode(), nTmpPos ),
    1141 [ #  # ][ #  # ]:          0 :                                                                 EditPaM( pParaPortion->GetNode(), nTmpPos + pPortion->GetLen() ) ) );
         [ #  # ][ #  # ]
    1142 [ #  # ][ #  # ]:          0 :                     sal_uInt16 nDecPos = aText.Search( aCurrentTab.aTabStop.GetDecimal() );
    1143         [ #  # ]:          0 :                     if ( nDecPos != STRING_NOTFOUND )
    1144                 :            :                     {
    1145         [ #  # ]:          0 :                         nW -= pParaPortion->GetTextPortions()[nTmpPortion]->GetSize().Width();
    1146 [ #  # ][ #  # ]:          0 :                         nW += aTmpFont.QuickGetTextSize( GetRefDevice(), pParaPortion->GetNode()->GetString(), nTmpPos, nDecPos, NULL ).Width();
    1147                 :          0 :                         aCurrentTab.bValid = sal_False;
    1148         [ #  # ]:          0 :                     }
    1149                 :            :                 }
    1150                 :            :                 else
    1151                 :            :                 {
    1152                 :            :                     OSL_FAIL( "CreateLines: Tab not handled!" );
    1153                 :            :                 }
    1154                 :          0 :                 long nMaxW = aCurrentTab.nTabPos - aCurrentTab.nStartPosX - nStartX;
    1155         [ #  # ]:          0 :                 if ( nW >= nMaxW )
    1156                 :            :                 {
    1157                 :          0 :                     nW = nMaxW;
    1158                 :          0 :                     aCurrentTab.bValid = sal_False;
    1159                 :            :                 }
    1160         [ #  # ]:          0 :                 const TextPortion* pTabPortion = pParaPortion->GetTextPortions()[aCurrentTab.nTabPortion];
    1161                 :          0 :                 pTabPortion->GetSize().Width() = aCurrentTab.nTabPos - aCurrentTab.nStartPosX - nW - nStartX;
    1162                 :          0 :                 nTmpWidth = aCurrentTab.nStartPosX + pTabPortion->GetSize().Width() + nWidthAfterTab;
    1163                 :            :             }
    1164                 :            : 
    1165                 :     210239 :             nTmpPos = nTmpPos + pPortion->GetLen();
    1166                 :     210239 :             nPortionEnd = nTmpPos;
    1167                 :     210239 :             nTmpPortion++;
    1168         [ -  + ]:     210239 :             if ( aStatus.OneCharPerLine() )
    1169                 :          0 :                 bEOL = sal_True;
    1170                 :            :         }
    1171                 :            : 
    1172                 :            :         DBG_ASSERT( pPortion, "no portion!?" );
    1173                 :            : 
    1174                 :     208554 :         aCurrentTab.bValid = sal_False;
    1175                 :            : 
    1176                 :            :         // this was possibly a portion too far:
    1177                 :     208554 :         sal_Bool bFixedEnd = sal_False;
    1178         [ -  + ]:     208554 :         if ( aStatus.OneCharPerLine() )
    1179                 :            :         {
    1180                 :            :             // State before Portion (apart from nTmpWidth):
    1181                 :          0 :             nPortionEnd = nTmpPos;
    1182         [ #  # ]:          0 :             nTmpPos -= pPortion ? pPortion->GetLen() : 0;
    1183                 :          0 :             nPortionStart = nTmpPos;
    1184                 :          0 :             nTmpPortion--;
    1185                 :            : 
    1186                 :          0 :             bEOL = sal_True;
    1187                 :          0 :             bEOC = sal_False;
    1188                 :            : 
    1189                 :            :             // And now just one character:
    1190                 :          0 :             nTmpPos++;
    1191                 :          0 :             nTmpPortion++;
    1192                 :          0 :             nPortionEnd = nTmpPortion;
    1193                 :            :             // one Non-Feature-Portion has to be wrapped
    1194         [ #  # ]:          0 :             if ( pPortion->GetLen() > 1 )
    1195                 :            :             {
    1196                 :            :                 DBG_ASSERT( pPortion && (pPortion->GetKind() == PORTIONKIND_TEXT), "Len>1, but no TextPortion?" );
    1197         [ #  # ]:          0 :                 nTmpWidth -= pPortion ? pPortion->GetSize().Width() : 0;
    1198         [ #  # ]:          0 :                 sal_uInt16 nP = SplitTextPortion( pParaPortion, nTmpPos, pLine );
    1199         [ #  # ]:          0 :                 const TextPortion* p = pParaPortion->GetTextPortions()[nP];
    1200                 :            :                 DBG_ASSERT( p, "Portion ?!" );
    1201                 :          0 :                 nTmpWidth += p->GetSize().Width();
    1202                 :            :             }
    1203                 :            :         }
    1204         [ +  + ]:     208554 :         else if ( nTmpWidth >= nXWidth )
    1205                 :            :         {
    1206                 :     115873 :             nPortionEnd = nTmpPos;
    1207         [ +  - ]:     115873 :             nTmpPos -= pPortion ? pPortion->GetLen() : 0;
    1208                 :     115873 :             nPortionStart = nTmpPos;
    1209                 :     115873 :             nTmpPortion--;
    1210                 :     115873 :             bEOL = sal_False;
    1211                 :     115873 :             bEOC = sal_False;
    1212         [ +  - ]:     115873 :             if( pPortion ) switch ( pPortion->GetKind() )
              [ +  +  - ]
    1213                 :            :             {
    1214                 :            :                 case PORTIONKIND_TEXT:
    1215                 :            :                 {
    1216                 :     115869 :                     nTmpWidth -= pPortion->GetSize().Width();
    1217                 :            :                 }
    1218                 :     115869 :                 break;
    1219                 :            :                 case PORTIONKIND_FIELD:
    1220                 :            :                 case PORTIONKIND_TAB:
    1221                 :            :                 {
    1222                 :          4 :                     nTmpWidth -= pPortion->GetSize().Width();
    1223                 :          4 :                     bEOL = sal_True;
    1224                 :          4 :                     bFixedEnd = sal_True;
    1225                 :            :                 }
    1226                 :          4 :                 break;
    1227                 :            :                 default:
    1228                 :            :                 {
    1229                 :            :                     //  A feature is not wrapped:
    1230                 :            :                     DBG_ASSERT( ( pPortion->GetKind() == PORTIONKIND_LINEBREAK ), "What Feature ?" );
    1231                 :          0 :                     bEOL = sal_True;
    1232                 :     115873 :                     bFixedEnd = sal_True;
    1233                 :            :                 }
    1234                 :            :             }
    1235                 :            :         }
    1236                 :            :         else
    1237                 :            :         {
    1238                 :      92681 :             bEOL = sal_True;
    1239                 :      92681 :             bEOC = sal_True;
    1240                 :      92681 :             pLine->SetEnd( nPortionEnd );
    1241                 :            :             DBG_ASSERT( pParaPortion->GetTextPortions().Count(), "No TextPortions?" );
    1242         [ +  - ]:      92681 :             pLine->SetEndPortion( (sal_uInt16)pParaPortion->GetTextPortions().Count() - 1 );
    1243                 :            :         }
    1244                 :            : 
    1245         [ -  + ]:     208554 :         if ( aStatus.OneCharPerLine() )
    1246                 :            :         {
    1247                 :          0 :             pLine->SetEnd( nPortionEnd );
    1248                 :          0 :             pLine->SetEndPortion( nTmpPortion-1 );
    1249                 :            :         }
    1250         [ +  + ]:     208554 :         else if ( bFixedEnd )
    1251                 :            :         {
    1252                 :          4 :             pLine->SetEnd( nPortionStart );
    1253                 :          4 :             pLine->SetEndPortion( nTmpPortion-1 );
    1254                 :            :         }
    1255 [ +  + ][ -  + ]:     208550 :         else if ( bLineBreak || bBrokenLine )
    1256                 :            :         {
    1257                 :         31 :             pLine->SetEnd( nPortionStart+1 );
    1258                 :         31 :             pLine->SetEndPortion( nTmpPortion-1 );
    1259                 :         31 :             bEOC = sal_False; // was set above, maybe change the sequence of the if's?
    1260                 :            :         }
    1261         [ +  + ]:     208519 :         else if ( !bEOL )
    1262                 :            :         {
    1263                 :            :             DBG_ASSERT( pPortion && ((nPortionEnd-nPortionStart) == pPortion->GetLen()), "However, another portion?!" );
    1264                 :     115869 :             long nRemainingWidth = nMaxLineWidth - nTmpWidth;
    1265         [ +  - ]:     115869 :             sal_Bool bCanHyphenate = ( aTmpFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL );
    1266 [ -  + ][ #  # ]:     115869 :             if ( bCompressedChars && pPortion && ( pPortion->GetLen() > 1 ) && pPortion->GetExtraInfos() && pPortion->GetExtraInfos()->bCompressed )
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
    1267                 :            :             {
    1268                 :            :                 // I need the manipulated DXArray for determining the break postion...
    1269                 :          0 :                 sal_Int32* pDXArray = NULL;
    1270 [ #  # ][ #  # ]:          0 :                 if (!pLine->GetCharPosArray().empty())
    1271 [ #  # ][ #  # ]:          0 :                     pDXArray = &pLine->GetCharPosArray()[0] + (nPortionStart - pLine->GetStart());
    1272                 :            :                 ImplCalcAsianCompression(
    1273         [ #  # ]:          0 :                     pNode, pPortion, nPortionStart, pDXArray, 10000, true);
    1274                 :            :             }
    1275         [ +  - ]:     115869 :             if( pPortion )
    1276                 :            :                 ImpBreakLine( pParaPortion, pLine, pPortion, nPortionStart,
    1277 [ +  - ][ +  + ]:     115869 :                                                 nRemainingWidth, bCanHyphenate && bHyphenatePara );
                 [ +  - ]
    1278                 :            :         }
    1279                 :            : 
    1280                 :            :         // ------------------------------------------------------------------
    1281                 :            :         // Line finished => adjust
    1282                 :            :         // ------------------------------------------------------------------
    1283                 :            : 
    1284                 :            :         // CalcTextSize should be replaced by a continuous registering!
    1285         [ +  - ]:     208554 :         Size aTextSize = pLine->CalcTextSize( *pParaPortion );
    1286                 :            : 
    1287         [ +  + ]:     208554 :         if ( aTextSize.Height() == 0 )
    1288                 :            :         {
    1289         [ +  - ]:         17 :             SeekCursor( pNode, pLine->GetStart()+1, aTmpFont );
    1290         [ +  - ]:         17 :             aTmpFont.SetPhysFont( pRefDev );
    1291         [ +  - ]:         17 :             ImplInitDigitMode( pRefDev, 0, 0, 0, aTmpFont.GetLanguage() );
    1292                 :            : 
    1293         [ -  + ]:         17 :             if ( IsFixedCellHeight() )
    1294         [ #  # ]:          0 :                 aTextSize.Height() = ImplCalculateFontIndependentLineSpacing( aTmpFont.GetHeight() );
    1295                 :            :             else
    1296 [ +  - ][ +  - ]:         17 :                 aTextSize.Height() = aTmpFont.GetPhysTxtSize( pRefDev, String() ).Height();
                 [ +  - ]
    1297                 :         17 :             pLine->SetHeight( (sal_uInt16)aTextSize.Height() );
    1298                 :            :         }
    1299                 :            : 
    1300                 :            :         // The font metrics can not be calculated continuously, if the font is
    1301                 :            :         // set anyway, because a large font only after wrapping suddenly ends
    1302                 :            :         // up in the next line => Font metrics too big.
    1303                 :     208554 :         FormatterFontMetric aFormatterMetrics;
    1304                 :     208554 :         sal_uInt16 nTPos = pLine->GetStart();
    1305         [ +  + ]:     419068 :         for ( sal_uInt16 nP = pLine->GetStartPortion(); nP <= pLine->GetEndPortion(); nP++ )
    1306                 :            :         {
    1307         [ +  - ]:     210514 :             const TextPortion* pTP = pParaPortion->GetTextPortions()[nP];
    1308                 :            :             // problem with hard font height attribute, when everthing but the line break has this attribute
    1309         [ +  + ]:     210514 :             if ( pTP->GetKind() != PORTIONKIND_LINEBREAK )
    1310                 :            :             {
    1311         [ +  - ]:     210483 :                 SeekCursor( pNode, nTPos+1, aTmpFont );
    1312         [ +  - ]:     210483 :                 aTmpFont.SetPhysFont( GetRefDevice() );
    1313         [ +  - ]:     210483 :                 ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
    1314         [ +  - ]:     210483 :                 RecalcFormatterFontMetrics( aFormatterMetrics, aTmpFont );
    1315                 :            :             }
    1316                 :     210514 :             nTPos = nTPos + pTP->GetLen();
    1317                 :            :         }
    1318                 :     208554 :         sal_uInt16 nLineHeight = aFormatterMetrics.GetHeight();
    1319         [ +  + ]:     208554 :         if ( nLineHeight > pLine->GetHeight() )
    1320                 :       6187 :             pLine->SetHeight( nLineHeight );
    1321                 :     208554 :         pLine->SetMaxAscent( aFormatterMetrics.nMaxAscent );
    1322                 :            : 
    1323                 :     208554 :         bSameLineAgain = sal_False;
    1324 [ #  # ][ -  + ]:     208554 :         if ( GetTextRanger() && ( pLine->GetHeight() > nTextLineHeight ) )
                 [ -  + ]
    1325                 :            :         {
    1326                 :            :             // put down with the other size!
    1327                 :          0 :             bSameLineAgain = sal_True;
    1328                 :            :         }
    1329                 :            : 
    1330                 :            : 
    1331 [ +  - ][ +  - ]:     208554 :         if ( !bSameLineAgain && !aStatus.IsOutliner() )
                 [ +  - ]
    1332                 :            :         {
    1333         [ +  + ]:     208554 :             if ( rLSItem.GetLineSpaceRule() == SVX_LINE_SPACE_MIN )
    1334                 :            :             {
    1335                 :       2658 :                 sal_uInt16 nMinHeight = GetYValue( rLSItem.GetLineHeight() );
    1336                 :       2658 :                 sal_uInt16 nTxtHeight = pLine->GetHeight();
    1337         [ -  + ]:       2658 :                 if ( nTxtHeight < nMinHeight )
    1338                 :            :                 {
    1339                 :            :                     // The Ascent has to be adjusted for the difference:
    1340                 :          0 :                     long nDiff = nMinHeight - nTxtHeight;
    1341                 :          0 :                     pLine->SetMaxAscent( (sal_uInt16)(pLine->GetMaxAscent() + nDiff) );
    1342                 :          0 :                     pLine->SetHeight( nMinHeight, nTxtHeight );
    1343                 :            :                 }
    1344                 :            :             }
    1345         [ -  + ]:     205896 :             else if ( rLSItem.GetLineSpaceRule() == SVX_LINE_SPACE_FIX )
    1346                 :            :             {
    1347                 :          0 :                 sal_uInt16 nFixHeight = GetYValue( rLSItem.GetLineHeight() );
    1348                 :          0 :                 sal_uInt16 nTxtHeight = pLine->GetHeight();
    1349                 :          0 :                 pLine->SetMaxAscent( (sal_uInt16)(pLine->GetMaxAscent() + ( nFixHeight - nTxtHeight ) ) );
    1350                 :          0 :                 pLine->SetHeight( nFixHeight, nTxtHeight );
    1351                 :            :             }
    1352         [ +  + ]:     205896 :             else if ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
    1353                 :            :             {
    1354 [ +  + ][ +  + ]:        588 :                 if ( nPara || IsFixedCellHeight() || pLine->GetStartPortion() ) // Not the very first line
         [ +  + ][ +  + ]
    1355                 :            :                 {
    1356                 :            :                     // There are documents with PropLineSpace 0, why?
    1357                 :            :                     // (cmc: re above question :-) such documents can be seen by importing a .ppt
    1358 [ +  - ][ +  + ]:        510 :                     if ( rLSItem.GetPropLineSpace() && ( rLSItem.GetPropLineSpace() != 100 ) )
                 [ +  + ]
    1359                 :            :                     {
    1360                 :        372 :                         sal_uInt16 nTxtHeight = pLine->GetHeight();
    1361                 :        372 :                         sal_Int32 nH = nTxtHeight;
    1362                 :        372 :                         nH *= rLSItem.GetPropLineSpace();
    1363                 :        372 :                         nH /= 100;
    1364                 :            :                         // The Ascent has to be adjusted for the difference:
    1365                 :        372 :                         long nDiff = pLine->GetHeight() - nH;
    1366         [ -  + ]:        372 :                         if ( nDiff > pLine->GetMaxAscent() )
    1367                 :          0 :                             nDiff = pLine->GetMaxAscent();
    1368                 :        372 :                         pLine->SetMaxAscent( (sal_uInt16)(pLine->GetMaxAscent() - nDiff) );
    1369                 :        372 :                         pLine->SetHeight( (sal_uInt16)nH, nTxtHeight );
    1370                 :            :                     }
    1371                 :            :                 }
    1372                 :            :             }
    1373                 :            :         }
    1374                 :            : 
    1375 [ +  - ][ +  +  :     398841 :         if ( ( !IsVertical() && aStatus.AutoPageWidth() ) ||
             -  +  #  # ]
                 [ +  + ]
    1376                 :     190287 :              ( IsVertical() && aStatus.AutoPageHeight() ) )
    1377                 :            :         {
    1378                 :            :             // If the row fits within the current paper width, then this width
    1379                 :            :             // has to be used for the Alignment. If it does not fit or if it
    1380                 :            :             // will change the paper width, it will be formatted again for
    1381                 :            :             // Justification! = LEFT anyway.
    1382                 :      36534 :             long nMaxLineWidthFix = ( !IsVertical() ? aPaperSize.Width() : aPaperSize.Height() )
    1383         [ +  - ]:      36534 :                                         - GetXValue( rLRItem.GetRight() ) - nStartX;
    1384         [ +  + ]:      18267 :             if ( aTextSize.Width() < nMaxLineWidthFix )
    1385                 :       5402 :                 nMaxLineWidth = nMaxLineWidthFix;
    1386                 :            :         }
    1387                 :            : 
    1388         [ -  + ]:     208554 :         if ( bCompressedChars )
    1389                 :            :         {
    1390                 :          0 :             long nRemainingWidth = nMaxLineWidth - aTextSize.Width();
    1391         [ #  # ]:          0 :             if ( nRemainingWidth > 0 )
    1392                 :            :             {
    1393         [ #  # ]:          0 :                 ImplExpandCompressedPortions( pLine, pParaPortion, nRemainingWidth );
    1394         [ #  # ]:          0 :                 aTextSize = pLine->CalcTextSize( *pParaPortion );
    1395                 :            :             }
    1396                 :            :         }
    1397                 :            : 
    1398         [ -  + ]:     208554 :         if ( pLine->IsHangingPunctuation() )
    1399                 :            :         {
    1400                 :            :             // Width from HangingPunctuation was set to 0 in ImpBreakLine,
    1401                 :            :             // check for rel width now, maybe create compression...
    1402                 :          0 :             long n = nMaxLineWidth - aTextSize.Width();
    1403         [ #  # ]:          0 :             const TextPortion* pTP = pParaPortion->GetTextPortions()[pLine->GetEndPortion()];
    1404                 :          0 :             sal_uInt16 nPosInArray = pLine->GetEnd()-1-pLine->GetStart();
    1405 [ #  # ][ #  # ]:          0 :             long nNewValue = ( nPosInArray ? pLine->GetCharPosArray()[ nPosInArray-1 ] : 0 ) + n;
                 [ #  # ]
    1406 [ #  # ][ #  # ]:          0 :             pLine->GetCharPosArray()[ nPosInArray ] = nNewValue;
    1407                 :          0 :             pTP->GetSize().Width() += n;
    1408                 :            :         }
    1409                 :            : 
    1410                 :     208554 :         pLine->SetTextWidth( aTextSize.Width() );
    1411   [ +  +  +  + ]:     208554 :         switch ( eJustification )
    1412                 :            :         {
    1413                 :            :             case SVX_ADJUST_CENTER:
    1414                 :            :             {
    1415                 :      11754 :                 long n = ( nMaxLineWidth - aTextSize.Width() ) / 2;
    1416                 :      11754 :                 n += nStartX;  // Indentation is kept.
    1417         [ +  + ]:      11754 :                 if ( n > 0 )
    1418                 :      11065 :                     pLine->SetStartPosX( (sal_uInt16)n );
    1419                 :            :                 else
    1420                 :        689 :                     pLine->SetStartPosX( 0 );
    1421                 :            : 
    1422                 :            :             }
    1423                 :      11754 :             break;
    1424                 :            :             case SVX_ADJUST_RIGHT:
    1425                 :            :             {
    1426                 :            :                 // For automatically wrapped lines, which has a blank at the end
    1427                 :            :                 // the blank must not be displayed!
    1428                 :       1892 :                 long n = nMaxLineWidth - aTextSize.Width();
    1429                 :       1892 :                 n += nStartX;  // Indentation is kept.
    1430         [ +  + ]:       1892 :                 if ( n > 0 )
    1431                 :       1466 :                     pLine->SetStartPosX( (sal_uInt16)n );
    1432                 :            :                 else
    1433                 :        426 :                     pLine->SetStartPosX( 0 );
    1434                 :            :             }
    1435                 :       1892 :             break;
    1436                 :            :             case SVX_ADJUST_BLOCK:
    1437                 :            :             {
    1438         [ +  - ]:        325 :                 bool bDistLastLine = (GetJustifyMethod(nPara) == SVX_JUSTIFY_METHOD_DISTRIBUTE);
    1439                 :        325 :                 long nRemainingSpace = nMaxLineWidth - aTextSize.Width();
    1440                 :        325 :                 pLine->SetStartPosX( (sal_uInt16)nStartX );
    1441 [ +  + ][ -  + ]:        325 :                 if ( nRemainingSpace > 0 && (!bEOC || bDistLastLine) )
                 [ +  + ]
    1442         [ +  - ]:        116 :                     ImpAdjustBlocks( pParaPortion, pLine, nRemainingSpace );
    1443                 :            :             }
    1444                 :        325 :             break;
    1445                 :            :             default:
    1446                 :            :             {
    1447                 :     194583 :                 pLine->SetStartPosX( (sal_uInt16)nStartX ); // FI, LI
    1448                 :            :             }
    1449                 :     194583 :             break;
    1450                 :            :         }
    1451                 :            : 
    1452                 :            :         // -----------------------------------------------------------------
    1453                 :            :         // Check whether the line must be re-issued ...
    1454                 :            :         // -----------------------------------------------------------------
    1455                 :     208554 :         pLine->SetInvalid();
    1456                 :            : 
    1457                 :            :         // If a portion was wrapped there may be far too many positions in
    1458                 :            :         // CharPosArray:
    1459         [ +  - ]:     208554 :         if ( bCalcCharPositions )
    1460                 :            :         {
    1461         [ +  - ]:     208554 :             EditLine::CharPosArrayType& rArray = pLine->GetCharPosArray();
    1462                 :     208554 :             size_t nLen = pLine->GetLen();
    1463         [ +  + ]:     208554 :             if (rArray.size() > nLen)
    1464 [ +  - ][ +  - ]:      94166 :                 rArray.erase(rArray.begin()+nLen, rArray.end());
    1465                 :            :         }
    1466                 :            : 
    1467         [ -  + ]:     208554 :         if ( GetTextRanger() )
    1468                 :            :         {
    1469         [ #  # ]:          0 :             if ( nTextXOffset )
    1470                 :          0 :                 pLine->SetStartPosX( (sal_uInt16) ( pLine->GetStartPosX() + nTextXOffset ) );
    1471         [ #  # ]:          0 :             if ( nTextExtraYOffset )
    1472                 :            :             {
    1473                 :          0 :                 pLine->SetHeight( (sal_uInt16) ( pLine->GetHeight() + nTextExtraYOffset ), 0, pLine->GetHeight() );
    1474                 :          0 :                 pLine->SetMaxAscent( (sal_uInt16) ( pLine->GetMaxAscent() + nTextExtraYOffset ) );
    1475                 :            :             }
    1476                 :            :         }
    1477                 :            : 
    1478                 :            :         // for <0 think over !
    1479         [ +  + ]:     208554 :         if ( pParaPortion->IsSimpleInvalid() )
    1480                 :            :         {
    1481                 :            :             // Change through simple Text changes ...
    1482                 :            :             // Do mot cancel formatting since Portions possibly have to be split
    1483                 :            :             // again! If at some point cancelable, then validate the following
    1484                 :            :             // line! But if applicable, mark as valid, so there is less output...
    1485         [ -  + ]:         68 :             if ( pLine->GetEnd() < nInvalidStart )
    1486                 :            :             {
    1487 [ #  # ][ #  # ]:          0 :                 if ( *pLine == aSaveLine )
    1488                 :            :                 {
    1489                 :          0 :                     pLine->SetValid();
    1490                 :            :                 }
    1491                 :            :             }
    1492                 :            :             else
    1493                 :            :             {
    1494                 :         68 :                 sal_uInt16 nStart = pLine->GetStart();
    1495                 :         68 :                 sal_uInt16 nEnd = pLine->GetEnd();
    1496                 :            : 
    1497         [ -  + ]:         68 :                 if ( nStart > nInvalidEnd )
    1498                 :            :                 {
    1499   [ #  #  #  # ]:          0 :                     if ( ( ( nStart-nInvalidDiff ) == aSaveLine.GetStart() ) &&
                 [ #  # ]
    1500                 :          0 :                             ( ( nEnd-nInvalidDiff ) == aSaveLine.GetEnd() ) )
    1501                 :            :                     {
    1502                 :          0 :                         pLine->SetValid();
    1503 [ #  # ][ #  # ]:          0 :                         if ( bCalcCharPositions && bQuickFormat )
    1504                 :            :                         {
    1505                 :          0 :                             bCalcCharPositions = sal_False;
    1506                 :          0 :                             bLineBreak = sal_False;
    1507         [ #  # ]:          0 :                             pParaPortion->CorrectValuesBehindLastFormattedLine( nLine );
    1508                 :            :                             break;
    1509                 :            :                         }
    1510                 :            :                     }
    1511                 :            :                 }
    1512 [ +  - ][ +  + ]:         68 :                 else if ( bCalcCharPositions && bQuickFormat && ( nEnd > nInvalidEnd) )
                 [ -  + ]
    1513                 :            :                 {
    1514                 :            :                     // If the invalid line ends so that the next begins on the
    1515                 :            :                     // 'same' passage as before, i.e. not wrapped differently,
    1516                 :            :                     //  then the text width does not have to be determined anew:
    1517         [ #  # ]:          0 :                     if ( nEnd == ( aSaveLine.GetEnd() + nInvalidDiff ) )
    1518                 :            :                     {
    1519                 :          0 :                         bCalcCharPositions = sal_False;
    1520                 :          0 :                         bLineBreak = sal_False;
    1521         [ #  # ]:          0 :                         pParaPortion->CorrectValuesBehindLastFormattedLine( nLine );
    1522                 :            :                         break;
    1523                 :            :                     }
    1524                 :            :                 }
    1525                 :            :             }
    1526                 :            :         }
    1527                 :            : 
    1528         [ +  - ]:     208554 :         if ( !bSameLineAgain )
    1529                 :            :         {
    1530                 :     208554 :             nIndex = pLine->GetEnd();   // next line start = last line end
    1531                 :            :                                         // as nEnd points to the last charecter!
    1532                 :            : 
    1533                 :     208554 :             sal_uInt16 nEndPortion = pLine->GetEndPortion();
    1534                 :            : 
    1535                 :            :             // Next line or maybe a new line....
    1536                 :     208554 :             pLine = 0;
    1537 [ +  + ][ +  - ]:     208554 :             if ( nLine < pParaPortion->GetLines().Count()-1 )
    1538         [ +  - ]:         34 :                 pLine = pParaPortion->GetLines()[++nLine];
    1539 [ +  + ][ +  - ]:     208554 :             if ( pLine && ( nIndex >= pNode->Len() ) )
         [ +  + ][ +  + ]
    1540                 :            :             {
    1541                 :          2 :                 nDelFromLine = nLine;
    1542                 :            :                 break;
    1543                 :            :             }
    1544         [ +  + ]:     208552 :             if ( !pLine )
    1545                 :            :             {
    1546 [ +  - ][ +  + ]:     208520 :                 if ( nIndex < pNode->Len() )
    1547                 :            :                 {
    1548 [ +  - ][ +  - ]:      94179 :                     pLine = new EditLine;
    1549         [ +  - ]:      94179 :                     pParaPortion->GetLines().Insert(++nLine, pLine);
    1550                 :            :                 }
    1551 [ +  - ][ +  + ]:     114341 :                 else if ( nIndex && bLineBreak && GetTextRanger() )
         [ -  + ][ -  + ]
    1552                 :            :                 {
    1553                 :            :                     // normaly CreateAndInsertEmptyLine would be called, but I want to use
    1554                 :            :                     // CreateLines, so I need Polygon code only here...
    1555         [ #  # ]:          0 :                     TextPortion* pDummyPortion = new TextPortion( 0 );
    1556         [ #  # ]:          0 :                     pParaPortion->GetTextPortions().Append(pDummyPortion);
    1557 [ #  # ][ #  # ]:          0 :                     pLine = new EditLine;
    1558         [ #  # ]:          0 :                     pParaPortion->GetLines().Insert(++nLine, pLine);
    1559                 :          0 :                     bForceOneRun = sal_True;
    1560                 :          0 :                     bProcessingEmptyLine = sal_True;
    1561                 :            :                 }
    1562                 :            :             }
    1563         [ +  + ]:     208552 :             if ( pLine )
    1564                 :            :             {
    1565         [ +  - ]:      94211 :                 aSaveLine = *pLine;
    1566                 :      94211 :                 pLine->SetStart( nIndex );
    1567                 :      94211 :                 pLine->SetEnd( nIndex );
    1568                 :      94211 :                 pLine->SetStartPortion( nEndPortion+1 );
    1569                 :     208554 :                 pLine->SetEndPortion( nEndPortion+1 );
    1570                 :            :             }
    1571                 :            :         }
    1572                 :            :     }   // while ( Index < Len )
    1573                 :            : 
    1574         [ +  + ]:     114343 :     if ( nDelFromLine != 0xFFFF )
    1575         [ +  - ]:          2 :         pParaPortion->GetLines().DeleteFromLine( nDelFromLine );
    1576                 :            : 
    1577                 :            :     DBG_ASSERT( pParaPortion->GetLines().Count(), "No line after CreateLines!" );
    1578                 :            : 
    1579         [ +  + ]:     114343 :     if ( bLineBreak == sal_True )
    1580         [ +  - ]:         19 :         CreateAndInsertEmptyLine( pParaPortion, nStartPosY );
    1581                 :            : 
    1582         [ +  - ]:     114343 :     delete[] pBuf;
    1583                 :            : 
    1584         [ +  - ]:     114343 :     sal_Bool bHeightChanged = FinishCreateLines( pParaPortion );
    1585                 :            : 
    1586         [ -  + ]:     114343 :     if ( bMapChanged )
    1587         [ #  # ]:          0 :         GetRefDevice()->Pop();
    1588                 :            : 
    1589         [ +  - ]:     114343 :     GetRefDevice()->Pop();
    1590                 :            : 
    1591 [ +  - ][ +  - ]:     324581 :     return bHeightChanged;
    1592                 :            : }
    1593                 :            : 
    1594                 :     210257 : void ImpEditEngine::CreateAndInsertEmptyLine( ParaPortion* pParaPortion, sal_uInt32 )
    1595                 :            : {
    1596                 :            :     DBG_ASSERT( !GetTextRanger(), "Don't use CreateAndInsertEmptyLine with a polygon!" );
    1597                 :            : 
    1598 [ +  - ][ +  - ]:     210257 :     EditLine* pTmpLine = new EditLine;
    1599         [ +  - ]:     210257 :     pTmpLine->SetStart( pParaPortion->GetNode()->Len() );
    1600         [ +  - ]:     210257 :     pTmpLine->SetEnd( pParaPortion->GetNode()->Len() );
    1601         [ +  - ]:     210257 :     pParaPortion->GetLines().Append(pTmpLine);
    1602                 :            : 
    1603 [ +  - ][ +  + ]:     210257 :     sal_Bool bLineBreak = pParaPortion->GetNode()->Len() ? sal_True : sal_False;
    1604                 :     210257 :     sal_Int32 nSpaceBefore = 0;
    1605         [ +  - ]:     210257 :     sal_Int32 nSpaceBeforeAndMinLabelWidth = GetSpaceBeforeAndMinLabelWidth( pParaPortion->GetNode(), &nSpaceBefore );
    1606         [ +  - ]:     210257 :     const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( pParaPortion->GetNode() );
    1607         [ +  - ]:     210257 :     const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pParaPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
    1608                 :     210257 :     short nStartX = GetXValue( (short)(rLRItem.GetTxtLeft() + rLRItem.GetTxtFirstLineOfst() + nSpaceBefore));
    1609                 :            : 
    1610         [ +  - ]:     210257 :     Rectangle aBulletArea = Rectangle( Point(), Point() );
    1611         [ +  + ]:     210257 :     if ( bLineBreak == sal_True )
    1612                 :            :     {
    1613                 :         19 :         nStartX = (short)GetXValue( rLRItem.GetTxtLeft() + rLRItem.GetTxtFirstLineOfst() + nSpaceBeforeAndMinLabelWidth );
    1614                 :            :     }
    1615                 :            :     else
    1616                 :            :     {
    1617 [ +  - ][ +  - ]:     210238 :         aBulletArea = GetEditEnginePtr()->GetBulletArea( GetParaPortions().GetPos( pParaPortion ) );
    1618         [ -  + ]:     210238 :         if ( aBulletArea.Right() > 0 )
    1619                 :          0 :             pParaPortion->SetBulletX( (sal_uInt16) GetXValue( aBulletArea.Right() ) );
    1620                 :            :         else
    1621                 :     210238 :             pParaPortion->SetBulletX( 0 ); // If Bullet set incorrectly.
    1622         [ -  + ]:     210238 :         if ( pParaPortion->GetBulletX() > nStartX )
    1623                 :            :         {
    1624                 :          0 :             nStartX = (short)GetXValue( rLRItem.GetTxtLeft() + rLRItem.GetTxtFirstLineOfst() + nSpaceBeforeAndMinLabelWidth );
    1625         [ #  # ]:          0 :             if ( pParaPortion->GetBulletX() > nStartX )
    1626                 :          0 :                 nStartX = pParaPortion->GetBulletX();
    1627                 :            :         }
    1628                 :            :     }
    1629                 :            : 
    1630         [ +  - ]:     210257 :     SvxFont aTmpFont;
    1631 [ +  + ][ +  - ]:     210257 :     SeekCursor( pParaPortion->GetNode(), bLineBreak ? pParaPortion->GetNode()->Len() : 0, aTmpFont );
                 [ +  - ]
    1632         [ +  - ]:     210257 :     aTmpFont.SetPhysFont( pRefDev );
    1633                 :            : 
    1634         [ +  - ]:     210257 :     TextPortion* pDummyPortion = new TextPortion( 0 );
    1635 [ +  - ][ +  - ]:     210257 :     pDummyPortion->GetSize() = aTmpFont.GetPhysTxtSize( pRefDev, String() );
                 [ +  - ]
    1636         [ +  + ]:     210257 :     if ( IsFixedCellHeight() )
    1637         [ +  - ]:        642 :         pDummyPortion->GetSize().Height() = ImplCalculateFontIndependentLineSpacing( aTmpFont.GetHeight() );
    1638         [ +  - ]:     210257 :     pParaPortion->GetTextPortions().Append(pDummyPortion);
    1639                 :     210257 :     FormatterFontMetric aFormatterMetrics;
    1640         [ +  - ]:     210257 :     RecalcFormatterFontMetrics( aFormatterMetrics, aTmpFont );
    1641                 :     210257 :     pTmpLine->SetMaxAscent( aFormatterMetrics.nMaxAscent );
    1642                 :     210257 :     pTmpLine->SetHeight( (sal_uInt16) pDummyPortion->GetSize().Height() );
    1643                 :     210257 :     sal_uInt16 nLineHeight = aFormatterMetrics.GetHeight();
    1644         [ +  + ]:     210257 :     if ( nLineHeight > pTmpLine->GetHeight() )
    1645                 :        609 :         pTmpLine->SetHeight( nLineHeight );
    1646                 :            : 
    1647         [ +  - ]:     210257 :     if ( !aStatus.IsOutliner() )
    1648                 :            :     {
    1649         [ +  - ]:     210257 :         sal_uInt16 nPara = GetParaPortions().GetPos( pParaPortion );
    1650         [ +  - ]:     210257 :         SvxAdjust eJustification = GetJustification( nPara );
    1651         [ +  - ]:     210257 :         long nMaxLineWidth = !IsVertical() ? aPaperSize.Width() : aPaperSize.Height();
    1652                 :     210257 :         nMaxLineWidth -= GetXValue( rLRItem.GetRight() );
    1653                 :     210257 :         long nTextXOffset = 0;
    1654         [ -  + ]:     210257 :         if ( nMaxLineWidth < 0 )
    1655                 :          0 :             nMaxLineWidth = 1;
    1656         [ +  + ]:     210257 :         if ( eJustification ==  SVX_ADJUST_CENTER )
    1657                 :         55 :             nStartX = sal::static_int_cast< short >(nMaxLineWidth / 2);
    1658         [ +  + ]:     210202 :         else if ( eJustification ==  SVX_ADJUST_RIGHT )
    1659                 :        324 :             nStartX = sal::static_int_cast< short >(nMaxLineWidth);
    1660                 :            : 
    1661                 :     210257 :         nStartX = sal::static_int_cast< short >(nStartX + nTextXOffset);
    1662                 :            :     }
    1663                 :            : 
    1664                 :     210257 :     pTmpLine->SetStartPosX( nStartX );
    1665                 :            : 
    1666         [ +  - ]:     210257 :     if ( !aStatus.IsOutliner() )
    1667                 :            :     {
    1668         [ +  + ]:     210257 :         if ( rLSItem.GetLineSpaceRule() == SVX_LINE_SPACE_MIN )
    1669                 :            :         {
    1670                 :        213 :             sal_uInt16 nMinHeight = rLSItem.GetLineHeight();
    1671                 :        213 :             sal_uInt16 nTxtHeight = pTmpLine->GetHeight();
    1672         [ -  + ]:        213 :             if ( nTxtHeight < nMinHeight )
    1673                 :            :             {
    1674                 :            :                 // The Ascent has to be adjusted for the difference:
    1675                 :          0 :                 long nDiff = nMinHeight - nTxtHeight;
    1676                 :          0 :                 pTmpLine->SetMaxAscent( (sal_uInt16)(pTmpLine->GetMaxAscent() + nDiff) );
    1677                 :          0 :                 pTmpLine->SetHeight( nMinHeight, nTxtHeight );
    1678                 :            :             }
    1679                 :            :         }
    1680         [ -  + ]:     210044 :         else if ( rLSItem.GetLineSpaceRule() == SVX_LINE_SPACE_FIX )
    1681                 :            :         {
    1682                 :          0 :             sal_uInt16 nFixHeight = rLSItem.GetLineHeight();
    1683                 :          0 :             sal_uInt16 nTxtHeight = pTmpLine->GetHeight();
    1684                 :            : 
    1685                 :          0 :             pTmpLine->SetMaxAscent( (sal_uInt16)(pTmpLine->GetMaxAscent() + ( nFixHeight - nTxtHeight ) ) );
    1686                 :          0 :             pTmpLine->SetHeight( nFixHeight, nTxtHeight );
    1687                 :            :         }
    1688         [ +  + ]:     210044 :         else if ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
    1689                 :            :         {
    1690         [ +  - ]:        129 :             sal_uInt16 nPara = GetParaPortions().GetPos( pParaPortion );
    1691 [ +  + ][ +  - ]:        129 :             if ( nPara || IsFixedCellHeight() || pTmpLine->GetStartPortion() ) // Not the very first line
         [ -  + ][ +  + ]
    1692                 :            :             {
    1693                 :            :                 // There are documents with PropLineSpace 0, why?
    1694                 :            :                 // (cmc: re above question :-) such documents can be seen by importing a .ppt
    1695 [ +  - ][ +  - ]:          9 :                 if ( rLSItem.GetPropLineSpace() && ( rLSItem.GetPropLineSpace() != 100 ) )
                 [ +  - ]
    1696                 :            :                 {
    1697                 :          9 :                     sal_uInt16 nTxtHeight = pTmpLine->GetHeight();
    1698                 :          9 :                     sal_Int32 nH = nTxtHeight;
    1699                 :          9 :                     nH *= rLSItem.GetPropLineSpace();
    1700                 :          9 :                     nH /= 100;
    1701                 :            :                     // The Ascent has to be adjusted for the difference:
    1702                 :          9 :                     long nDiff = pTmpLine->GetHeight() - nH;
    1703         [ -  + ]:          9 :                     if ( nDiff > pTmpLine->GetMaxAscent() )
    1704                 :          0 :                         nDiff = pTmpLine->GetMaxAscent();
    1705                 :          9 :                     pTmpLine->SetMaxAscent( (sal_uInt16)(pTmpLine->GetMaxAscent() - nDiff) );
    1706                 :          9 :                     pTmpLine->SetHeight( (sal_uInt16)nH, nTxtHeight );
    1707                 :            :                 }
    1708                 :            :             }
    1709                 :            :         }
    1710                 :            :     }
    1711                 :            : 
    1712         [ +  + ]:     210257 :     if ( !bLineBreak )
    1713                 :            :     {
    1714         [ +  - ]:     210238 :         long nMinHeight = aBulletArea.GetHeight();
    1715         [ -  + ]:     210238 :         if ( nMinHeight > (long)pTmpLine->GetHeight() )
    1716                 :            :         {
    1717                 :          0 :             long nDiff = nMinHeight - (long)pTmpLine->GetHeight();
    1718                 :            :             // distribute nDiff upwards and downwards
    1719                 :          0 :             pTmpLine->SetMaxAscent( (sal_uInt16)(pTmpLine->GetMaxAscent() + nDiff/2) );
    1720                 :          0 :             pTmpLine->SetHeight( (sal_uInt16)nMinHeight );
    1721                 :            :         }
    1722                 :            :     }
    1723                 :            :     else
    1724                 :            :     {
    1725                 :            :         // -2: The new one is already inserted.
    1726                 :            : #ifdef DBG_UTIL
    1727                 :            :         EditLine* pLastLine = pParaPortion->GetLines()[pParaPortion->GetLines().Count()-2];
    1728                 :            :         DBG_ASSERT( pLastLine, "soft wrap no line?!" );
    1729                 :            :         DBG_ASSERT( pLastLine->GetEnd() == pParaPortion->GetNode()->Len(), "different anyway?" );
    1730                 :            : #endif
    1731         [ +  - ]:         19 :         sal_uInt16 nPos = (sal_uInt16) pParaPortion->GetTextPortions().Count() - 1 ;
    1732                 :         19 :         pTmpLine->SetStartPortion( nPos );
    1733                 :         19 :         pTmpLine->SetEndPortion( nPos );
    1734         [ +  - ]:     210257 :     }
    1735                 :     210257 : }
    1736                 :            : 
    1737                 :     324581 : sal_Bool ImpEditEngine::FinishCreateLines( ParaPortion* pParaPortion )
    1738                 :            : {
    1739                 :            : //  CalcCharPositions( pParaPortion );
    1740                 :     324581 :     pParaPortion->SetValid();
    1741                 :     324581 :     long nOldHeight = pParaPortion->GetHeight();
    1742                 :     324581 :     CalcHeight( pParaPortion );
    1743                 :            : 
    1744                 :            :     DBG_ASSERT( pParaPortion->GetTextPortions().Count(), "FinishCreateLines: No Text-Portion?" );
    1745                 :     324581 :     sal_Bool bRet = ( pParaPortion->GetHeight() != nOldHeight );
    1746                 :     324581 :     return bRet;
    1747                 :            : }
    1748                 :            : 
    1749                 :     115869 : void ImpEditEngine::ImpBreakLine( ParaPortion* pParaPortion, EditLine* pLine, TextPortion* pPortion, sal_uInt16 nPortionStart, long nRemainingWidth, sal_Bool bCanHyphenate )
    1750                 :            : {
    1751                 :     115869 :     ContentNode* const pNode = pParaPortion->GetNode();
    1752                 :            : 
    1753                 :     115869 :     sal_uInt16 nBreakInLine = nPortionStart - pLine->GetStart();
    1754                 :     115869 :     sal_uInt16 nMax = nBreakInLine + pPortion->GetLen();
    1755 [ +  - ][ +  + ]:     161419 :     while ( ( nBreakInLine < nMax ) && ( pLine->GetCharPosArray()[nBreakInLine] < nRemainingWidth ) )
                 [ +  + ]
    1756                 :      45550 :         nBreakInLine++;
    1757                 :            : 
    1758                 :     115869 :     sal_uInt16 nMaxBreakPos = nBreakInLine + pLine->GetStart();
    1759                 :     115869 :        sal_uInt16 nBreakPos = 0xFFFF;
    1760                 :            : 
    1761                 :     115869 :     sal_Bool bCompressBlank = sal_False;
    1762                 :     115869 :     sal_Bool bHyphenated = sal_False;
    1763                 :     115869 :     sal_Bool bHangingPunctuation = sal_False;
    1764                 :     115869 :     sal_Unicode cAlternateReplChar = 0;
    1765                 :     115869 :     sal_Unicode cAlternateExtraChar = 0;
    1766                 :            : 
    1767 [ +  + ][ +  + ]:     115869 :     if ( ( nMaxBreakPos < ( nMax + pLine->GetStart() ) ) && ( pNode->GetChar( nMaxBreakPos ) == ' ' ) )
                 [ +  - ]
    1768                 :            :     {
    1769                 :            :         // Break behind the blank, blank will be compressed...
    1770                 :      15099 :         nBreakPos = nMaxBreakPos + 1;
    1771                 :      15099 :         bCompressBlank = sal_True;
    1772                 :            :     }
    1773                 :            :     else
    1774                 :            :     {
    1775                 :     100770 :         sal_uInt16 nMinBreakPos = pLine->GetStart();
    1776         [ +  - ]:     100770 :         const CharAttribList::AttribsType& rAttrs = pNode->GetCharAttribs().GetAttribs();
    1777         [ +  + ]:     141824 :         for (size_t nAttr = rAttrs.size(); nAttr; )
    1778                 :            :         {
    1779         [ +  - ]:      41057 :             const EditCharAttrib& rAttr = rAttrs[--nAttr];
    1780 [ +  + ][ +  + ]:      41057 :             if (rAttr.IsFeature() && rAttr.GetEnd() > nMinBreakPos && rAttr.GetEnd() <= nMaxBreakPos)
         [ +  + ][ +  + ]
    1781                 :            :             {
    1782                 :          3 :                 nMinBreakPos = rAttr.GetEnd();
    1783                 :          3 :                 break;
    1784                 :            :             }
    1785                 :            :         }
    1786                 :            : 
    1787 [ +  - ][ +  - ]:     100770 :         lang::Locale aLocale = GetLocale( EditPaM( pNode, nMaxBreakPos ) );
    1788                 :            : 
    1789         [ +  - ]:     100770 :         Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    1790 [ +  - ][ +  - ]:     100770 :         OUString aText = pNode->GetString();
    1791                 :     100770 :         Reference< XHyphenator > xHyph;
    1792         [ +  + ]:     100770 :         if ( bCanHyphenate )
    1793 [ +  - ][ +  - ]:      98080 :             xHyph = GetHyphenator();
    1794 [ +  - ][ +  - ]:     100770 :         i18n::LineBreakHyphenationOptions aHyphOptions( xHyph, Sequence< PropertyValue >(), 1 );
                 [ +  - ]
    1795                 :     100770 :         i18n::LineBreakUserOptions aUserOptions;
    1796                 :            : 
    1797 [ +  - ][ +  - ]:     100770 :         const i18n::ForbiddenCharacters* pForbidden = GetForbiddenCharsTable()->GetForbiddenCharacters( SvxLocaleToLanguage( aLocale ), sal_True );
         [ +  - ][ +  - ]
    1798                 :     100770 :         aUserOptions.forbiddenBeginCharacters = pForbidden->beginLine;
    1799                 :     100770 :         aUserOptions.forbiddenEndCharacters = pForbidden->endLine;
    1800         [ +  - ]:     100770 :         aUserOptions.applyForbiddenRules = ((const SfxBoolItem&)pNode->GetContentAttribs().GetItem( EE_PARA_FORBIDDENRULES )).GetValue();
    1801         [ +  - ]:     100770 :         aUserOptions.allowPunctuationOutsideMargin = ((const SfxBoolItem&)pNode->GetContentAttribs().GetItem( EE_PARA_HANGINGPUNCTUATION )).GetValue();
    1802                 :     100770 :         aUserOptions.allowHyphenateEnglish = sal_False;
    1803                 :            : 
    1804         [ +  - ]:     100770 :         i18n::LineBreakResults aLBR = _xBI->getLineBreak(
    1805 [ +  - ][ +  - ]:     100770 :             pNode->GetString(), nMaxBreakPos, aLocale, nMinBreakPos, aHyphOptions, aUserOptions );
                 [ +  - ]
    1806                 :     100770 :         nBreakPos = (sal_uInt16)aLBR.breakIndex;
    1807                 :            : 
    1808                 :            :         // BUG in I18N - under special condition (break behind field, #87327#) breakIndex is < nMinBreakPos
    1809         [ +  + ]:     100770 :         if ( nBreakPos < nMinBreakPos )
    1810                 :            :         {
    1811                 :      64369 :             nBreakPos = nMinBreakPos;
    1812                 :            :         }
    1813 [ -  + ][ #  # ]:      36401 :         else if ( ( nBreakPos > nMaxBreakPos ) && !aUserOptions.allowPunctuationOutsideMargin )
    1814                 :            :         {
    1815                 :            :             OSL_FAIL( "I18N: XBreakIterator::getLineBreak returns position > Max" );
    1816                 :          0 :             nBreakPos = nMaxBreakPos;
    1817                 :            :         }
    1818                 :            : 
    1819                 :            :         // nBreakPos can never be outside the portion, even not with hangig punctuation
    1820         [ -  + ]:     100770 :         if ( nBreakPos > nMaxBreakPos )
    1821                 :          0 :             nBreakPos = nMaxBreakPos;
    1822                 :            : 
    1823                 :            :         // BUG in I18N - the japanese dot is in the next line!
    1824                 :            :         // !!!  Test!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1825         [ +  + ]:     100770 :         if ( (nBreakPos + ( aUserOptions.allowPunctuationOutsideMargin ? 0 : 1 ) ) <= nMaxBreakPos )
    1826                 :            :         {
    1827 [ +  - ][ +  + ]:       7115 :             sal_Unicode cFirstInNextLine = ( (nBreakPos+1) < pNode->Len() ) ? pNode->GetChar( nBreakPos ) : 0;
                 [ +  - ]
    1828         [ -  + ]:       7115 :             if ( cFirstInNextLine == 12290 )
    1829                 :          0 :                 nBreakPos++;
    1830                 :            :         }
    1831                 :            : 
    1832         [ -  + ]:     100770 :         bHangingPunctuation = ( nBreakPos > nMaxBreakPos ) ? sal_True : sal_False;
    1833                 :     100770 :         pLine->SetHangingPunctuation( bHangingPunctuation );
    1834                 :            : 
    1835                 :            :         // Whether a separator or not, push the word after the separator through
    1836                 :            :         // hyphenation ... NMaxBreakPos is the last character that fits into
    1837                 :            :         // the line, nBreakPos is the beginning of the word.
    1838                 :            :         // There is a problem if the Doc is so narrow that a word is broken
    1839                 :            :         // into more than two lines ...
    1840 [ +  + ][ +  - ]:     100770 :         if ( !bHangingPunctuation && bCanHyphenate && GetHyphenator().is() )
         [ +  - ][ +  + ]
           [ +  +  #  # ]
                 [ +  - ]
    1841                 :            :         {
    1842         [ +  - ]:      98080 :             i18n::Boundary aBoundary = _xBI->getWordBoundary(
    1843 [ +  - ][ +  - ]:      98080 :                 pNode->GetString(), nBreakPos, GetLocale( EditPaM( pNode, nBreakPos ) ), ::com::sun::star::i18n::WordType::DICTIONARY_WORD, true);
         [ +  - ][ +  - ]
                 [ +  - ]
    1844                 :      98080 :             sal_uInt16 nWordStart = nBreakPos;
    1845                 :      98080 :             sal_uInt16 nWordEnd = (sal_uInt16) aBoundary.endPos;
    1846                 :            :             DBG_ASSERT( nWordEnd > nWordStart, "ImpBreakLine: Start >= End?" );
    1847                 :            : 
    1848                 :      98080 :             sal_uInt16 nWordLen = nWordEnd - nWordStart;
    1849 [ +  + ][ +  - ]:      98080 :             if ( ( nWordEnd >= nMaxBreakPos ) && ( nWordLen > 3 ) )
    1850                 :            :             {
    1851                 :            :                 // May happen, because getLineBreak may differ from getWordBoudary with DICTIONARY_WORD
    1852 [ +  - ][ +  - ]:      26445 :                 String aWord(pNode->GetString(), nWordStart, nWordLen);
    1853                 :      26445 :                 sal_uInt16 nMinTrail = nWordEnd-nMaxBreakPos+1; //+1: Before the dickey letter
    1854                 :      26445 :                 Reference< XHyphenatedWord > xHyphWord;
    1855         [ +  - ]:      26445 :                 if (xHyphenator.is())
    1856 [ +  - ][ +  - ]:      26445 :                     xHyphWord = xHyphenator->hyphenate( aWord, aLocale, aWord.Len() - nMinTrail, Sequence< PropertyValue >() );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1857         [ +  + ]:      26445 :                 if (xHyphWord.is())
    1858                 :            :                 {
    1859 [ +  - ][ +  - ]:        282 :                     sal_Bool bAlternate = xHyphWord->isAlternativeSpelling();
    1860 [ +  - ][ +  - ]:        282 :                     sal_uInt16 _nWordLen = 1 + xHyphWord->getHyphenPos();
    1861                 :            : 
    1862 [ +  - ][ +  - ]:        282 :                     if ( ( _nWordLen >= 2 ) && ( (nWordStart+_nWordLen) >= (pLine->GetStart() + 2 ) ) )
                 [ +  - ]
    1863                 :            :                     {
    1864         [ +  - ]:        282 :                         if ( !bAlternate )
    1865                 :            :                         {
    1866                 :        282 :                             bHyphenated = sal_True;
    1867                 :        282 :                             nBreakPos = nWordStart + _nWordLen;
    1868                 :            :                         }
    1869                 :            :                         else
    1870                 :            :                         {
    1871 [ #  # ][ #  # ]:          0 :                             String aAlt( xHyphWord->getHyphenatedWord() );
                 [ #  # ]
    1872                 :            : 
    1873                 :            :                             // We expect the two cases, which might exist now:
    1874                 :            :                             // 1) packen becomes pak-ken
    1875                 :            :                             // 2) Schiffahrt becomes Schiff-fahrt
    1876                 :            :                             // In case 1, a character has to be replaced
    1877                 :            :                             // in case 2 a character is added.
    1878                 :            :                             // The identification is complicated by long
    1879                 :            :                             // compound words because the Hyphenator separates
    1880                 :            :                             // all position of the word.
    1881                 :            :                             // "Schiffahrtsbrennesseln" -> "Schifffahrtsbrennnesseln"
    1882                 :            :                  // We can thus actually not directly connect the index of the
    1883                 :            :                             // AlternativeWord to aWord. The whole issue will be simplified
    1884                 :            :                             // by a function in the  Hyphenator as soon as AMA builds this in...
    1885                 :          0 :                             sal_uInt16 nAltStart = _nWordLen - 1;
    1886                 :          0 :                             sal_uInt16 nTxtStart = nAltStart - (aAlt.Len() - aWord.Len());
    1887                 :          0 :                             sal_uInt16 nTxtEnd = nTxtStart;
    1888                 :          0 :                             sal_uInt16 nAltEnd = nAltStart;
    1889                 :            : 
    1890                 :            :                             // The regions between the nStart and nEnd is the
    1891                 :            :                             // difference between alternative and original string.
    1892         [ #  # ]:          0 :                             while( nTxtEnd < aWord.Len() && nAltEnd < aAlt.Len() &&
           [ #  #  #  # ]
                 [ #  # ]
    1893                 :          0 :                                    aWord.GetChar(nTxtEnd) != aAlt.GetChar(nAltEnd) )
    1894                 :            :                             {
    1895                 :          0 :                                 ++nTxtEnd;
    1896                 :          0 :                                 ++nAltEnd;
    1897                 :            :                             }
    1898                 :            : 
    1899                 :            :                             // If a character is added, then we notice it now:
    1900         [ #  # ]:          0 :                             if( nAltEnd > nTxtEnd && nAltStart == nAltEnd &&
           [ #  #  #  # ]
                 [ #  # ]
    1901                 :          0 :                                 aWord.GetChar( nTxtEnd ) == aAlt.GetChar(nAltEnd) )
    1902                 :            :                             {
    1903                 :          0 :                                 ++nAltEnd;
    1904                 :          0 :                                 ++nTxtStart;
    1905                 :          0 :                                 ++nTxtEnd;
    1906                 :            :                             }
    1907                 :            : 
    1908                 :            :                             DBG_ASSERT( ( nAltEnd - nAltStart ) == 1, "Alternate: Wrong assumption!" );
    1909                 :            : 
    1910         [ #  # ]:          0 :                             if ( nTxtEnd > nTxtStart )
    1911                 :          0 :                                 cAlternateReplChar = aAlt.GetChar( nAltStart );
    1912                 :            :                             else
    1913                 :          0 :                                 cAlternateExtraChar = aAlt.GetChar( nAltStart );
    1914                 :            : 
    1915                 :          0 :                             bHyphenated = sal_True;
    1916                 :          0 :                             nBreakPos = nWordStart + nTxtStart;
    1917         [ #  # ]:          0 :                             if ( cAlternateReplChar )
    1918         [ #  # ]:          0 :                                 nBreakPos++;
    1919                 :            :                         }
    1920                 :            :                     }
    1921         [ +  - ]:      98080 :                 }
    1922                 :            :             }
    1923                 :            :         }
    1924                 :            : 
    1925         [ +  + ]:     100770 :         if ( nBreakPos <= pLine->GetStart() )
    1926                 :            :         {
    1927                 :            :             // No separator in line => Chop!
    1928                 :     100213 :             nBreakPos = nMaxBreakPos;
    1929                 :            :             // I18N nextCharacters !
    1930         [ +  + ]:     100213 :             if ( nBreakPos <= pLine->GetStart() )
    1931                 :      93552 :                 nBreakPos = pLine->GetStart() + 1;  // Otherwise infinite loop!
    1932 [ +  - ][ +  - ]:     100770 :         }
    1933                 :            :     }
    1934                 :            : 
    1935                 :            :     // the dickey portion is the end portion
    1936                 :     115869 :     pLine->SetEnd( nBreakPos );
    1937                 :            : 
    1938                 :     115869 :     sal_uInt16 nEndPortion = SplitTextPortion( pParaPortion, nBreakPos, pLine );
    1939                 :            : 
    1940 [ +  - ][ +  + ]:     115869 :     if ( !bCompressBlank && !bHangingPunctuation )
    1941                 :            :     {
    1942                 :            :         // When justification is not SVX_ADJUST_LEFT, it's important to compress
    1943                 :            :         // the trailing space even if there is enough room for the space...
    1944                 :            :         // Don't check for SVX_ADJUST_LEFT, doesn't matter to compress in this case too...
    1945                 :            :         DBG_ASSERT( nBreakPos > pLine->GetStart(), "ImpBreakLines - BreakPos not expected!" );
    1946         [ +  + ]:     100770 :         if ( pNode->GetChar( nBreakPos-1 ) == ' ' )
    1947                 :        272 :             bCompressBlank = sal_True;
    1948                 :            :     }
    1949                 :            : 
    1950 [ +  + ][ -  + ]:     115869 :     if ( bCompressBlank || bHangingPunctuation )
    1951                 :            :     {
    1952                 :      15371 :         const TextPortion* pTP = pParaPortion->GetTextPortions()[nEndPortion];
    1953                 :            :         DBG_ASSERT( pTP->GetKind() == PORTIONKIND_TEXT, "BlankRubber: No TextPortion!" );
    1954                 :            :         DBG_ASSERT( nBreakPos > pLine->GetStart(), "SplitTextPortion at the beginning of the line?" );
    1955                 :      15371 :         sal_uInt16 nPosInArray = nBreakPos - 1 - pLine->GetStart();
    1956 [ +  - ][ +  - ]:      15371 :         pTP->GetSize().Width() = ( nPosInArray && ( pTP->GetLen() > 1 ) ) ? pLine->GetCharPosArray()[ nPosInArray-1 ] : 0;
         [ +  - ][ +  + ]
    1957                 :      15371 :         pLine->GetCharPosArray()[ nPosInArray ] = pTP->GetSize().Width();
    1958                 :            :     }
    1959         [ +  + ]:     100498 :     else if ( bHyphenated )
    1960                 :            :     {
    1961                 :            :         // A portion for inserting the separator ...
    1962         [ +  - ]:        282 :         TextPortion* pHyphPortion = new TextPortion( 0 );
    1963                 :        282 :         pHyphPortion->GetKind() = PORTIONKIND_HYPHENATOR;
    1964         [ +  - ]:        282 :         String aHyphText(rtl::OUString(CH_HYPH));
    1965         [ -  + ]:        282 :         if ( cAlternateReplChar )
    1966                 :            :         {
    1967         [ #  # ]:          0 :             TextPortion* pPrev = pParaPortion->GetTextPortions()[nEndPortion];
    1968                 :            :             DBG_ASSERT( pPrev && pPrev->GetLen(), "Hyphenate: Prev portion?!" );
    1969                 :          0 :             pPrev->SetLen( pPrev->GetLen() - 1 );
    1970                 :          0 :             pHyphPortion->SetLen( 1 );
    1971                 :          0 :             pHyphPortion->SetExtraValue( cAlternateReplChar );
    1972                 :            :             // Correct width of the portion above:
    1973                 :          0 :             pPrev->GetSize().Width() =
    1974 [ #  # ][ #  # ]:          0 :                 pLine->GetCharPosArray()[ nBreakPos-1 - pLine->GetStart() - 1 ];
    1975                 :            :         }
    1976         [ -  + ]:        282 :         else if ( cAlternateExtraChar )
    1977                 :            :         {
    1978                 :          0 :             pHyphPortion->SetExtraValue( cAlternateExtraChar );
    1979 [ #  # ][ #  # ]:          0 :             aHyphText.Insert( rtl::OUString(cAlternateExtraChar), 0 );
                 [ #  # ]
    1980                 :            :         }
    1981                 :            : 
    1982                 :            :         // Determine the width of the Hyph-Portion:
    1983         [ +  - ]:        282 :         SvxFont aFont;
    1984         [ +  - ]:        282 :         SeekCursor( pParaPortion->GetNode(), nBreakPos, aFont );
    1985         [ +  - ]:        282 :         aFont.SetPhysFont( GetRefDevice() );
    1986         [ +  - ]:        282 :         pHyphPortion->GetSize().Height() = GetRefDevice()->GetTextHeight();
    1987         [ +  - ]:        282 :         pHyphPortion->GetSize().Width() = GetRefDevice()->GetTextWidth( aHyphText );
    1988                 :            : 
    1989 [ +  - ][ +  - ]:        282 :         pParaPortion->GetTextPortions().Insert(++nEndPortion, pHyphPortion);
                 [ +  - ]
    1990                 :            :     }
    1991                 :     115869 :     pLine->SetEndPortion( nEndPortion );
    1992                 :     115869 : }
    1993                 :            : 
    1994                 :        116 : void ImpEditEngine::ImpAdjustBlocks( ParaPortion* pParaPortion, EditLine* pLine, long nRemainingSpace )
    1995                 :            : {
    1996                 :            :     DBG_ASSERT( nRemainingSpace > 0, "AdjustBlocks: Somewhat too little..." );
    1997                 :            :     DBG_ASSERT( pLine, "AdjustBlocks: Line ?!" );
    1998 [ +  - ][ -  + ]:        116 :     if ( ( nRemainingSpace < 0 ) || pLine->IsEmpty() )
                 [ +  - ]
    1999                 :            :         return ;
    2000                 :            : 
    2001                 :        116 :     const sal_uInt16 nFirstChar = pLine->GetStart();
    2002                 :        116 :     const sal_uInt16 nLastChar = pLine->GetEnd() -1;    // Last points behind
    2003                 :        116 :     ContentNode* pNode = pParaPortion->GetNode();
    2004                 :            : 
    2005                 :            :     DBG_ASSERT( nLastChar < pNode->Len(), "AdjustBlocks: Out of range!" );
    2006                 :            : 
    2007                 :            :     // Search blanks or Kashidas...
    2008         [ +  - ]:        116 :     std::vector<sal_uInt16> aPositions;
    2009                 :        116 :     sal_uInt16 nLastScript = i18n::ScriptType::LATIN;
    2010         [ +  + ]:        448 :     for ( sal_uInt16 nChar = nFirstChar; nChar <= nLastChar; nChar++ )
    2011                 :            :     {
    2012         [ +  - ]:        332 :         EditPaM aPaM( pNode, nChar+1 );
    2013         [ +  - ]:        332 :         LanguageType eLang = GetLanguage(aPaM);
    2014         [ +  - ]:        332 :         sal_uInt16 nScript = GetScriptType(aPaM);
    2015         [ -  + ]:        332 :         if ( MsLangId::getPrimaryLanguage( eLang) == LANGUAGE_ARABIC_PRIMARY_ONLY )
    2016                 :            :             // Arabic script is handled later.
    2017                 :          0 :             continue;
    2018                 :            : 
    2019 [ +  - ][ +  + ]:        332 :         if ( pNode->GetChar(nChar) == ' ' )
    2020                 :            :         {
    2021                 :            :             // Normal latin script.
    2022         [ +  - ]:          8 :             aPositions.push_back( nChar );
    2023                 :            :         }
    2024         [ +  + ]:        324 :         else if (nChar > nFirstChar)
    2025                 :            :         {
    2026         [ -  + ]:        208 :             if (nLastScript == i18n::ScriptType::ASIAN)
    2027                 :            :             {
    2028                 :            :                 // Set break position between this and the last character if
    2029                 :            :                 // the last character is asian script.
    2030         [ #  # ]:          0 :                 aPositions.push_back( nChar-1 );
    2031                 :            :             }
    2032         [ -  + ]:        208 :             else if (nScript == i18n::ScriptType::ASIAN)
    2033                 :            :             {
    2034                 :            :                 // Set break position between a latin script and asian script.
    2035         [ #  # ]:          0 :                 aPositions.push_back( nChar-1 );
    2036                 :            :             }
    2037                 :            :         }
    2038                 :            : 
    2039                 :        332 :         nLastScript = nScript;
    2040                 :            :     }
    2041                 :            : 
    2042                 :            :     // Kashidas ?
    2043         [ +  - ]:        116 :     ImpFindKashidas( pNode, nFirstChar, nLastChar, aPositions );
    2044                 :            : 
    2045         [ +  + ]:        116 :     if ( aPositions.empty() )
    2046                 :            :         return;
    2047                 :            : 
    2048                 :            :     // If the last character is a blank, it is rejected!
    2049                 :            :     // The width must be distributed to the blockers in front...
    2050                 :            :     // But not if it is the only one.
    2051 [ +  - ][ +  - ]:         16 :     if ( ( pNode->GetChar( nLastChar ) == ' ' ) && ( aPositions.size() > 1 ) &&
           [ -  +  #  # ]
                 [ -  + ]
    2052 [ #  # ][ #  # ]:          8 :          ( MsLangId::getPrimaryLanguage( GetLanguage( EditPaM( pNode, nLastChar ) ) ) != LANGUAGE_ARABIC_PRIMARY_ONLY ) )
         [ -  + ][ #  # ]
    2053                 :            :     {
    2054         [ #  # ]:          0 :         aPositions.pop_back();
    2055                 :            :         sal_uInt16 nPortionStart, nPortion;
    2056         [ #  # ]:          0 :         nPortion = pParaPortion->GetTextPortions().FindPortion( nLastChar+1, nPortionStart );
    2057         [ #  # ]:          0 :         TextPortion* pLastPortion = pParaPortion->GetTextPortions()[ nPortion ];
    2058 [ #  # ][ #  # ]:          0 :         long nRealWidth = pLine->GetCharPosArray()[nLastChar-nFirstChar];
    2059                 :          0 :         long nBlankWidth = nRealWidth;
    2060         [ #  # ]:          0 :         if ( nLastChar > nPortionStart )
    2061 [ #  # ][ #  # ]:          0 :             nBlankWidth -= pLine->GetCharPosArray()[nLastChar-nFirstChar-1];
    2062                 :            :         // Possibly the blank has already been deducted in ImpBreakLine:
    2063         [ #  # ]:          0 :         if ( nRealWidth == pLastPortion->GetSize().Width() )
    2064                 :            :         {
    2065                 :            :             // For the last character the portion must stop behind the blank
    2066                 :            :             // => Simplify correction:
    2067                 :            :             DBG_ASSERT( ( nPortionStart + pLastPortion->GetLen() ) == ( nLastChar+1 ), "Blank actually not at the end of the portion!?");
    2068                 :          0 :             pLastPortion->GetSize().Width() -= nBlankWidth;
    2069                 :          0 :             nRemainingSpace += nBlankWidth;
    2070                 :            :         }
    2071 [ #  # ][ #  # ]:          0 :         pLine->GetCharPosArray()[nLastChar-nFirstChar] -= nBlankWidth;
    2072                 :            :     }
    2073                 :            : 
    2074                 :          8 :     size_t nGaps = aPositions.size();
    2075                 :          8 :     const long nMore4Everyone = nRemainingSpace / nGaps;
    2076                 :          8 :     long nSomeExtraSpace = nRemainingSpace - nMore4Everyone*nGaps;
    2077                 :            : 
    2078                 :            :     DBG_ASSERT( nSomeExtraSpace < (long)nGaps, "AdjustBlocks: ExtraSpace too large" );
    2079                 :            :     DBG_ASSERT( nSomeExtraSpace >= 0, "AdjustBlocks: ExtraSpace < 0 " );
    2080                 :            : 
    2081                 :            :     // Correct the positions in the Array and the portion widths:
    2082                 :            :     // Last character won't be considered ...
    2083 [ +  - ][ +  - ]:         16 :     for ( std::vector<sal_uInt16>::const_iterator it(aPositions.begin()); it != aPositions.end(); ++it )
         [ +  + ][ +  - ]
    2084                 :            :     {
    2085         [ +  - ]:          8 :         sal_uInt16 nChar = *it;
    2086         [ -  + ]:          8 :         if ( nChar < nLastChar )
    2087                 :            :         {
    2088                 :            :             sal_uInt16 nPortionStart, nPortion;
    2089         [ #  # ]:          0 :             nPortion = pParaPortion->GetTextPortions().FindPortion( nChar, nPortionStart, true );
    2090         [ #  # ]:          0 :             TextPortion* pLastPortion = pParaPortion->GetTextPortions()[ nPortion ];
    2091                 :            : 
    2092                 :            :             // The width of the portion:
    2093                 :          0 :             pLastPortion->GetSize().Width() += nMore4Everyone;
    2094         [ #  # ]:          0 :             if ( nSomeExtraSpace )
    2095                 :          0 :                 pLastPortion->GetSize().Width()++;
    2096                 :            : 
    2097                 :            :             // Correct positions in array
    2098                 :            :             // Even for kashidas just change positions, VCL will then draw the kashida automaticly
    2099                 :          0 :             sal_uInt16 nPortionEnd = nPortionStart + pLastPortion->GetLen();
    2100         [ #  # ]:          0 :             for ( sal_uInt16 _n = nChar; _n < nPortionEnd; _n++ )
    2101                 :            :             {
    2102 [ #  # ][ #  # ]:          0 :                 pLine->GetCharPosArray()[_n-nFirstChar] += nMore4Everyone;
    2103         [ #  # ]:          0 :                 if ( nSomeExtraSpace )
    2104 [ #  # ][ #  # ]:          0 :                     pLine->GetCharPosArray()[_n-nFirstChar]++;
    2105                 :            :             }
    2106                 :            : 
    2107         [ #  # ]:          0 :             if ( nSomeExtraSpace )
    2108                 :          0 :                 nSomeExtraSpace--;
    2109                 :            :         }
    2110                 :            :     }
    2111                 :            : 
    2112                 :            :     // Now the text width contains the extra width...
    2113         [ +  + ]:        116 :     pLine->SetTextWidth( pLine->GetTextWidth() + nRemainingSpace );
    2114                 :            : }
    2115                 :            : 
    2116                 :        116 : void ImpEditEngine::ImpFindKashidas( ContentNode* pNode, sal_uInt16 nStart, sal_uInt16 nEnd, std::vector<sal_uInt16>& rArray )
    2117                 :            : {
    2118                 :            :     // the search has to be performed on a per word base
    2119                 :            : 
    2120 [ +  - ][ +  - ]:        116 :     EditSelection aWordSel( EditPaM( pNode, nStart ) );
    2121 [ +  - ][ +  - ]:        116 :     aWordSel = SelectWord( aWordSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
    2122         [ +  + ]:        116 :     if ( aWordSel.Min().GetIndex() < nStart )
    2123                 :         70 :        aWordSel.Min().GetIndex() = nStart;
    2124                 :            : 
    2125 [ +  - ][ +  - ]:        232 :     while ( ( aWordSel.Min().GetNode() == pNode ) && ( aWordSel.Min().GetIndex() < nEnd ) )
         [ +  + ][ +  + ]
    2126                 :            :     {
    2127                 :        116 :         sal_uInt16 nSavPos = aWordSel.Max().GetIndex();
    2128         [ +  + ]:        116 :         if ( aWordSel.Max().GetIndex() > nEnd )
    2129                 :        108 :            aWordSel.Max().GetIndex() = nEnd;
    2130                 :            : 
    2131         [ +  - ]:        116 :         String aWord = GetSelected( aWordSel );
    2132                 :            : 
    2133                 :            :         // restore selection for proper iteration at the end of the function
    2134                 :        116 :         aWordSel.Max().GetIndex() = nSavPos;
    2135                 :            : 
    2136                 :        116 :         xub_StrLen nIdx = 0;
    2137                 :        116 :         xub_StrLen nKashidaPos = STRING_LEN;
    2138                 :            :         xub_Unicode cCh;
    2139                 :        116 :         xub_Unicode cPrevCh = 0;
    2140                 :            : 
    2141         [ +  + ]:        332 :         while ( nIdx < aWord.Len() )
    2142                 :            :         {
    2143                 :        216 :             cCh = aWord.GetChar( nIdx );
    2144                 :            : 
    2145                 :            :             // 1. Priority:
    2146                 :            :             // after user inserted kashida
    2147         [ -  + ]:        216 :             if ( 0x640 == cCh )
    2148                 :            :             {
    2149                 :          0 :                 nKashidaPos = aWordSel.Min().GetIndex() + nIdx;
    2150                 :          0 :                 break;
    2151                 :            :             }
    2152                 :            : 
    2153                 :            :             // 2. Priority:
    2154                 :            :             // after a Seen or Sad
    2155 [ +  + ][ +  - ]:        216 :             if ( nIdx + 1 < aWord.Len() &&
         [ -  + ][ -  + ]
    2156                 :            :                  ( 0x633 == cCh || 0x635 == cCh ) )
    2157                 :            :             {
    2158                 :          0 :                 nKashidaPos = aWordSel.Min().GetIndex() + nIdx;
    2159                 :          0 :                 break;
    2160                 :            :             }
    2161                 :            : 
    2162                 :            :             // 3. Priority:
    2163                 :            :             // before final form of Teh Marbuta, Hah, Dal
    2164                 :            :             // 4. Priority:
    2165                 :            :             // before final form of Alef, Lam or Kaf
    2166 [ +  + ][ +  + ]:        216 :             if ( nIdx && nIdx + 1 == aWord.Len() &&
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
                 [ -  + ]
    2167                 :            :                  ( 0x629 == cCh || 0x62D == cCh || 0x62F == cCh ||
    2168                 :            :                    0x627 == cCh || 0x644 == cCh || 0x643 == cCh ) )
    2169                 :            :             {
    2170                 :            :                 DBG_ASSERT( 0 != cPrevCh, "No previous character" );
    2171                 :            : 
    2172                 :            :                 // check if character is connectable to previous character,
    2173         [ #  # ]:          0 :                 if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
    2174                 :            :                 {
    2175                 :          0 :                     nKashidaPos = aWordSel.Min().GetIndex() + nIdx - 1;
    2176                 :          0 :                     break;
    2177                 :            :                 }
    2178                 :            :             }
    2179                 :            : 
    2180                 :            :             // 5. Priority:
    2181                 :            :             // before media Bah
    2182 [ +  + ][ +  + ]:        216 :             if ( nIdx && nIdx + 1 < aWord.Len() && 0x628 == cCh )
         [ -  + ][ -  + ]
    2183                 :            :             {
    2184                 :            :                 DBG_ASSERT( 0 != cPrevCh, "No previous character" );
    2185                 :            : 
    2186                 :            :                 // check if next character is Reh, Yeh or Alef Maksura
    2187                 :          0 :                 xub_Unicode cNextCh = aWord.GetChar( nIdx + 1 );
    2188                 :            : 
    2189 [ #  # ][ #  # ]:          0 :                 if ( 0x631 == cNextCh || 0x64A == cNextCh ||
                 [ #  # ]
    2190                 :            :                      0x649 == cNextCh )
    2191                 :            :                 {
    2192                 :            :                     // check if character is connectable to previous character,
    2193         [ #  # ]:          0 :                     if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
    2194                 :          0 :                         nKashidaPos = aWordSel.Min().GetIndex() + nIdx - 1;
    2195                 :            :                 }
    2196                 :            :             }
    2197                 :            : 
    2198                 :            :             // 6. Priority:
    2199                 :            :             // other connecting possibilities
    2200 [ +  + ][ +  + ]:        216 :             if ( nIdx && nIdx + 1 == aWord.Len() &&
         [ -  + ][ #  # ]
                 [ -  + ]
    2201                 :            :                  0x60C <= cCh && 0x6FE >= cCh )
    2202                 :            :             {
    2203                 :            :                 DBG_ASSERT( 0 != cPrevCh, "No previous character" );
    2204                 :            : 
    2205                 :            :                 // check if character is connectable to previous character,
    2206         [ #  # ]:          0 :                 if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
    2207                 :            :                 {
    2208                 :            :                     // only choose this position if we did not find
    2209                 :            :                     // a better one:
    2210         [ #  # ]:          0 :                     if ( STRING_LEN == nKashidaPos )
    2211                 :          0 :                         nKashidaPos = aWordSel.Min().GetIndex() + nIdx - 1;
    2212                 :          0 :                     break;
    2213                 :            :                 }
    2214                 :            :             }
    2215                 :            : 
    2216                 :            :             // Do not consider Fathatan, Dammatan, Kasratan, Fatha,
    2217                 :            :             // Damma, Kasra, Shadda and Sukun when checking if
    2218                 :            :             // a character can be connected to previous character.
    2219 [ -  + ][ #  # ]:        216 :             if ( cCh < 0x64B || cCh > 0x652 )
    2220                 :        216 :                 cPrevCh = cCh;
    2221                 :            : 
    2222                 :        216 :             ++nIdx;
    2223                 :            :         } // end of current word
    2224                 :            : 
    2225         [ -  + ]:        116 :         if ( STRING_LEN != nKashidaPos )
    2226         [ #  # ]:          0 :             rArray.push_back( nKashidaPos );
    2227                 :            : 
    2228 [ +  - ][ +  - ]:        116 :         aWordSel = WordRight( aWordSel.Max(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
    2229 [ +  - ][ +  - ]:        116 :         aWordSel = SelectWord( aWordSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
    2230         [ +  - ]:        116 :     }
    2231                 :        116 : }
    2232                 :            : 
    2233                 :     115869 : sal_uInt16 ImpEditEngine::SplitTextPortion( ParaPortion* pPortion, sal_uInt16 nPos, EditLine* pCurLine )
    2234                 :            : {
    2235                 :            :     DBG_ASSERT( pPortion, "SplitTextPortion: Which ?" );
    2236                 :            : 
    2237                 :            :     // The portion at nPos is split, if there is not a transition at nPos anyway
    2238         [ -  + ]:     115869 :     if ( nPos == 0 )
    2239                 :          0 :         return 0;
    2240                 :            : 
    2241                 :            :     sal_uInt16 nSplitPortion;
    2242                 :     115869 :     sal_uInt16 nTmpPos = 0;
    2243                 :     115869 :     TextPortion* pTextPortion = NULL;
    2244                 :     115869 :     sal_uInt16 nPortions = pPortion->GetTextPortions().Count();
    2245         [ +  - ]:     519732 :     for ( nSplitPortion = 0; nSplitPortion < nPortions; nSplitPortion++ )
    2246                 :            :     {
    2247                 :     519732 :         TextPortion* pTP = pPortion->GetTextPortions()[nSplitPortion];
    2248                 :     519732 :         nTmpPos = nTmpPos + pTP->GetLen();
    2249         [ +  + ]:     519732 :         if ( nTmpPos >= nPos )
    2250                 :            :         {
    2251         [ +  + ]:     115869 :             if ( nTmpPos == nPos )  // then nothing needs to be split
    2252                 :            :             {
    2253                 :      21710 :                 return nSplitPortion;
    2254                 :            :             }
    2255                 :      94159 :             pTextPortion = pTP;
    2256                 :      94159 :             break;
    2257                 :            :         }
    2258                 :            :     }
    2259                 :            : 
    2260                 :            :     DBG_ASSERT( pTextPortion, "Position outside the area!" );
    2261                 :            :     DBG_ASSERT( pTextPortion->GetKind() == PORTIONKIND_TEXT, "SplitTextPortion: No TextPortion!" );
    2262                 :            : 
    2263                 :      94159 :     sal_uInt16 nOverlapp = nTmpPos - nPos;
    2264                 :      94159 :     pTextPortion->GetLen() = pTextPortion->GetLen() - nOverlapp;
    2265                 :      94159 :     TextPortion* pNewPortion = new TextPortion( nOverlapp );
    2266                 :      94159 :     pPortion->GetTextPortions().Insert(nSplitPortion+1, pNewPortion);
    2267                 :            :     // Set sizes
    2268         [ +  - ]:      94159 :     if ( pCurLine )
    2269                 :            :     {
    2270                 :            :         // No new GetTextSize, instead use values from the Array:
    2271                 :            :         DBG_ASSERT( nPos > pCurLine->GetStart(), "SplitTextPortion at the beginning of the line?" );
    2272                 :      94159 :         pTextPortion->GetSize().Width() = pCurLine->GetCharPosArray()[ nPos-pCurLine->GetStart()-1 ];
    2273                 :            : 
    2274 [ #  # ][ -  + ]:      94159 :         if ( pTextPortion->GetExtraInfos() && pTextPortion->GetExtraInfos()->bCompressed )
                 [ -  + ]
    2275                 :            :         {
    2276                 :            :             // We need the original size from the portion
    2277         [ #  # ]:          0 :             sal_uInt16 nTxtPortionStart = pPortion->GetTextPortions().GetStartPos( nSplitPortion );
    2278         [ #  # ]:          0 :                SvxFont aTmpFont( pPortion->GetNode()->GetCharAttribs().GetDefFont() );
    2279         [ #  # ]:          0 :             SeekCursor( pPortion->GetNode(), nTxtPortionStart+1, aTmpFont );
    2280         [ #  # ]:          0 :             aTmpFont.SetPhysFont( GetRefDevice() );
    2281         [ #  # ]:          0 :             GetRefDevice()->Push( PUSH_TEXTLANGUAGE );
    2282         [ #  # ]:          0 :             ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
    2283 [ #  # ][ #  # ]:          0 :             Size aSz = aTmpFont.QuickGetTextSize( GetRefDevice(), pPortion->GetNode()->GetString(), nTxtPortionStart, pTextPortion->GetLen(), NULL );
    2284         [ #  # ]:          0 :             GetRefDevice()->Pop();
    2285         [ #  # ]:          0 :             pTextPortion->GetExtraInfos()->nOrgWidth = aSz.Width();
    2286                 :            :         }
    2287                 :            :     }
    2288                 :            :     else
    2289                 :          0 :         pTextPortion->GetSize().Width() = (-1);
    2290                 :            : 
    2291                 :     115869 :     return nSplitPortion;
    2292                 :            : }
    2293                 :            : 
    2294                 :     114287 : void ImpEditEngine::CreateTextPortions( ParaPortion* pParaPortion, sal_uInt16& rStart )
    2295                 :            : {
    2296                 :     114287 :     sal_uInt16 nStartPos = rStart;
    2297                 :     114287 :     ContentNode* pNode = pParaPortion->GetNode();
    2298                 :            :     DBG_ASSERT( pNode->Len(), "CreateTextPortions should not be used for empty paragraphs!" );
    2299                 :            : 
    2300         [ +  - ]:     114287 :     ::std::set< sal_uInt32 > aPositions;
    2301         [ +  - ]:     114287 :     aPositions.insert( 0 );
    2302                 :            : 
    2303                 :     114287 :     sal_uInt16 nAttr = 0;
    2304 [ +  - ][ +  - ]:     114287 :     EditCharAttrib* pAttrib = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
    2305         [ +  + ]:     180603 :     while ( pAttrib )
    2306                 :            :     {
    2307                 :            :         // Insert Start and End into the Array...
    2308                 :            :         // The Insert method does not allow for duplicate values....
    2309         [ +  - ]:      66316 :         aPositions.insert( pAttrib->GetStart() );
    2310         [ +  - ]:      66316 :         aPositions.insert( pAttrib->GetEnd() );
    2311                 :      66316 :         nAttr++;
    2312 [ +  - ][ +  - ]:      66316 :         pAttrib = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
    2313                 :            :     }
    2314 [ +  - ][ +  - ]:     114287 :     aPositions.insert( pNode->Len() );
    2315                 :            : 
    2316         [ -  + ]:     114287 :     if ( pParaPortion->aScriptInfos.empty() )
    2317 [ #  # ][ #  # ]:          0 :         ((ImpEditEngine*)this)->InitScriptTypes( GetParaPortions().GetPos( pParaPortion ) );
    2318                 :            : 
    2319                 :     114287 :     const ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
    2320         [ +  + ]:     228847 :     for ( size_t nT = 0; nT < rTypes.size(); nT++ )
    2321 [ +  - ][ +  - ]:     114560 :         aPositions.insert( rTypes[nT].nStartPos );
    2322                 :            : 
    2323                 :     114287 :     const WritingDirectionInfos& rWritingDirections = pParaPortion->aWritingDirectionInfos;
    2324         [ +  + ]:     228574 :     for ( size_t nD = 0; nD < rWritingDirections.size(); nD++ )
    2325 [ +  - ][ +  - ]:     114287 :         aPositions.insert( rWritingDirections[nD].nStartPos );
    2326                 :            : 
    2327 [ -  + ][ #  # ]:     114287 :     if ( mpIMEInfos && mpIMEInfos->nLen && mpIMEInfos->pAttribs && ( mpIMEInfos->aPos.GetNode() == pNode ) )
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
    2328                 :            :     {
    2329                 :          0 :         sal_uInt16 nLastAttr = 0xFFFF;
    2330         [ #  # ]:          0 :         for( sal_uInt16 n = 0; n < mpIMEInfos->nLen; n++ )
    2331                 :            :         {
    2332         [ #  # ]:          0 :             if ( mpIMEInfos->pAttribs[n] != nLastAttr )
    2333                 :            :             {
    2334         [ #  # ]:          0 :                 aPositions.insert( mpIMEInfos->aPos.GetIndex() + n );
    2335                 :          0 :                 nLastAttr = mpIMEInfos->pAttribs[n];
    2336                 :            :             }
    2337                 :            :         }
    2338         [ #  # ]:          0 :         aPositions.insert( mpIMEInfos->aPos.GetIndex() + mpIMEInfos->nLen );
    2339                 :            :     }
    2340                 :            : 
    2341                 :            :     // From ... Delete:
    2342                 :            :     // Unfortunately, the number of text portions does not have to match
    2343                 :            :     // aPositions.Count(), since there might be line breaks...
    2344                 :     114287 :     sal_uInt16 nPortionStart = 0;
    2345                 :     114287 :     sal_uInt16 nInvPortion = 0;
    2346                 :            :     sal_uInt16 nP;
    2347 [ +  - ][ +  + ]:     114287 :     for ( nP = 0; nP < pParaPortion->GetTextPortions().Count(); nP++ )
    2348                 :            :     {
    2349         [ +  - ]:       3728 :         const TextPortion* pTmpPortion = pParaPortion->GetTextPortions()[nP];
    2350                 :       3728 :         nPortionStart = nPortionStart + pTmpPortion->GetLen();
    2351         [ +  - ]:       3728 :         if ( nPortionStart >= nStartPos )
    2352                 :            :         {
    2353                 :       3728 :             nPortionStart = nPortionStart - pTmpPortion->GetLen();
    2354                 :       3728 :             rStart = nPortionStart;
    2355                 :       3728 :             nInvPortion = nP;
    2356                 :       3728 :             break;
    2357                 :            :         }
    2358                 :            :     }
    2359                 :            :     DBG_ASSERT( nP < pParaPortion->GetTextPortions().Count() || !pParaPortion->GetTextPortions().Count(), "Nothing to delete: CreateTextPortions" );
    2360 [ -  + ][ #  # ]:     114287 :     if ( nInvPortion && ( nPortionStart+pParaPortion->GetTextPortions()[nInvPortion]->GetLen() > nStartPos ) )
         [ #  # ][ -  + ]
    2361                 :            :     {
    2362                 :            :         // prefer one in front ...
    2363                 :            :         // But only if it was in the middle of the portion of, otherwise it
    2364                 :            :         // might be the only one in the row in front!
    2365                 :          0 :         nInvPortion--;
    2366         [ #  # ]:          0 :         nPortionStart = nPortionStart - pParaPortion->GetTextPortions()[nInvPortion]->GetLen();
    2367                 :            :     }
    2368         [ +  - ]:     114287 :     pParaPortion->GetTextPortions().DeleteFromPortion( nInvPortion );
    2369                 :            : 
    2370                 :            :     // A portion may also have been formed by a line break:
    2371         [ +  - ]:     114287 :     aPositions.insert( nPortionStart );
    2372                 :            : 
    2373         [ +  - ]:     114287 :     ::std::set< sal_uInt32 >::iterator nInvPos = aPositions.find(  nPortionStart );
    2374                 :            :     DBG_ASSERT( (nInvPos != aPositions.end()), "InvPos ?!" );
    2375                 :            : 
    2376                 :     114287 :     ::std::set< sal_uInt32 >::iterator i = nInvPos;
    2377         [ +  - ]:     114287 :     ++i;
    2378 [ +  - ][ +  + ]:     230304 :     while ( i != aPositions.end() )
    2379                 :            :     {
    2380 [ +  - ][ +  - ]:     116017 :         TextPortion* pNew = new TextPortion( static_cast<sal_uInt16>(*i++) - static_cast<sal_uInt16>(*nInvPos++) );
         [ +  - ][ +  - ]
                 [ +  - ]
    2381         [ +  - ]:     116017 :         pParaPortion->GetTextPortions().Append(pNew);
    2382                 :            :     }
    2383                 :            : 
    2384                 :     114287 :     DBG_ASSERT( pParaPortion->GetTextPortions().Count(), "No Portions?!" );
    2385                 :            : #if OSL_DEBUG_LEVEL > 2
    2386                 :            :     OSL_ENSURE( pParaPortion->DbgCheckTextPortions(), "Portion is broken?" );
    2387                 :            : #endif
    2388                 :     114287 : }
    2389                 :            : 
    2390                 :         56 : void ImpEditEngine::RecalcTextPortion( ParaPortion* pParaPortion, sal_uInt16 nStartPos, short nNewChars )
    2391                 :            : {
    2392                 :            :     DBG_ASSERT( pParaPortion->GetTextPortions().Count(), "No Portions!" );
    2393                 :            :     DBG_ASSERT( nNewChars, "RecalcTextPortion with Diff == 0" );
    2394                 :            : 
    2395                 :         56 :     ContentNode* const pNode = pParaPortion->GetNode();
    2396         [ +  - ]:         56 :     if ( nNewChars > 0 )
    2397                 :            :     {
    2398                 :            :         // If an Attribute begins/ends at nStartPos, then a new portion starts
    2399                 :            :         // otherwise the portion is extended at nStartPos.
    2400 [ +  - ][ +  + ]:         56 :         if ( pNode->GetCharAttribs().HasBoundingAttrib( nStartPos ) || IsScriptChange( EditPaM( pNode, nStartPos ) ) )
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
           [ +  -  #  # ]
    2401                 :            :         {
    2402                 :         56 :             sal_uInt16 nNewPortionPos = 0;
    2403         [ -  + ]:         56 :             if ( nStartPos )
    2404                 :          0 :                 nNewPortionPos = SplitTextPortion( pParaPortion, nStartPos ) + 1;
    2405                 :            : 
    2406                 :            :             // A blank portion may be here, if the paragraph was empty,
    2407                 :            :             // or if a line was created by a hard line break.
    2408   [ +  -  +  - ]:        112 :             if ( ( nNewPortionPos < pParaPortion->GetTextPortions().Count() ) &&
                 [ +  - ]
    2409                 :         56 :                     !pParaPortion->GetTextPortions()[nNewPortionPos]->GetLen() )
    2410                 :            :             {
    2411                 :            :                 DBG_ASSERT( pParaPortion->GetTextPortions()[nNewPortionPos]->GetKind() == PORTIONKIND_TEXT, "the empty portion was no TextPortion!" );
    2412                 :            :                 sal_uInt16 & r =
    2413                 :         56 :                     pParaPortion->GetTextPortions()[nNewPortionPos]->GetLen();
    2414                 :         56 :                 r = r + nNewChars;
    2415                 :            :             }
    2416                 :            :             else
    2417                 :            :             {
    2418                 :          0 :                 TextPortion* pNewPortion = new TextPortion( nNewChars );
    2419                 :          0 :                 pParaPortion->GetTextPortions().Insert(nNewPortionPos, pNewPortion);
    2420                 :            :             }
    2421                 :            :         }
    2422                 :            :         else
    2423                 :            :         {
    2424                 :            :             sal_uInt16 nPortionStart;
    2425                 :          0 :             const sal_uInt16 nTP = pParaPortion->GetTextPortions().
    2426         [ #  # ]:          0 :                 FindPortion( nStartPos, nPortionStart );
    2427         [ #  # ]:          0 :             TextPortion* const pTP = pParaPortion->GetTextPortions()[ nTP ];
    2428                 :            :             DBG_ASSERT( pTP, "RecalcTextPortion: Portion not found"  );
    2429                 :          0 :             pTP->GetLen() = pTP->GetLen() + nNewChars;
    2430                 :          0 :             pTP->GetSize().Width() = (-1);
    2431                 :            :         }
    2432                 :            :     }
    2433                 :            :     else
    2434                 :            :     {
    2435                 :            :         // Shrink or remove portion if necessary.
    2436                 :            :         // Before calling this method it must be ensured that no portions were
    2437                 :            :         // in the deleted area!
    2438                 :            : 
    2439                 :            :         // There must be no portions extending into the area or portions starting in
    2440                 :            :         // the area, so it must be:
    2441                 :            :         //    nStartPos <= nPos <= nStartPos - nNewChars(neg.)
    2442                 :          0 :         sal_uInt16 nPortion = 0;
    2443                 :          0 :         sal_uInt16 nPos = 0;
    2444                 :          0 :         sal_uInt16 nEnd = nStartPos-nNewChars;
    2445                 :          0 :         sal_uInt16 nPortions = pParaPortion->GetTextPortions().Count();
    2446                 :          0 :         TextPortion* pTP = 0;
    2447         [ #  # ]:          0 :         for ( nPortion = 0; nPortion < nPortions; nPortion++ )
    2448                 :            :         {
    2449                 :          0 :             pTP = pParaPortion->GetTextPortions()[ nPortion ];
    2450         [ #  # ]:          0 :             if ( ( nPos+pTP->GetLen() ) > nStartPos )
    2451                 :            :             {
    2452                 :            :                 DBG_ASSERT( nPos <= nStartPos, "Wrong Start!" );
    2453                 :            :                 DBG_ASSERT( nPos+pTP->GetLen() >= nEnd, "Wrong End!" );
    2454                 :          0 :                 break;
    2455                 :            :             }
    2456                 :          0 :             nPos = nPos + pTP->GetLen();
    2457                 :            :         }
    2458                 :            :         DBG_ASSERT( pTP, "RecalcTextPortion: Portion not found" );
    2459 [ #  # ][ #  # ]:          0 :         if ( ( nPos == nStartPos ) && ( (nPos+pTP->GetLen()) == nEnd ) )
                 [ #  # ]
    2460                 :            :         {
    2461                 :            :             // Remove portion;
    2462                 :          0 :             sal_uInt8 nType = pTP->GetKind();
    2463                 :          0 :             pParaPortion->GetTextPortions().Remove( nPortion );
    2464         [ #  # ]:          0 :             if ( nType == PORTIONKIND_LINEBREAK )
    2465                 :            :             {
    2466                 :          0 :                 TextPortion* pNext = pParaPortion->GetTextPortions()[ nPortion ];
    2467 [ #  # ][ #  # ]:          0 :                 if ( pNext && !pNext->GetLen() )
                 [ #  # ]
    2468                 :            :                 {
    2469                 :            :                     // Remove dummy portion
    2470                 :          0 :                     pParaPortion->GetTextPortions().Remove( nPortion );
    2471                 :            :                 }
    2472                 :            :             }
    2473                 :            :         }
    2474                 :            :         else
    2475                 :            :         {
    2476                 :            :             DBG_ASSERT( pTP->GetLen() > (-nNewChars), "Portion too small to shrink! ");
    2477                 :          0 :             pTP->GetLen() = pTP->GetLen() + nNewChars;
    2478                 :            :         }
    2479                 :            : 
    2480                 :          0 :         sal_uInt16 nPortionCount = pParaPortion->GetTextPortions().Count();
    2481                 :            :         assert( nPortionCount );
    2482         [ #  # ]:          0 :         if (nPortionCount)
    2483                 :            :         {
    2484                 :            :             // No HYPHENATOR portion is allowed to get stuck right at the end...
    2485                 :          0 :             sal_uInt16 nLastPortion = nPortionCount - 1;
    2486                 :          0 :             pTP = pParaPortion->GetTextPortions()[nLastPortion];
    2487         [ #  # ]:          0 :             if ( pTP->GetKind() == PORTIONKIND_HYPHENATOR )
    2488                 :            :             {
    2489                 :            :                 // Discard portion; if possible, correct the ones before,
    2490                 :            :                 // if the Hyphenator portion has swallowed one character...
    2491 [ #  # ][ #  # ]:          0 :                 if ( nLastPortion && pTP->GetLen() )
                 [ #  # ]
    2492                 :            :                 {
    2493                 :          0 :                     TextPortion* pPrev = pParaPortion->GetTextPortions()[nLastPortion - 1];
    2494                 :            :                     DBG_ASSERT( pPrev->GetKind() == PORTIONKIND_TEXT, "Portion?!" );
    2495                 :          0 :                     pPrev->SetLen( pPrev->GetLen() + pTP->GetLen() );
    2496                 :          0 :                     pPrev->GetSize().Width() = (-1);
    2497                 :            :                 }
    2498                 :          0 :                 pParaPortion->GetTextPortions().Remove( nLastPortion );
    2499                 :            :             }
    2500                 :            :         }
    2501                 :            :     }
    2502                 :            : #if OSL_DEBUG_LEVEL > 2
    2503                 :            :     OSL_ENSURE( pParaPortion->DbgCheckTextPortions(), "Portions are broken?" );
    2504                 :            : #endif
    2505                 :         56 : }
    2506                 :            : 
    2507                 :     353510 : void ImpEditEngine::SetTextRanger( TextRanger* pRanger )
    2508                 :            : {
    2509         [ -  + ]:     353510 :     if ( pTextRanger != pRanger )
    2510                 :            :     {
    2511         [ #  # ]:          0 :         delete pTextRanger;
    2512                 :          0 :         pTextRanger = pRanger;
    2513                 :            : 
    2514         [ #  # ]:          0 :         for ( sal_uInt16 nPara = 0; nPara < GetParaPortions().Count(); nPara++ )
    2515                 :            :         {
    2516                 :          0 :             ParaPortion* pParaPortion = GetParaPortions()[nPara];
    2517                 :          0 :             pParaPortion->MarkSelectionInvalid( 0, pParaPortion->GetNode()->Len() );
    2518                 :          0 :             pParaPortion->GetLines().Reset();
    2519                 :            :         }
    2520                 :            : 
    2521                 :          0 :         FormatFullDoc();
    2522                 :          0 :         UpdateViews( GetActiveView() );
    2523 [ #  # ][ #  # ]:          0 :         if ( GetUpdateMode() && GetActiveView() )
                 [ #  # ]
    2524                 :          0 :             pActiveView->ShowCursor(false, false);
    2525                 :            :     }
    2526                 :     353510 : }
    2527                 :            : 
    2528                 :     143220 : void ImpEditEngine::SetVertical( sal_Bool bVertical )
    2529                 :            : {
    2530         [ -  + ]:     143220 :     if ( IsVertical() != bVertical )
    2531                 :            :     {
    2532                 :          0 :         GetEditDoc().SetVertical( bVertical );
    2533                 :          0 :         sal_Bool bUseCharAttribs = ( aStatus.GetControlWord() & EE_CNTRL_USECHARATTRIBS ) ? sal_True : sal_False;
    2534                 :          0 :         GetEditDoc().CreateDefFont( bUseCharAttribs );
    2535         [ #  # ]:          0 :         if ( IsFormatted() )
    2536                 :            :         {
    2537                 :          0 :             FormatFullDoc();
    2538                 :          0 :             UpdateViews( GetActiveView() );
    2539                 :            :         }
    2540                 :            :     }
    2541                 :     143220 : }
    2542                 :            : 
    2543                 :      96755 : void ImpEditEngine::SetFixedCellHeight( sal_Bool bUseFixedCellHeight )
    2544                 :            : {
    2545         [ +  + ]:      96755 :     if ( IsFixedCellHeight() != bUseFixedCellHeight )
    2546                 :            :     {
    2547                 :         12 :         GetEditDoc().SetFixedCellHeight( bUseFixedCellHeight );
    2548         [ +  - ]:         12 :         if ( IsFormatted() )
    2549                 :            :         {
    2550                 :         12 :             FormatFullDoc();
    2551                 :         12 :             UpdateViews( GetActiveView() );
    2552                 :            :         }
    2553                 :            :     }
    2554                 :      96755 : }
    2555                 :            : 
    2556                 :     653796 : void ImpEditEngine::SeekCursor( ContentNode* pNode, sal_uInt16 nPos, SvxFont& rFont, OutputDevice* pOut, sal_uInt16 nIgnoreWhich )
    2557                 :            : {
    2558                 :            :     // It was planned, SeekCursor( nStartPos, nEndPos, ... ), so that it would
    2559                 :            :     // only be searched anew at the StartPosition.
    2560                 :            :     // Problem: There would be two lists to consider/handle:
    2561                 :            :     // OrderedByStart,OrderedByEnd.
    2562                 :            : 
    2563         [ +  + ]:     653796 :     if ( nPos > pNode->Len() )
    2564                 :       2603 :         nPos = pNode->Len();
    2565                 :            : 
    2566                 :     653796 :     rFont = pNode->GetCharAttribs().GetDefFont();
    2567                 :            : 
    2568         [ +  - ]:     653796 :     short nScriptType = GetScriptType( EditPaM( pNode, nPos ) );
    2569 [ +  + ][ -  + ]:     653796 :     if ( ( nScriptType == i18n::ScriptType::ASIAN ) || ( nScriptType == i18n::ScriptType::COMPLEX ) )
    2570                 :            :     {
    2571 [ +  - ][ +  - ]:         42 :         const SvxFontItem& rFontItem = (const SvxFontItem&)pNode->GetContentAttribs().GetItem( GetScriptItemId( EE_CHAR_FONTINFO, nScriptType ) );
    2572 [ +  - ][ +  - ]:         42 :         rFont.SetName( rFontItem.GetFamilyName() );
    2573         [ +  - ]:         42 :         rFont.SetFamily( rFontItem.GetFamily() );
    2574         [ +  - ]:         42 :         rFont.SetPitch( rFontItem.GetPitch() );
    2575         [ +  - ]:         42 :         rFont.SetCharSet( rFontItem.GetCharSet() );
    2576         [ +  - ]:         42 :         Size aSz( rFont.GetSize() );
    2577 [ +  - ][ +  - ]:         42 :         aSz.Height() = ((const SvxFontHeightItem&)pNode->GetContentAttribs().GetItem( GetScriptItemId( EE_CHAR_FONTHEIGHT, nScriptType ) ) ).GetHeight();
    2578         [ +  - ]:         42 :         rFont.SetSize( aSz );
    2579 [ +  - ][ +  - ]:         42 :         rFont.SetWeight( ((const SvxWeightItem&)pNode->GetContentAttribs().GetItem( GetScriptItemId( EE_CHAR_WEIGHT, nScriptType ))).GetWeight() );
                 [ +  - ]
    2580 [ +  - ][ +  - ]:         42 :         rFont.SetItalic( ((const SvxPostureItem&)pNode->GetContentAttribs().GetItem( GetScriptItemId( EE_CHAR_ITALIC, nScriptType ))).GetPosture() );
                 [ +  - ]
    2581 [ +  - ][ +  - ]:         42 :         rFont.SetLanguage( ((const SvxLanguageItem&)pNode->GetContentAttribs().GetItem( GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType ))).GetLanguage() );
                 [ +  - ]
    2582                 :            :     }
    2583                 :            : 
    2584                 :     653796 :     sal_uInt16 nRelWidth = ((const SvxCharScaleWidthItem&)pNode->GetContentAttribs().GetItem( EE_CHAR_FONTWIDTH)).GetValue();
    2585                 :            : 
    2586         [ +  + ]:     653796 :     if ( pOut )
    2587                 :            :     {
    2588                 :      21118 :         const SvxUnderlineItem& rTextLineColor = (const SvxUnderlineItem&)pNode->GetContentAttribs().GetItem( EE_CHAR_UNDERLINE );
    2589         [ +  + ]:      21118 :         if ( rTextLineColor.GetColor() != COL_TRANSPARENT )
    2590                 :       2662 :             pOut->SetTextLineColor( rTextLineColor.GetColor() );
    2591                 :            :         else
    2592                 :      18456 :             pOut->SetTextLineColor();
    2593                 :            :     }
    2594                 :            : 
    2595         [ +  + ]:     653796 :     if ( pOut )
    2596                 :            :     {
    2597                 :      21118 :         const SvxOverlineItem& rOverlineColor = (const SvxOverlineItem&)pNode->GetContentAttribs().GetItem( EE_CHAR_OVERLINE );
    2598         [ +  + ]:      21118 :         if ( rOverlineColor.GetColor() != COL_TRANSPARENT )
    2599                 :       2429 :             pOut->SetOverlineColor( rOverlineColor.GetColor() );
    2600                 :            :         else
    2601                 :      18689 :             pOut->SetOverlineColor();
    2602                 :            :     }
    2603                 :            : 
    2604                 :     653796 :     const SvxLanguageItem* pCJKLanguageItem = NULL;
    2605                 :            : 
    2606         [ +  - ]:     653796 :     if ( aStatus.UseCharAttribs() )
    2607                 :            :     {
    2608                 :     653796 :         CharAttribList::AttribsType& rAttribs = pNode->GetCharAttribs().GetAttribs();
    2609                 :     653796 :         size_t nAttr = 0;
    2610                 :     653796 :         EditCharAttrib* pAttrib = GetAttrib(rAttribs, nAttr);
    2611 [ +  + ][ +  + ]:     941215 :         while ( pAttrib && ( pAttrib->GetStart() <= nPos ) )
                 [ +  + ]
    2612                 :            :         {
    2613                 :            :             // when seeking, ignore attributes which start there! Empty attributes
    2614                 :            :             // are considered (used) as these are just set. But do not use empty
    2615                 :            :             // attributes: When just set and empty => no effect on font
    2616                 :            :             // In a blank paragraph, set characters take effect immediately.
    2617   [ +  -  +  +  :     867423 :             if ( ( pAttrib->Which() != nIgnoreWhich ) &&
             +  +  +  + ]
                 [ +  + ]
    2618                 :     553011 :                  ( ( ( pAttrib->GetStart() < nPos ) && ( pAttrib->GetEnd() >= nPos ) )
    2619                 :      26993 :                      || ( !pNode->Len() ) ) )
    2620                 :            :             {
    2621                 :            :                 DBG_ASSERT( ( pAttrib->Which() >= EE_CHAR_START ) && ( pAttrib->Which() <= EE_FEATURE_END ), "Invalid Attribute in Seek() " );
    2622         [ +  + ]:     281982 :                 if ( IsScriptItemValid( pAttrib->Which(), nScriptType ) )
    2623                 :            :                 {
    2624                 :     197153 :                     pAttrib->SetFont( rFont, pOut );
    2625                 :            :                     // #i1550# hard color attrib should win over text color from field
    2626         [ +  + ]:     197153 :                     if ( pAttrib->Which() == EE_FEATURE_FIELD )
    2627                 :            :                     {
    2628                 :       7680 :                         EditCharAttrib* pColorAttr = pNode->GetCharAttribs().FindAttrib( EE_CHAR_COLOR, nPos );
    2629         [ +  + ]:       7680 :                         if ( pColorAttr )
    2630                 :        504 :                             pColorAttr->SetFont( rFont, pOut );
    2631                 :            :                     }
    2632                 :            :                 }
    2633         [ +  + ]:     281982 :                 if ( pAttrib->Which() == EE_CHAR_FONTWIDTH )
    2634                 :       8959 :                     nRelWidth = ((const SvxCharScaleWidthItem*)pAttrib->GetItem())->GetValue();
    2635         [ +  + ]:     281982 :                 if ( pAttrib->Which() == EE_CHAR_LANGUAGE_CJK )
    2636                 :       8473 :                     pCJKLanguageItem = (const SvxLanguageItem*) pAttrib->GetItem();
    2637                 :            :             }
    2638                 :     287419 :             pAttrib = GetAttrib( rAttribs, ++nAttr );
    2639                 :            :         }
    2640                 :            :     }
    2641                 :            : 
    2642         [ +  + ]:     653796 :     if ( !pCJKLanguageItem )
    2643                 :     645323 :         pCJKLanguageItem = (const SvxLanguageItem*) &pNode->GetContentAttribs().GetItem( EE_CHAR_LANGUAGE_CJK );
    2644                 :            : 
    2645                 :     653796 :     rFont.SetCJKContextLanguage( pCJKLanguageItem->GetLanguage() );
    2646                 :            : 
    2647 [ -  + ][ #  # ]:     653796 :     if ( rFont.GetKerning() && IsKernAsianPunctuation() && ( nScriptType == i18n::ScriptType::ASIAN ) )
         [ -  + ][ +  + ]
    2648                 :          0 :         rFont.SetKerning( rFont.GetKerning() | KERNING_ASIAN );
    2649                 :            : 
    2650         [ -  + ]:     653796 :     if ( aStatus.DoNotUseColors() )
    2651                 :            :     {
    2652         [ #  # ]:          0 :         rFont.SetColor( /* rColorItem.GetValue() */ COL_BLACK );
    2653                 :            :     }
    2654                 :            : 
    2655 [ +  + ][ +  + ]:     653796 :     if ( aStatus.DoStretch() || ( nRelWidth != 100 ) )
                 [ +  + ]
    2656                 :            :     {
    2657                 :            :         // For the current Output device, because otherwise if RefDev=Printer its looks
    2658                 :            :         // ugly on the screen!
    2659         [ +  + ]:      12197 :         OutputDevice* pDev = pOut ? pOut : GetRefDevice();
    2660         [ +  - ]:      12197 :         rFont.SetPhysFont( pDev );
    2661         [ +  - ]:      12197 :         FontMetric aMetric( pDev->GetFontMetric() );
    2662                 :            :         // For the height do not consider the metrics, because it will go
    2663                 :            :         // wrong at Superscript/Subscript.
    2664 [ +  - ][ +  - ]:      12197 :         Size aRealSz( aMetric.GetSize().Width(), rFont.GetSize().Height() );
    2665         [ +  + ]:      12197 :         if ( aStatus.DoStretch() )
    2666                 :            :         {
    2667         [ -  + ]:        682 :             if ( nStretchY != 100 )
    2668                 :            :             {
    2669                 :          0 :                 aRealSz.Height() *= nStretchY;
    2670                 :          0 :                 aRealSz.Height() /= 100;
    2671                 :            :             }
    2672         [ -  + ]:        682 :             if ( nStretchX != 100 )
    2673                 :            :             {
    2674 [ #  # ][ #  # ]:          0 :                 if ( nStretchX == nStretchY &&
    2675                 :            :                      nRelWidth == 100 )
    2676                 :            :                 {
    2677                 :          0 :                     aRealSz.Width() = 0;
    2678                 :            :                 }
    2679                 :            :                 else
    2680                 :            :                 {
    2681                 :          0 :                     aRealSz.Width() *= nStretchX;
    2682                 :          0 :                     aRealSz.Width() /= 100;
    2683                 :            : 
    2684                 :            :                     // Also the Kerning: (long due to handle Interim results)
    2685                 :          0 :                     long nKerning = rFont.GetFixKerning();
    2686                 :            : /*
    2687                 :            :   The consideration was: If negative kerning, but StretchX = 200
    2688                 :            :   => Do not double the kerning, thus pull the letters closer together
    2689                 :            :   ---------------------------
    2690                 :            :   Kern  StretchX    =>Kern
    2691                 :            :   ---------------------------
    2692                 :            :   >0        <100        < (Proportional)
    2693                 :            :   <0        <100        < (Proportional)
    2694                 :            :   >0        >100        > (Proportional)
    2695                 :            :   <0        >100        < (The amount, thus disproportional)
    2696                 :            : */
    2697 [ #  # ][ #  # ]:          0 :                     if ( ( nKerning < 0  ) && ( nStretchX > 100 ) )
    2698                 :            :                     {
    2699                 :            :                         // disproportional
    2700                 :          0 :                         nKerning *= 100;
    2701                 :          0 :                         nKerning /= nStretchX;
    2702                 :            :                     }
    2703         [ #  # ]:          0 :                     else if ( nKerning )
    2704                 :            :                     {
    2705                 :            :                         // Proportional
    2706                 :          0 :                         nKerning *= nStretchX;
    2707                 :          0 :                         nKerning /= 100;
    2708                 :            :                     }
    2709                 :          0 :                     rFont.SetFixKerning( (short)nKerning );
    2710                 :            :                 }
    2711                 :            :             }
    2712                 :            :         }
    2713         [ +  + ]:      12197 :         if ( nRelWidth != 100 )
    2714                 :            :         {
    2715                 :      11515 :             aRealSz.Width() *= nRelWidth;
    2716                 :      11515 :             aRealSz.Width() /= 100;
    2717                 :            :         }
    2718 [ +  - ][ +  - ]:      12197 :         rFont.SetSize( aRealSz );
    2719                 :            :         // Font is not restored ...
    2720                 :            :     }
    2721                 :            : 
    2722 [ +  - ][ +  + ]:     653796 :     if ( ( ( rFont.GetColor() == COL_AUTO ) || ( IsForceAutoColor() ) ) && pOut )
         [ -  + ][ +  + ]
                 [ +  - ]
           [ +  +  #  # ]
    2723                 :            :     {
    2724                 :            :         // #i75566# Do not use AutoColor when printing OR Pdf export
    2725                 :      14481 :         const bool bPrinting(OUTDEV_PRINTER == pOut->GetOutDevType());
    2726                 :      14481 :         const bool bPDFExporting(0 != pOut->GetPDFWriter());
    2727                 :            : 
    2728 [ +  - ][ +  - ]:      14481 :         if ( IsAutoColorEnabled() && !bPrinting && !bPDFExporting)
         [ +  - ][ +  - ]
    2729                 :            :         {
    2730                 :            :             // Never use WindowTextColor on the printer
    2731         [ +  - ]:      14481 :             rFont.SetColor( GetAutoColor() );
    2732                 :            :         }
    2733                 :            :         else
    2734                 :            :         {
    2735 [ #  # ][ #  # ]:          0 :             if ( ( GetBackgroundColor() != COL_AUTO ) && GetBackgroundColor().IsDark() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  #  
             #  #  #  # ]
    2736         [ #  # ]:          0 :                 rFont.SetColor( COL_WHITE );
    2737                 :            :             else
    2738         [ #  # ]:          0 :                 rFont.SetColor( COL_BLACK );
    2739                 :            :         }
    2740                 :            :     }
    2741                 :            : 
    2742 [ -  + ][ #  # ]:     653796 :     if ( mpIMEInfos && mpIMEInfos->pAttribs && ( mpIMEInfos->aPos.GetNode() == pNode ) &&
           [ #  #  #  #  
           #  # ][ -  + ]
    2743                 :          0 :         ( nPos > mpIMEInfos->aPos.GetIndex() ) && ( nPos <= ( mpIMEInfos->aPos.GetIndex() + mpIMEInfos->nLen ) ) )
    2744                 :            :     {
    2745                 :          0 :         sal_uInt16 nAttr = mpIMEInfos->pAttribs[ nPos - mpIMEInfos->aPos.GetIndex() - 1 ];
    2746         [ #  # ]:          0 :         if ( nAttr & EXTTEXTINPUT_ATTR_UNDERLINE )
    2747                 :          0 :             rFont.SetUnderline( UNDERLINE_SINGLE );
    2748         [ #  # ]:          0 :         else if ( nAttr & EXTTEXTINPUT_ATTR_BOLDUNDERLINE )
    2749                 :          0 :             rFont.SetUnderline( UNDERLINE_BOLD );
    2750         [ #  # ]:          0 :         else if ( nAttr & EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE )
    2751                 :          0 :             rFont.SetUnderline( UNDERLINE_DOTTED );
    2752         [ #  # ]:          0 :         else if ( nAttr & EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE )
    2753                 :          0 :             rFont.SetUnderline( UNDERLINE_DOTTED );
    2754         [ #  # ]:          0 :         else if ( nAttr & EXTTEXTINPUT_ATTR_REDTEXT )
    2755         [ #  # ]:          0 :             rFont.SetColor( Color( COL_RED ) );
    2756         [ #  # ]:          0 :         else if ( nAttr & EXTTEXTINPUT_ATTR_HALFTONETEXT )
    2757         [ #  # ]:          0 :             rFont.SetColor( Color( COL_LIGHTGRAY ) );
    2758         [ #  # ]:          0 :         if ( nAttr & EXTTEXTINPUT_ATTR_HIGHLIGHT )
    2759                 :            :         {
    2760                 :          0 :             const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    2761                 :          0 :             rFont.SetColor( rStyleSettings.GetHighlightTextColor() );
    2762                 :          0 :             rFont.SetFillColor( rStyleSettings.GetHighlightColor() );
    2763                 :          0 :             rFont.SetTransparent( sal_False );
    2764                 :            :         }
    2765         [ #  # ]:          0 :         else if ( nAttr & EXTTEXTINPUT_ATTR_GRAYWAVELINE )
    2766                 :            :         {
    2767                 :          0 :             rFont.SetUnderline( UNDERLINE_WAVE );
    2768         [ #  # ]:          0 :             if( pOut )
    2769         [ #  # ]:          0 :                 pOut->SetTextLineColor( Color( COL_LIGHTGRAY ) );
    2770                 :            :         }
    2771                 :            :     }
    2772                 :     653796 : }
    2773                 :            : 
    2774                 :     420740 : void ImpEditEngine::RecalcFormatterFontMetrics( FormatterFontMetric& rCurMetrics, SvxFont& rFont )
    2775                 :            : {
    2776                 :            :     // for line height at high / low first without Propr!
    2777                 :     420740 :     sal_uInt16 nPropr = rFont.GetPropr();
    2778                 :            :     DBG_ASSERT( ( nPropr == 100 ) || rFont.GetEscapement(), "Propr without Escape?!" );
    2779         [ +  + ]:     420740 :     if ( nPropr != 100 )
    2780                 :            :     {
    2781                 :       3901 :         rFont.SetPropr( 100 );
    2782         [ +  - ]:       3901 :         rFont.SetPhysFont( pRefDev );
    2783                 :            :     }
    2784                 :            :     sal_uInt16 nAscent, nDescent;
    2785                 :            : 
    2786         [ +  - ]:     420740 :     FontMetric aMetric( pRefDev->GetFontMetric() );
    2787         [ +  - ]:     420740 :     nAscent = (sal_uInt16)aMetric.GetAscent();
    2788         [ +  + ]:     420740 :     if ( IsAddExtLeading() )
    2789                 :            :         nAscent = sal::static_int_cast< sal_uInt16 >(
    2790         [ +  - ]:        303 :             nAscent + aMetric.GetExtLeading() );
    2791         [ +  - ]:     420740 :     nDescent = (sal_uInt16)aMetric.GetDescent();
    2792                 :            : 
    2793         [ +  + ]:     420740 :     if ( IsFixedCellHeight() )
    2794                 :            :     {
    2795         [ +  - ]:       1146 :         nAscent = sal::static_int_cast< sal_uInt16 >( rFont.GetHeight() );
    2796         [ +  - ]:       1146 :         nDescent= sal::static_int_cast< sal_uInt16 >( ImplCalculateFontIndependentLineSpacing( rFont.GetHeight() ) - nAscent );
    2797                 :            :     }
    2798                 :            :     else
    2799                 :            :     {
    2800 [ +  - ][ +  - ]:     419594 :         sal_uInt16 nIntLeading = ( aMetric.GetIntLeading() > 0 ) ? (sal_uInt16)aMetric.GetIntLeading() : 0;
                 [ +  - ]
    2801                 :            :         // Fonts without leading cause problems
    2802 [ -  + ][ #  # ]:     419594 :         if ( ( nIntLeading == 0 ) && ( pRefDev->GetOutDevType() == OUTDEV_PRINTER ) )
                 [ -  + ]
    2803                 :            :         {
    2804                 :            :             // Lets see what Leading one gets on the screen
    2805         [ #  # ]:          0 :             VirtualDevice* pVDev = GetVirtualDevice( pRefDev->GetMapMode(), pRefDev->GetDrawMode() );
    2806         [ #  # ]:          0 :             rFont.SetPhysFont( pVDev );
    2807 [ #  # ][ #  # ]:          0 :             aMetric = pVDev->GetFontMetric();
                 [ #  # ]
    2808                 :            : 
    2809                 :            :             // This is so that the Leading does not count itself out again,
    2810                 :            :             // if the whole line has the font, nTmpLeading.
    2811         [ #  # ]:          0 :             nAscent = (sal_uInt16)aMetric.GetAscent();
    2812         [ #  # ]:          0 :             nDescent = (sal_uInt16)aMetric.GetDescent();
    2813                 :            :         }
    2814                 :            :     }
    2815         [ +  + ]:     420740 :     if ( nAscent > rCurMetrics.nMaxAscent )
    2816                 :     418794 :         rCurMetrics.nMaxAscent = nAscent;
    2817         [ +  + ]:     420740 :     if ( nDescent > rCurMetrics.nMaxDescent )
    2818                 :     418794 :         rCurMetrics.nMaxDescent= nDescent;
    2819                 :            :     // Special treatment of high/low:
    2820         [ +  + ]:     420740 :     if ( rFont.GetEscapement() )
    2821                 :            :     {
    2822                 :            :         // Now in consideration of Escape/Propr
    2823                 :            :         // possibly enlarge Ascent or Descent
    2824         [ +  - ]:       6006 :         short nDiff = (short)(rFont.GetSize().Height()*rFont.GetEscapement()/100L);
    2825         [ +  - ]:       6006 :         if ( rFont.GetEscapement() > 0 )
    2826                 :            :         {
    2827                 :       6006 :             nAscent = (sal_uInt16) (((long)nAscent)*nPropr/100 + nDiff);
    2828         [ +  + ]:       6006 :             if ( nAscent > rCurMetrics.nMaxAscent )
    2829                 :       2018 :                 rCurMetrics.nMaxAscent = nAscent;
    2830                 :            :         }
    2831                 :            :         else    // has to be < 0
    2832                 :            :         {
    2833                 :          0 :             nDescent = (sal_uInt16) (((long)nDescent)*nPropr/100 - nDiff);
    2834         [ #  # ]:          0 :             if ( nDescent > rCurMetrics.nMaxDescent )
    2835                 :          0 :                 rCurMetrics.nMaxDescent= nDescent;
    2836                 :            :         }
    2837         [ +  - ]:     420740 :     }
    2838                 :     420740 : }
    2839                 :            : 
    2840                 :      16003 : void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRec, Point aStartPos, sal_Bool bStripOnly, short nOrientation )
    2841                 :            : {
    2842 [ -  + ][ #  # ]:      16003 :     if ( !GetUpdateMode() && !bStripOnly )
                 [ +  - ]
    2843                 :            :         return;
    2844                 :            : 
    2845         [ -  + ]:      16003 :     if ( !IsFormatted() )
    2846         [ #  # ]:          0 :         FormatDoc();
    2847                 :            : 
    2848                 :      16003 :     long nFirstVisXPos = - pOutDev->GetMapMode().GetOrigin().X();
    2849                 :      16003 :     long nFirstVisYPos = - pOutDev->GetMapMode().GetOrigin().Y();
    2850                 :            : 
    2851                 :      16003 :     const EditLine* pLine = NULL;
    2852                 :      16003 :     Point aTmpPos;
    2853                 :      16003 :     Point aRedLineTmpPos;
    2854                 :            :     DBG_ASSERT( GetParaPortions().Count(), "No ParaPortion?!" );
    2855 [ +  - ][ +  - ]:      16003 :     SvxFont aTmpFont( GetParaPortions()[0]->GetNode()->GetCharAttribs().GetDefFont() );
    2856         [ +  - ]:      16003 :     Font aOldFont( pOutDev->GetFont() );
    2857 [ -  + ][ #  # ]:      16003 :     vcl::PDFExtOutDevData* pPDFExtOutDevData = PTR_CAST( vcl::PDFExtOutDevData, pOutDev->GetExtOutDevData() );
         [ #  # ][ #  # ]
    2858                 :            : 
    2859                 :            :     // In the case of rotated text is aStartPos considered TopLeft because
    2860                 :            :     // other information is missing, and since the whole object is shown anyway
    2861                 :            :     // un-scrolled.
    2862                 :            :     // The rectangle is infinite.
    2863                 :      16003 :     Point aOrigin( aStartPos );
    2864                 :      16003 :     double nCos = 0.0, nSin = 0.0;
    2865         [ +  + ]:      16003 :     if ( nOrientation )
    2866                 :            :     {
    2867                 :        659 :         double nRealOrientation = nOrientation*F_PI1800;
    2868                 :        659 :         nCos = cos( nRealOrientation );
    2869                 :        659 :         nSin = sin( nRealOrientation );
    2870                 :            :     }
    2871                 :            : 
    2872                 :            :     // #110496# Added some more optional metafile comments. This
    2873                 :            :     // change: factored out some duplicated code.
    2874                 :      16003 :     GDIMetaFile* pMtf = pOutDev->GetConnectMetaFile();
    2875                 :      16003 :     const bool bMetafileValid( pMtf != NULL );
    2876                 :            : 
    2877         [ +  - ]:      16003 :     long nVertLineSpacing = CalcVertLineSpacing(aStartPos);
    2878                 :            : 
    2879                 :            :     // --------------------------------------------------
    2880                 :            :     // Over all the paragraphs ...
    2881                 :            :     // --------------------------------------------------
    2882 [ +  - ][ +  + ]:      33434 :     for ( sal_uInt16 n = 0; n < GetParaPortions().Count(); n++ )
    2883                 :            :     {
    2884         [ +  - ]:      18187 :         const ParaPortion* pPortion = GetParaPortions()[n];
    2885                 :            :         DBG_ASSERT( pPortion, "NULL-Pointer in TokenList in Paint" );
    2886                 :            :         // if when typing idle formatting,  asynchronous Paint.
    2887                 :            :         // Invisible Portions may be invalid.
    2888 [ +  - ][ -  + ]:      18187 :         if ( pPortion->IsVisible() && pPortion->IsInvalid() )
                 [ -  + ]
    2889                 :            :             return;
    2890                 :            : 
    2891         [ -  + ]:      18187 :         if ( pPDFExtOutDevData )
    2892         [ #  # ]:          0 :             pPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::Paragraph );
    2893                 :            : 
    2894                 :      18187 :         long nParaHeight = pPortion->GetHeight();
    2895 [ +  - ][ +  -  :      54561 :         if ( pPortion->IsVisible() && (
          +  -  -  +  #  
                #  #  # ]
    2896                 :      36374 :                 ( !IsVertical() && ( ( aStartPos.Y() + nParaHeight ) > aClipRec.Top() ) ) ||
    2897                 :          0 :                 ( IsVertical() && ( ( aStartPos.X() - nParaHeight ) < aClipRec.Right() ) ) ) )
    2898                 :            : 
    2899                 :            :         {
    2900                 :            :             // --------------------------------------------------
    2901                 :            :             // Over the lines of the paragraph ...
    2902                 :            :             // --------------------------------------------------
    2903         [ +  - ]:      18187 :             sal_uInt16 nLines = pPortion->GetLines().Count();
    2904                 :      18187 :             sal_uInt16 nLastLine = nLines-1;
    2905                 :            : 
    2906         [ +  - ]:      18187 :             if ( !IsVertical() )
    2907                 :      18187 :                 aStartPos.Y() += pPortion->GetFirstLineOffset();
    2908                 :            :             else
    2909                 :          0 :                 aStartPos.X() -= pPortion->GetFirstLineOffset();
    2910                 :            : 
    2911                 :      18187 :             Point aParaStart( aStartPos );
    2912                 :            : 
    2913         [ +  - ]:      18187 :             const SvxLineSpacingItem& rLSItem = ((const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL ));
    2914                 :      18187 :             sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
    2915         [ +  + ]:      18187 :                                 ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
    2916         [ +  + ]:      38433 :             for ( sal_uInt16 nLine = 0; nLine < nLines; nLine++ )
    2917                 :            :             {
    2918         [ +  - ]:      21002 :                 pLine = pPortion->GetLines()[nLine];
    2919                 :            :                 DBG_ASSERT( pLine, "NULL-Pointer in the line iterator in UpdateViews" );
    2920                 :      21002 :                 aTmpPos = aStartPos;
    2921         [ +  - ]:      21002 :                 if ( !IsVertical() )
    2922                 :            :                 {
    2923                 :      21002 :                     aTmpPos.X() += pLine->GetStartPosX();
    2924                 :      21002 :                     aTmpPos.Y() += pLine->GetMaxAscent();
    2925                 :      21002 :                     aStartPos.Y() += pLine->GetHeight();
    2926         [ +  + ]:      21002 :                     if (nLine != nLastLine)
    2927                 :       2815 :                         aStartPos.Y() += nVertLineSpacing;
    2928                 :            :                 }
    2929                 :            :                 else
    2930                 :            :                 {
    2931                 :          0 :                     aTmpPos.Y() += pLine->GetStartPosX();
    2932                 :          0 :                     aTmpPos.X() -= pLine->GetMaxAscent();
    2933                 :          0 :                     aStartPos.X() -= pLine->GetHeight();
    2934         [ #  # ]:          0 :                     if (nLine != nLastLine)
    2935                 :          0 :                         aStartPos.X() -= nVertLineSpacing;
    2936                 :            :                 }
    2937                 :            : 
    2938 [ +  - ][ -  +  :      21002 :                 if ( ( !IsVertical() && ( aStartPos.Y() > aClipRec.Top() ) )
             #  #  #  # ]
                 [ +  - ]
    2939                 :          0 :                     || ( IsVertical() && aStartPos.X() < aClipRec.Right() ) )
    2940                 :            :                 {
    2941                 :            :                     // Why not just also call when stripping portions? This will give the correct values
    2942                 :            :                     // and needs no position corrections in OutlinerEditEng::DrawingText which tries to call
    2943                 :            :                     // PaintBullet correctly; exactly what GetEditEnginePtr()->PaintingFirstLine
    2944                 :            :                     // does, too. No change for not-layouting (painting).
    2945         [ +  + ]:      21002 :                     if(0 == nLine) // && !bStripOnly)
    2946                 :            :                     {
    2947         [ +  - ]:      18187 :                         GetEditEnginePtr()->PaintingFirstLine( n, aParaStart, aTmpPos.Y(), aOrigin, nOrientation, pOutDev );
    2948                 :            :                     }
    2949                 :            : 
    2950                 :            :                     // --------------------------------------------------
    2951                 :            :                     // Over the Portions of the line ...
    2952                 :            :                     // --------------------------------------------------
    2953                 :      21002 :                     sal_uInt16 nIndex = pLine->GetStart();
    2954                 :      21002 :                     bool bParsingFields = false;
    2955                 :      21002 :                     ::std::vector< sal_Int32 >::iterator itSubLines;
    2956         [ +  + ]:      42157 :                     for ( sal_uInt16 y = pLine->GetStartPortion(); y <= pLine->GetEndPortion(); y++ )
    2957                 :            :                     {
    2958                 :            :                         DBG_ASSERT( pPortion->GetTextPortions().Count(), "Line without Textportion in Paint!" );
    2959         [ +  - ]:      21155 :                         const TextPortion* pTextPortion = pPortion->GetTextPortions()[y];
    2960                 :            :                         DBG_ASSERT( pTextPortion, "NULL-Pointer in Portion iterator in UpdateViews" );
    2961                 :            : 
    2962         [ +  - ]:      21155 :                         long nPortionXOffset = GetPortionXOffset( pPortion, pLine, y );
    2963         [ +  - ]:      21155 :                         if ( !IsVertical() )
    2964                 :            :                         {
    2965                 :      21155 :                             aTmpPos.X() = aStartPos.X() + nPortionXOffset;
    2966         [ +  + ]:      21155 :                             if ( aTmpPos.X() > aClipRec.Right() )
    2967                 :         31 :                                 break;  // No further output in line necessary
    2968                 :            :                         }
    2969                 :            :                         else
    2970                 :            :                         {
    2971                 :          0 :                             aTmpPos.Y() = aStartPos.Y() + nPortionXOffset;
    2972         [ #  # ]:          0 :                             if ( aTmpPos.Y() > aClipRec.Bottom() )
    2973                 :          0 :                                 break;  // No further output in line necessary
    2974                 :            :                         }
    2975                 :            : 
    2976      [ +  -  + ]:      21124 :                         switch ( pTextPortion->GetKind() )
    2977                 :            :                         {
    2978                 :            :                             case PORTIONKIND_TEXT:
    2979                 :            :                             case PORTIONKIND_FIELD:
    2980                 :            :                             case PORTIONKIND_HYPHENATOR:
    2981                 :            :                             {
    2982         [ +  - ]:      21118 :                                 SeekCursor( pPortion->GetNode(), nIndex+1, aTmpFont, pOutDev );
    2983                 :            : 
    2984                 :      21118 :                                 sal_Bool bDrawFrame = sal_False;
    2985                 :            : 
    2986 [ +  + ][ +  - ]:      42246 :                                 if ( ( pTextPortion->GetKind() == PORTIONKIND_FIELD ) && !aTmpFont.IsTransparent() &&
           [ +  +  +  - ]
           [ +  +  +  -  
           +  - ][ +  + ]
    2987 [ +  - ][ +  + ]:      21126 :                                      ( GetBackgroundColor() != COL_AUTO ) && GetBackgroundColor().IsDark() &&
         [ +  + ][ +  + ]
           [ #  #  #  #  
                   #  # ]
    2988                 :          2 :                                      ( IsAutoColorEnabled() && ( pOutDev->GetOutDevType() != OUTDEV_PRINTER ) ) )
    2989                 :            :                                 {
    2990         [ +  - ]:          1 :                                     aTmpFont.SetTransparent( sal_True );
    2991         [ +  - ]:          1 :                                     pOutDev->SetFillColor();
    2992 [ +  - ][ +  - ]:          1 :                                     pOutDev->SetLineColor( GetAutoColor() );
    2993                 :          1 :                                     bDrawFrame = sal_True;
    2994                 :            :                                 }
    2995                 :            : 
    2996                 :            : #if OSL_DEBUG_LEVEL > 2
    2997                 :            :                                 if ( pTextPortion->GetKind() == PORTIONKIND_HYPHENATOR )
    2998                 :            :                                 {
    2999                 :            :                                     aTmpFont.SetFillColor( COL_LIGHTGRAY );
    3000                 :            :                                     aTmpFont.SetTransparent( sal_False );
    3001                 :            :                                 }
    3002                 :            :                                 if ( pTextPortion->GetRightToLeft()  )
    3003                 :            :                                 {
    3004                 :            :                                     aTmpFont.SetFillColor( COL_LIGHTGRAY );
    3005                 :            :                                     aTmpFont.SetTransparent( sal_False );
    3006                 :            :                                 }
    3007                 :            :                                 else if ( GetScriptType( EditPaM( pPortion->GetNode(), nIndex+1 ) ) == i18n::ScriptType::COMPLEX )
    3008                 :            :                                 {
    3009                 :            :                                     aTmpFont.SetFillColor( COL_LIGHTCYAN );
    3010                 :            :                                     aTmpFont.SetTransparent( sal_False );
    3011                 :            :                                 }
    3012                 :            : #endif
    3013         [ +  - ]:      21118 :                                 aTmpFont.SetPhysFont( pOutDev );
    3014                 :            : 
    3015                 :            :                                 // #114278# Saving both layout mode and language (since I'm
    3016                 :            :                                 // potentially changing both)
    3017         [ +  - ]:      21118 :                                 pOutDev->Push( PUSH_TEXTLAYOUTMODE|PUSH_TEXTLANGUAGE );
    3018         [ +  - ]:      21118 :                                 ImplInitLayoutMode( pOutDev, n, nIndex );
    3019         [ +  - ]:      21118 :                                 ImplInitDigitMode( pOutDev, 0, 0, 0, aTmpFont.GetLanguage() );
    3020                 :            : 
    3021         [ +  - ]:      21118 :                                 XubString aText;
    3022                 :      21118 :                                 sal_uInt16 nTextStart = 0;
    3023                 :      21118 :                                 sal_uInt16 nTextLen = 0;
    3024                 :      21118 :                                 const sal_Int32* pDXArray = 0;
    3025                 :      21118 :                                 sal_Int32* pTmpDXArray = 0;
    3026                 :            : 
    3027         [ +  + ]:      21118 :                                 if ( pTextPortion->GetKind() == PORTIONKIND_TEXT )
    3028                 :            :                                 {
    3029 [ +  - ][ +  - ]:      20016 :                                     aText = pPortion->GetNode()->GetString();
    3030                 :      20016 :                                     nTextStart = nIndex;
    3031                 :      20016 :                                     nTextLen = pTextPortion->GetLen();
    3032 [ +  + ][ +  - ]:      20016 :                                     if (!pLine->GetCharPosArray().empty())
    3033 [ +  - ][ +  - ]:      18588 :                                         pDXArray = &pLine->GetCharPosArray()[0]+( nIndex-pLine->GetStart() );
    3034                 :            : 
    3035                 :            :                                     // Paint control characters (#i55716#)
    3036         [ +  + ]:      20016 :                                     if ( aStatus.MarkFields() )
    3037                 :            :                                     {
    3038                 :            :                                         xub_StrLen nTmpIdx;
    3039                 :       2487 :                                         const xub_StrLen nTmpEnd = nTextStart + pTextPortion->GetLen();
    3040                 :            : 
    3041         [ +  + ]:      11795 :                                         for ( nTmpIdx = nTextStart; nTmpIdx <= nTmpEnd ; ++nTmpIdx )
    3042                 :            :                                         {
    3043                 :       9308 :                                             const sal_Unicode cChar = ( nTmpIdx != aText.Len() && ( nTmpIdx != nTextStart || 0 == nTextStart ) ) ?
    3044                 :       6821 :                                                                         aText.GetChar( nTmpIdx ) :
    3045 [ +  + ][ +  + ]:       9308 :                                                                         0;
                 [ +  + ]
    3046                 :            : 
    3047 [ +  - ][ -  + ]:       9308 :                                             if ( 0x200B == cChar || 0x2060 == cChar )
    3048                 :            :                                             {
    3049                 :          0 :                                                 const rtl::OUString aBlank( ' ' );
    3050 [ #  # ][ #  # ]:          0 :                                                 long nHalfBlankWidth = aTmpFont.QuickGetTextSize( pOutDev, aBlank, 0, 1, 0 ).Width() / 2;
                 [ #  # ]
    3051                 :            : 
    3052                 :            :                                                 const long nAdvanceX = ( nTmpIdx == nTmpEnd ?
    3053         [ #  # ]:          0 :                                                                          pTextPortion->GetSize().Width() :
    3054         [ #  # ]:          0 :                                                                          pDXArray[ nTmpIdx - nTextStart ] ) - nHalfBlankWidth;
    3055                 :          0 :                                                 const long nAdvanceY = -pLine->GetMaxAscent();
    3056                 :            : 
    3057                 :          0 :                                                 Point aTopLeftRectPos( aTmpPos );
    3058         [ #  # ]:          0 :                                                 if ( !IsVertical() )
    3059                 :            :                                                 {
    3060                 :          0 :                                                     aTopLeftRectPos.X() += nAdvanceX;
    3061                 :          0 :                                                     aTopLeftRectPos.Y() += nAdvanceY;
    3062                 :            :                                                 }
    3063                 :            :                                                 else
    3064                 :            :                                                 {
    3065                 :          0 :                                                     aTopLeftRectPos.Y() += nAdvanceX;
    3066                 :          0 :                                                     aTopLeftRectPos.X() -= nAdvanceY;
    3067                 :            :                                                 }
    3068                 :            : 
    3069                 :          0 :                                                 Point aBottomRightRectPos( aTopLeftRectPos );
    3070         [ #  # ]:          0 :                                                 if ( !IsVertical() )
    3071                 :            :                                                 {
    3072                 :          0 :                                                     aBottomRightRectPos.X() += 2 * nHalfBlankWidth;
    3073                 :          0 :                                                     aBottomRightRectPos.Y() += pLine->GetHeight();
    3074                 :            :                                                 }
    3075                 :            :                                                 else
    3076                 :            :                                                 {
    3077                 :          0 :                                                     aBottomRightRectPos.X() -= pLine->GetHeight();
    3078                 :          0 :                                                     aBottomRightRectPos.Y() += 2 * nHalfBlankWidth;
    3079                 :            :                                                 }
    3080                 :            : 
    3081         [ #  # ]:          0 :                                                 pOutDev->Push( PUSH_FILLCOLOR );
    3082         [ #  # ]:          0 :                                                 pOutDev->Push( PUSH_LINECOLOR );
    3083         [ #  # ]:          0 :                                                 pOutDev->SetFillColor( COL_LIGHTGRAY );
    3084         [ #  # ]:          0 :                                                 pOutDev->SetLineColor( COL_LIGHTGRAY );
    3085                 :            : 
    3086         [ #  # ]:          0 :                                                 const Rectangle aBackRect( aTopLeftRectPos, aBottomRightRectPos );
    3087         [ #  # ]:          0 :                                                 pOutDev->DrawRect( aBackRect );
    3088                 :            : 
    3089         [ #  # ]:          0 :                                                 pOutDev->Pop();
    3090         [ #  # ]:          0 :                                                 pOutDev->Pop();
    3091                 :            : 
    3092         [ #  # ]:          0 :                                                 if ( 0x200B == cChar )
    3093                 :            :                                                 {
    3094                 :          0 :                                                     const rtl::OUString aSlash( '/' );
    3095                 :          0 :                                                     const short nOldEscapement = aTmpFont.GetEscapement();
    3096                 :          0 :                                                     const sal_uInt8 nOldPropr = aTmpFont.GetPropr();
    3097                 :            : 
    3098                 :          0 :                                                     aTmpFont.SetEscapement( -20 );
    3099                 :          0 :                                                     aTmpFont.SetPropr( 25 );
    3100         [ #  # ]:          0 :                                                     aTmpFont.SetPhysFont( pOutDev );
    3101                 :            : 
    3102 [ #  # ][ #  # ]:          0 :                                                     const Size aSlashSize = aTmpFont.QuickGetTextSize( pOutDev, aSlash, 0, 1, 0 );
                 [ #  # ]
    3103                 :          0 :                                                     Point aSlashPos( aTmpPos );
    3104                 :          0 :                                                     const long nAddX = nHalfBlankWidth - aSlashSize.Width() / 2;
    3105         [ #  # ]:          0 :                                                     if ( !IsVertical() )
    3106                 :            :                                                     {
    3107                 :          0 :                                                         aSlashPos.X() = aTopLeftRectPos.X() + nAddX;
    3108                 :            :                                                     }
    3109                 :            :                                                     else
    3110                 :            :                                                     {
    3111                 :          0 :                                                         aSlashPos.Y() = aTopLeftRectPos.Y() + nAddX;
    3112                 :            :                                                     }
    3113                 :            : 
    3114 [ #  # ][ #  # ]:          0 :                                                     aTmpFont.QuickDrawText( pOutDev, aSlashPos, aSlash, 0, 1, 0 );
                 [ #  # ]
    3115                 :            : 
    3116                 :          0 :                                                     aTmpFont.SetEscapement( nOldEscapement );
    3117                 :          0 :                                                     aTmpFont.SetPropr( nOldPropr );
    3118         [ #  # ]:          0 :                                                     aTmpFont.SetPhysFont( pOutDev );
    3119                 :          0 :                                                 }
    3120                 :            :                                             }
    3121                 :            :                                         }
    3122                 :            :                                     }
    3123                 :            :                                 }
    3124         [ +  + ]:       1102 :                                 else if ( pTextPortion->GetKind() == PORTIONKIND_FIELD )
    3125                 :            :                                 {
    3126         [ +  - ]:       1014 :                                     const EditCharAttrib* pAttr = pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
    3127                 :            :                                     DBG_ASSERT( pAttr, "Field not found");
    3128                 :            :                                     DBG_ASSERT( pAttr && pAttr->GetItem()->ISA( SvxFieldItem ), "Field of the wrong type! ");
    3129 [ +  - ][ +  - ]:       1014 :                                     aText = ((EditCharAttribField*)pAttr)->GetFieldValue();
    3130                 :       1014 :                                     nTextStart = 0;
    3131                 :       1014 :                                     nTextLen = aText.Len();
    3132                 :       1014 :                                     ExtraPortionInfo *pExtraInfo = pTextPortion->GetExtraInfos();
    3133                 :            :                                     // Do not split the Fields into different lines while editing
    3134 [ +  - ][ -  + ]:       1014 :                                     if( bStripOnly && !bParsingFields && pExtraInfo && pExtraInfo->lineBreaksList.size() )
         [ #  # ][ -  + ]
                 [ +  + ]
    3135                 :            :                                     {
    3136                 :          0 :                                         bParsingFields = true;
    3137                 :          0 :                                         itSubLines = pExtraInfo->lineBreaksList.begin();
    3138                 :            :                                     }
    3139         [ -  + ]:       1014 :                                     if( bParsingFields )
    3140                 :            :                                     {
    3141 [ #  # ][ #  # ]:          0 :                                         if( itSubLines != pExtraInfo->lineBreaksList.begin() )
    3142                 :            :                                         {
    3143         [ #  # ]:          0 :                                             if ( !IsVertical() )
    3144                 :            :                                             {
    3145                 :          0 :                                                 aStartPos.Y() += pLine->GetMaxAscent();
    3146                 :          0 :                                                 aTmpPos.Y() += pLine->GetHeight();
    3147                 :            :                                             }
    3148                 :            :                                             else
    3149                 :            :                                             {
    3150                 :          0 :                                                 aTmpPos.X() -= pLine->GetMaxAscent();
    3151                 :          0 :                                                 aStartPos.X() -= pLine->GetHeight();
    3152                 :            :                                             }
    3153                 :            :                                         }
    3154                 :          0 :                                         ::std::vector< sal_Int32 >::iterator curIt = itSubLines;
    3155         [ #  # ]:          0 :                                         ++itSubLines;
    3156 [ #  # ][ #  # ]:          0 :                                         if( itSubLines != pExtraInfo->lineBreaksList.end() )
    3157                 :            :                                         {
    3158         [ #  # ]:          0 :                                             nTextStart = *curIt;
    3159         [ #  # ]:          0 :                                             nTextLen = *itSubLines - nTextStart;
    3160                 :            :                                         }
    3161                 :            :                                         else
    3162                 :            :                                         {
    3163         [ #  # ]:          0 :                                             nTextStart = *curIt;
    3164                 :          0 :                                             nTextLen = nTextLen - nTextStart;
    3165                 :          0 :                                             bParsingFields = false;
    3166                 :            :                                         }
    3167                 :            :                                     }
    3168                 :            : 
    3169         [ +  - ]:       1014 :                                     pTmpDXArray = new sal_Int32[ aText.Len() ];
    3170                 :       1014 :                                     pDXArray = pTmpDXArray;
    3171         [ +  - ]:       1014 :                                     Font _aOldFont( GetRefDevice()->GetFont() );
    3172         [ +  - ]:       1014 :                                     aTmpFont.SetPhysFont( GetRefDevice() );
    3173         [ +  - ]:       1014 :                                     aTmpFont.QuickGetTextSize( GetRefDevice(), aText, nTextStart, nTextLen, pTmpDXArray );
    3174         [ -  + ]:       1014 :                                     if ( aStatus.DoRestoreFont() )
    3175         [ #  # ]:          0 :                                         GetRefDevice()->SetFont( _aOldFont );
    3176                 :            : 
    3177                 :            :                                     // add a meta file comment if we record to a metafile
    3178         [ -  + ]:       1014 :                                     if( bMetafileValid )
    3179                 :            :                                     {
    3180         [ #  # ]:          0 :                                         const SvxFieldItem* pFieldItem = dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
    3181         [ #  # ]:          0 :                                         if( pFieldItem )
    3182                 :            :                                         {
    3183                 :          0 :                                             const SvxFieldData* pFieldData = pFieldItem->GetField();
    3184         [ #  # ]:          0 :                                             if( pFieldData )
    3185 [ #  # ][ #  # ]:          0 :                                                 pMtf->AddAction( pFieldData->createBeginComment() );
    3186                 :            :                                         }
    3187         [ +  - ]:       1014 :                                     }
    3188                 :            : 
    3189                 :            :                                 }
    3190         [ +  - ]:         88 :                                 else if ( pTextPortion->GetKind() == PORTIONKIND_HYPHENATOR )
    3191                 :            :                                 {
    3192         [ -  + ]:         88 :                                     if ( pTextPortion->GetExtraValue() )
    3193         [ #  # ]:          0 :                                         aText = pTextPortion->GetExtraValue();
    3194         [ +  - ]:         88 :                                     aText += CH_HYPH;
    3195                 :         88 :                                     nTextStart = 0;
    3196                 :         88 :                                     nTextLen = aText.Len();
    3197                 :            : 
    3198                 :            :                                     // crash when accessing 0 pointer in pDXArray
    3199         [ +  - ]:         88 :                                     pTmpDXArray = new sal_Int32[ aText.Len() ];
    3200                 :         88 :                                     pDXArray = pTmpDXArray;
    3201         [ +  - ]:         88 :                                     Font _aOldFont( GetRefDevice()->GetFont() );
    3202         [ +  - ]:         88 :                                     aTmpFont.SetPhysFont( GetRefDevice() );
    3203         [ +  - ]:         88 :                                     aTmpFont.QuickGetTextSize( GetRefDevice(), aText, 0, aText.Len(), pTmpDXArray );
    3204         [ -  + ]:         88 :                                     if ( aStatus.DoRestoreFont() )
    3205 [ #  # ][ +  - ]:         88 :                                         GetRefDevice()->SetFont( _aOldFont );
    3206                 :            :                                 }
    3207                 :            : 
    3208                 :      21118 :                                 long nTxtWidth = pTextPortion->GetSize().Width();
    3209                 :            : 
    3210                 :      21118 :                                 Point aOutPos( aTmpPos );
    3211                 :      21118 :                                 aRedLineTmpPos = aTmpPos;
    3212                 :            :                                 // In RTL portions spell markup pos should be at the start of the
    3213                 :            :                                 // first chara as well. That is on the right end of the portion
    3214         [ -  + ]:      21118 :                                 if (pTextPortion->IsRightToLeft())
    3215                 :          0 :                                     aRedLineTmpPos.X() += pTextPortion->GetSize().Width();
    3216                 :            : 
    3217         [ +  + ]:      21118 :                                 if ( bStripOnly )
    3218                 :            :                                 {
    3219         [ +  - ]:      18034 :                                     EEngineData::WrongSpellVector aWrongSpellVector;
    3220                 :            : 
    3221 [ +  + ][ +  + ]:      18034 :                                     if(GetStatus().DoOnlineSpelling() && pTextPortion->GetLen())
                 [ +  + ]
    3222                 :            :                                     {
    3223                 :       5406 :                                         WrongList* pWrongs = pPortion->GetNode()->GetWrongList();
    3224                 :            : 
    3225 [ +  - ][ -  + ]:       5406 :                                         if(pWrongs && !pWrongs->empty())
         [ -  + ][ +  - ]
    3226                 :            :                                         {
    3227                 :          0 :                                             sal_uInt16 nStart(nIndex);
    3228                 :          0 :                                             sal_uInt16 nEnd(0);
    3229         [ #  # ]:          0 :                                             sal_Bool bWrong(pWrongs->NextWrong(nStart, nEnd));
    3230                 :          0 :                                             const sal_uInt16 nMaxEnd(nIndex + pTextPortion->GetLen());
    3231                 :            : 
    3232         [ #  # ]:          0 :                                             while(bWrong)
    3233                 :            :                                             {
    3234         [ #  # ]:          0 :                                                 if(nStart >= nMaxEnd)
    3235                 :            :                                                 {
    3236                 :          0 :                                                     break;
    3237                 :            :                                                 }
    3238                 :            : 
    3239         [ #  # ]:          0 :                                                 if(nStart < nIndex)
    3240                 :            :                                                 {
    3241                 :          0 :                                                     nStart = nIndex;
    3242                 :            :                                                 }
    3243                 :            : 
    3244         [ #  # ]:          0 :                                                 if(nEnd > nMaxEnd)
    3245                 :            :                                                 {
    3246                 :          0 :                                                     nEnd = nMaxEnd;
    3247                 :            :                                                 }
    3248                 :            : 
    3249                 :            :                                                 // add to vector
    3250         [ #  # ]:          0 :                                                 aWrongSpellVector.push_back(EEngineData::WrongSpellClass(nStart, nEnd));
    3251                 :            : 
    3252                 :            :                                                 // goto next index
    3253                 :          0 :                                                 nStart = nEnd + 1;
    3254                 :            : 
    3255         [ #  # ]:          0 :                                                 if(nEnd < nMaxEnd)
    3256                 :            :                                                 {
    3257         [ #  # ]:          0 :                                                     bWrong = pWrongs->NextWrong(nStart, nEnd);
    3258                 :            :                                                 }
    3259                 :            :                                                 else
    3260                 :            :                                                 {
    3261                 :          0 :                                                     bWrong = sal_False;
    3262                 :            :                                                 }
    3263                 :            :                                             }
    3264                 :            :                                         }
    3265                 :            :                                     }
    3266                 :            : 
    3267                 :      18034 :                                     const SvxFieldData* pFieldData = 0;
    3268                 :            : 
    3269         [ +  + ]:      18034 :                                     if(PORTIONKIND_FIELD == pTextPortion->GetKind())
    3270                 :            :                                     {
    3271         [ +  - ]:        888 :                                         const EditCharAttrib* pAttr = pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
    3272         [ -  + ]:        888 :                                         const SvxFieldItem* pFieldItem = dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
    3273                 :            : 
    3274         [ +  - ]:        888 :                                         if(pFieldItem)
    3275                 :            :                                         {
    3276                 :        888 :                                             pFieldData = pFieldItem->GetField();
    3277                 :            :                                         }
    3278                 :            :                                     }
    3279                 :            : 
    3280                 :            :                                     // support for EOC, EOW, EOS TEXT comments. To support that,
    3281                 :            :                                     // the locale is needed. With the locale and a XBreakIterator it is
    3282                 :            :                                     // possible to re-create the text marking info on primitive level
    3283 [ +  - ][ +  - ]:      18034 :                                     const lang::Locale aLocale(GetLocale(EditPaM(pPortion->GetNode(), nIndex + 1)));
    3284                 :            : 
    3285                 :            :                                     // create EOL and EOP bools
    3286                 :      18034 :                                     const bool bEndOfLine(y == pLine->GetEndPortion());
    3287 [ +  + ][ +  + ]:      18034 :                                     const bool bEndOfParagraph(bEndOfLine && nLine + 1 == nLines);
    3288                 :            : 
    3289                 :            :                                     // get Overline color (from ((const SvxOverlineItem*)GetItem())->GetColor() in
    3290                 :            :                                     // consequence, but also already set at pOutDev)
    3291                 :      18034 :                                     const Color aOverlineColor(pOutDev->GetOverlineColor());
    3292                 :            : 
    3293                 :            :                                     // get TextLine color (from ((const SvxUnderlineItem*)GetItem())->GetColor() in
    3294                 :            :                                     // consequence, but also already set at pOutDev)
    3295                 :      18034 :                                     const Color aTextLineColor(pOutDev->GetTextLineColor());
    3296                 :            : 
    3297                 :            :                                     // Unicode code points conversion according to ctl text numeral setting
    3298         [ +  - ]:      18034 :                                     ImplInitDigitMode( 0, &aText, nTextStart, nTextLen, aTmpFont.GetLanguage() );
    3299                 :            : 
    3300                 :            :                                     // StripPortions() data callback
    3301                 :      18034 :                                     GetEditEnginePtr()->DrawingText( aOutPos, aText, nTextStart, nTextLen, pDXArray,
    3302                 :      18034 :                                         aTmpFont, n, nIndex, pTextPortion->GetRightToLeft(),
    3303                 :      18034 :                                         aWrongSpellVector.size() ? &aWrongSpellVector : 0,
    3304                 :            :                                         pFieldData,
    3305                 :            :                                         bEndOfLine, bEndOfParagraph, false, // support for EOL/EOP TEXT comments
    3306                 :            :                                         &aLocale,
    3307                 :            :                                         aOverlineColor,
    3308 [ +  - ][ -  + ]:      36068 :                                         aTextLineColor);
    3309                 :            :                                 }
    3310                 :            :                                 else
    3311                 :            :                                 {
    3312                 :       3084 :                                     short nEsc = aTmpFont.GetEscapement();
    3313         [ +  + ]:       3084 :                                     if ( nOrientation )
    3314                 :            :                                     {
    3315                 :            :                                         // In case of high/low do it yourself:
    3316         [ -  + ]:       1390 :                                         if ( aTmpFont.GetEscapement() )
    3317                 :            :                                         {
    3318         [ #  # ]:          0 :                                             long nDiff = aTmpFont.GetSize().Height() * aTmpFont.GetEscapement() / 100L;
    3319         [ #  # ]:          0 :                                             if ( !IsVertical() )
    3320                 :          0 :                                                 aOutPos.Y() -= nDiff;
    3321                 :            :                                             else
    3322                 :          0 :                                                 aOutPos.X() += nDiff;
    3323                 :          0 :                                             aRedLineTmpPos = aOutPos;
    3324                 :          0 :                                             aTmpFont.SetEscapement( 0 );
    3325                 :            :                                         }
    3326                 :            : 
    3327                 :       1390 :                                         aOutPos = lcl_ImplCalcRotatedPos( aOutPos, aOrigin, nSin, nCos );
    3328 [ +  - ][ +  - ]:       1390 :                                         aTmpFont.SetOrientation( aTmpFont.GetOrientation()+nOrientation );
    3329         [ +  - ]:       1390 :                                         aTmpFont.SetPhysFont( pOutDev );
    3330                 :            : 
    3331                 :            :                                     }
    3332                 :            : 
    3333                 :            :                                     // Take only what begins in the visible range:
    3334                 :            :                                     // Important, because of a bug in some graphic cards
    3335                 :            :                                     // when transparent font, output when negative
    3336 [ +  + ][ +  - ]:       3084 :                                     if ( nOrientation || ( !IsVertical() && ( ( aTmpPos.X() + nTxtWidth ) >= nFirstVisXPos ) )
           [ -  +  #  #  
           #  # ][ +  - ]
    3337                 :          0 :                                             || ( IsVertical() && ( ( aTmpPos.Y() + nTxtWidth ) >= nFirstVisYPos ) ) )
    3338                 :            :                                     {
    3339 [ +  + ][ +  - ]:       3084 :                                         if ( nEsc && ( ( aTmpFont.GetUnderline() != UNDERLINE_NONE ) ) )
         [ +  + ][ +  + ]
    3340                 :            :                                         {
    3341                 :            :                                             // Paint the high/low without underline,
    3342                 :            :                                             // Display the Underline on the
    3343                 :            :                                             // base line of the original font height ...
    3344                 :            :                                             // But only if there was something underlined before!
    3345                 :         69 :                                             sal_Bool bSpecialUnderline = sal_False;
    3346         [ +  - ]:         69 :                                             EditCharAttrib* pPrev = pPortion->GetNode()->GetCharAttribs().FindAttrib( EE_CHAR_ESCAPEMENT, nIndex );
    3347         [ +  - ]:         69 :                                             if ( pPrev )
    3348                 :            :                                             {
    3349         [ +  - ]:         69 :                                                 SvxFont aDummy;
    3350                 :            :                                                 // Underscore in front?
    3351         [ -  + ]:         69 :                                                 if ( pPrev->GetStart() )
    3352                 :            :                                                 {
    3353         [ #  # ]:          0 :                                                     SeekCursor( pPortion->GetNode(), pPrev->GetStart(), aDummy );
    3354 [ #  # ][ #  # ]:          0 :                                                     if ( aDummy.GetUnderline() != UNDERLINE_NONE )
    3355                 :          0 :                                                         bSpecialUnderline = sal_True;
    3356                 :            :                                                 }
    3357 [ +  - ][ +  - ]:         69 :                                                 if ( !bSpecialUnderline && ( pPrev->GetEnd() < pPortion->GetNode()->Len() ) )
         [ -  + ][ -  + ]
    3358                 :            :                                                 {
    3359         [ #  # ]:          0 :                                                     SeekCursor( pPortion->GetNode(), pPrev->GetEnd()+1, aDummy );
    3360 [ #  # ][ #  # ]:          0 :                                                     if ( aDummy.GetUnderline() != UNDERLINE_NONE )
    3361                 :          0 :                                                         bSpecialUnderline = sal_True;
    3362         [ +  - ]:         69 :                                                 }
    3363                 :            :                                             }
    3364         [ -  + ]:         69 :                                             if ( bSpecialUnderline )
    3365                 :            :                                             {
    3366         [ #  # ]:          0 :                                                 Size aSz = aTmpFont.GetPhysTxtSize( pOutDev, aText, nTextStart, nTextLen );
    3367                 :          0 :                                                 sal_uInt8 nProp = aTmpFont.GetPropr();
    3368                 :          0 :                                                 aTmpFont.SetEscapement( 0 );
    3369                 :          0 :                                                 aTmpFont.SetPropr( 100 );
    3370         [ #  # ]:          0 :                                                 aTmpFont.SetPhysFont( pOutDev );
    3371                 :          0 :                                                 rtl::OUStringBuffer aBlanks;
    3372         [ #  # ]:          0 :                                                 comphelper::string::padToLength( aBlanks, (sal_Int32) nTextLen, ' ' );
    3373                 :          0 :                                                 Point aUnderlinePos( aOutPos );
    3374         [ #  # ]:          0 :                                                 if ( nOrientation )
    3375                 :          0 :                                                     aUnderlinePos = lcl_ImplCalcRotatedPos( aTmpPos, aOrigin, nSin, nCos );
    3376 [ #  # ][ #  # ]:          0 :                                                 pOutDev->DrawStretchText( aUnderlinePos, aSz.Width(), aBlanks.makeStringAndClear(), 0, nTextLen );
         [ #  # ][ #  # ]
    3377                 :            : 
    3378         [ #  # ]:          0 :                                                 aTmpFont.SetUnderline( UNDERLINE_NONE );
    3379         [ #  # ]:          0 :                                                 if ( !nOrientation )
    3380                 :          0 :                                                     aTmpFont.SetEscapement( nEsc );
    3381                 :          0 :                                                 aTmpFont.SetPropr( nProp );
    3382         [ #  # ]:          0 :                                                 aTmpFont.SetPhysFont( pOutDev );
    3383                 :            :                                             }
    3384                 :            :                                         }
    3385                 :       3084 :                                         Point aRealOutPos( aOutPos );
    3386   [ +  +  -  +  :       6035 :                                         if ( ( pTextPortion->GetKind() == PORTIONKIND_TEXT )
             #  #  #  # ]
                 [ -  + ]
    3387                 :       2951 :                                                && pTextPortion->GetExtraInfos() && pTextPortion->GetExtraInfos()->bCompressed
    3388                 :          0 :                                                && pTextPortion->GetExtraInfos()->bFirstCharIsRightPunktuation )
    3389                 :            :                                         {
    3390                 :          0 :                                             aRealOutPos.X() += pTextPortion->GetExtraInfos()->nPortionOffsetX;
    3391                 :            :                                         }
    3392                 :            : 
    3393                 :            :                                         // RTL portions with (#i37132#)
    3394                 :            :                                         // compressed blank should not paint this blank:
    3395 [ -  + ][ #  # ]:       3084 :                                         if ( pTextPortion->IsRightToLeft() && nTextLen >= 2 &&
           [ #  #  #  # ]
                 [ -  + ]
    3396                 :          0 :                                              pDXArray[ nTextLen - 1 ] ==
    3397                 :          0 :                                              pDXArray[ nTextLen - 2 ] &&
    3398                 :          0 :                                              ' ' == aText.GetChar( nTextStart + nTextLen - 1 ) )
    3399                 :          0 :                                             --nTextLen;
    3400                 :            : 
    3401                 :            :                                         // output directly
    3402         [ +  - ]:       3084 :                                         aTmpFont.QuickDrawText( pOutDev, aRealOutPos, aText, nTextStart, nTextLen, pDXArray );
    3403                 :            : 
    3404         [ +  + ]:       3084 :                                         if ( bDrawFrame )
    3405                 :            :                                         {
    3406                 :          1 :                                             Point aTopLeft( aTmpPos );
    3407                 :          1 :                                             aTopLeft.Y() -= pLine->GetMaxAscent();
    3408         [ -  + ]:          1 :                                             if ( nOrientation )
    3409                 :          0 :                                                 aTopLeft = lcl_ImplCalcRotatedPos( aTopLeft, aOrigin, nSin, nCos );
    3410         [ +  - ]:          1 :                                             Rectangle aRect( aTopLeft, pTextPortion->GetSize() );
    3411         [ +  - ]:          1 :                                             pOutDev->DrawRect( aRect );
    3412                 :            :                                         }
    3413                 :            : 
    3414                 :            :                                         // PDF export:
    3415         [ -  + ]:       3084 :                                         if ( pPDFExtOutDevData )
    3416                 :            :                                         {
    3417         [ #  # ]:          0 :                                             if ( pTextPortion->GetKind() == PORTIONKIND_FIELD )
    3418                 :            :                                             {
    3419         [ #  # ]:          0 :                                                 const EditCharAttrib* pAttr = pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
    3420         [ #  # ]:          0 :                                                 const SvxFieldItem* pFieldItem = dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
    3421         [ #  # ]:          0 :                                                 if( pFieldItem )
    3422                 :            :                                                 {
    3423                 :          0 :                                                     const SvxFieldData* pFieldData = pFieldItem->GetField();
    3424 [ #  # ][ #  # ]:          0 :                                                     if ( pFieldData->ISA( SvxURLField ) )
                 [ #  # ]
    3425                 :            :                                                     {
    3426                 :          0 :                                                         Point aTopLeft( aTmpPos );
    3427                 :          0 :                                                         aTopLeft.Y() -= pLine->GetMaxAscent();
    3428                 :            : 
    3429         [ #  # ]:          0 :                                                         Rectangle aRect( aTopLeft, pTextPortion->GetSize() );
    3430                 :          0 :                                                         vcl::PDFExtOutDevBookmarkEntry aBookmark;
    3431         [ #  # ]:          0 :                                                         aBookmark.nLinkId = pPDFExtOutDevData->CreateLink( aRect );
    3432                 :          0 :                                                         aBookmark.aBookmark = ((SvxURLField*)pFieldData)->GetURL();
    3433         [ #  # ]:          0 :                                                         std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFExtOutDevData->GetBookmarks();
    3434         [ #  # ]:       3084 :                                                         rBookmarks.push_back( aBookmark );
    3435                 :            :                                                     }
    3436                 :            :                                                 }
    3437                 :            :                                             }
    3438                 :            :                                         }
    3439                 :            :                                     }
    3440                 :            : 
    3441 [ +  + ][ +  - ]:       3084 :                                     if ( GetStatus().DoOnlineSpelling() && !pPortion->GetNode()->GetWrongList()->empty() && pTextPortion->GetLen() )
         [ +  + ][ +  + ]
                 [ +  + ]
    3442                 :            :                                     {
    3443                 :            :                                         {//#105750# adjust LinePos for superscript or subscript text
    3444                 :        517 :                                             short _nEsc = aTmpFont.GetEscapement();
    3445         [ +  + ]:        517 :                                             if( _nEsc )
    3446                 :            :                                             {
    3447         [ +  - ]:         60 :                                                 long nShift = ((_nEsc*long(aTmpFont.GetSize().Height()))/ 100L);
    3448         [ +  - ]:         60 :                                                 if( !IsVertical() )
    3449                 :         60 :                                                     aRedLineTmpPos.Y() -= nShift;
    3450                 :            :                                                 else
    3451                 :          0 :                                                     aRedLineTmpPos.X() += nShift;
    3452                 :            :                                             }
    3453                 :            :                                         }
    3454                 :        517 :                                         Color aOldColor( pOutDev->GetLineColor() );
    3455 [ +  - ][ +  - ]:        517 :                                         pOutDev->SetLineColor( Color( GetColorConfig().GetColorValue( svtools::SPELL ).nColor ) );
                 [ +  - ]
    3456 [ +  - ][ +  - ]:        517 :                                         lcl_DrawRedLines( pOutDev, aTmpFont.GetSize().Height(), aRedLineTmpPos, nIndex, nIndex + pTextPortion->GetLen(), pDXArray, pPortion->GetNode()->GetWrongList(), nOrientation, aOrigin, IsVertical(), pTextPortion->IsRightToLeft() );
    3457         [ +  - ]:        517 :                                         pOutDev->SetLineColor( aOldColor );
    3458                 :            :                                     }
    3459                 :            :                                 }
    3460                 :            : 
    3461         [ +  - ]:      21118 :                                 pOutDev->Pop();
    3462                 :            : 
    3463                 :            :                                 //The C++ language guarantees that delete p will do nothing if p is equal to NULL.
    3464         [ +  + ]:      21118 :                                 delete[] pTmpDXArray;
    3465                 :            : 
    3466         [ +  + ]:      21118 :                                 if ( pTextPortion->GetKind() == PORTIONKIND_FIELD )
    3467                 :            :                                 {
    3468         [ +  - ]:       1014 :                                     const EditCharAttrib* pAttr = pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
    3469                 :            :                                     DBG_ASSERT( pAttr, "Field not found" );
    3470                 :            :                                     DBG_ASSERT( pAttr && pAttr->GetItem()->ISA( SvxFieldItem ), "Wrong type of field!" );
    3471                 :            : 
    3472                 :            :                                     // add a meta file comment if we record to a metafile
    3473         [ -  + ]:       1014 :                                     if( bMetafileValid )
    3474                 :            :                                     {
    3475         [ #  # ]:          0 :                                         const SvxFieldItem* pFieldItem = dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
    3476                 :            : 
    3477         [ #  # ]:          0 :                                         if( pFieldItem )
    3478                 :            :                                         {
    3479                 :          0 :                                             const SvxFieldData* pFieldData = pFieldItem->GetField();
    3480         [ #  # ]:          0 :                                             if( pFieldData )
    3481 [ #  # ][ #  # ]:          0 :                                                 pMtf->AddAction( pFieldData->createEndComment() );
    3482                 :            :                                         }
    3483                 :            :                                     }
    3484                 :            : 
    3485         [ +  - ]:      21118 :                                 }
    3486                 :            : 
    3487                 :            :                             }
    3488                 :      21118 :                             break;
    3489                 :            :                             case PORTIONKIND_TAB:
    3490                 :            :                             {
    3491 [ #  # ][ #  # ]:          0 :                                 if ( pTextPortion->GetExtraValue() && ( pTextPortion->GetExtraValue() != ' ' ) )
                 [ #  # ]
    3492                 :            :                                 {
    3493         [ #  # ]:          0 :                                     SeekCursor( pPortion->GetNode(), nIndex+1, aTmpFont, pOutDev );
    3494         [ #  # ]:          0 :                                     aTmpFont.SetTransparent( sal_False );
    3495                 :          0 :                                     aTmpFont.SetEscapement( 0 );
    3496         [ #  # ]:          0 :                                     aTmpFont.SetPhysFont( pOutDev );
    3497                 :            :                                     long nCharWidth = aTmpFont.QuickGetTextSize( pOutDev,
    3498 [ #  # ][ #  # ]:          0 :                                         rtl::OUString(pTextPortion->GetExtraValue()), 0, 1, NULL ).Width();
                 [ #  # ]
    3499                 :          0 :                                     long nChars = 2;
    3500         [ #  # ]:          0 :                                     if( nCharWidth )
    3501                 :          0 :                                         nChars = pTextPortion->GetSize().Width() / nCharWidth;
    3502         [ #  # ]:          0 :                                     if ( nChars < 2 )
    3503                 :          0 :                                         nChars = 2; // is compressed by DrawStretchText.
    3504         [ #  # ]:          0 :                                     else if ( nChars == 2 )
    3505                 :          0 :                                         nChars = 3; // looks better
    3506                 :            : 
    3507         [ #  # ]:          0 :                                     String aText;
    3508         [ #  # ]:          0 :                                     aText.Fill( (sal_uInt16)nChars, pTextPortion->GetExtraValue() );
    3509         [ #  # ]:          0 :                                     aTmpFont.QuickDrawText( pOutDev, aTmpPos, aText, 0, aText.Len(), NULL );
    3510         [ #  # ]:          0 :                                     pOutDev->DrawStretchText( aTmpPos, pTextPortion->GetSize().Width(), aText );
    3511                 :            : 
    3512         [ #  # ]:          0 :                                     if ( bStripOnly )
    3513                 :            :                                     {
    3514                 :            :                                         // create EOL and EOP bools
    3515                 :          0 :                                         const bool bEndOfLine(y == pLine->GetEndPortion());
    3516 [ #  # ][ #  # ]:          0 :                                         const bool bEndOfParagraph(bEndOfLine && nLine + 1 == nLines);
    3517                 :            : 
    3518                 :          0 :                                         const Color aOverlineColor(pOutDev->GetOverlineColor());
    3519                 :          0 :                                         const Color aTextLineColor(pOutDev->GetTextLineColor());
    3520                 :            : 
    3521                 :            :                                         // StripPortions() data callback
    3522                 :          0 :                                         GetEditEnginePtr()->DrawingTab( aTmpPos,
    3523                 :          0 :                                             pTextPortion->GetSize().Width(),
    3524                 :          0 :                                             rtl::OUString(pTextPortion->GetExtraValue()),
    3525                 :          0 :                                             aTmpFont, n, nIndex, pTextPortion->GetRightToLeft(),
    3526                 :            :                                             bEndOfLine, bEndOfParagraph,
    3527         [ #  # ]:          0 :                                             aOverlineColor, aTextLineColor);
           [ #  #  #  # ]
    3528         [ #  # ]:          0 :                                     }
    3529                 :            :                                 }
    3530         [ #  # ]:          0 :                                 else if ( bStripOnly )
    3531                 :            :                                 {
    3532                 :            :                                     // #i108052# When stripping, a callback for _empty_ paragraphs is also needed.
    3533                 :            :                                     // This was optimized away (by not rendering the space-only tab portion), so do
    3534                 :            :                                     // it manually here.
    3535                 :          0 :                                     const bool bEndOfLine(y == pLine->GetEndPortion());
    3536 [ #  # ][ #  # ]:          0 :                                     const bool bEndOfParagraph(bEndOfLine && nLine + 1 == nLines);
    3537                 :            : 
    3538                 :          0 :                                     const Color aOverlineColor(pOutDev->GetOverlineColor());
    3539                 :          0 :                                     const Color aTextLineColor(pOutDev->GetTextLineColor());
    3540                 :            : 
    3541                 :          0 :                                     GetEditEnginePtr()->DrawingText(
    3542                 :            :                                         aTmpPos, String(), 0, 0, 0,
    3543                 :            :                                         aTmpFont, n, nIndex, 0,
    3544                 :            :                                         0,
    3545                 :            :                                         0,
    3546                 :            :                                         bEndOfLine, bEndOfParagraph, false,
    3547                 :            :                                         0,
    3548                 :            :                                         aOverlineColor,
    3549 [ #  # ][ #  # ]:          0 :                                         aTextLineColor);
                 [ #  # ]
    3550                 :            :                                 }
    3551                 :            :                             }
    3552                 :          0 :                             break;
    3553                 :            :                         }
    3554         [ -  + ]:      21124 :                         if( bParsingFields )
    3555                 :          0 :                             y--;
    3556                 :            :                         else
    3557                 :      21124 :                             nIndex = nIndex + pTextPortion->GetLen();
    3558                 :            : 
    3559                 :            :                     }
    3560                 :            :                 }
    3561                 :            : 
    3562 [ +  + ][ +  - ]:      21002 :                 if ( ( nLine != nLastLine ) && !aStatus.IsOutliner() )
                 [ +  + ]
    3563                 :            :                 {
    3564         [ +  - ]:       2815 :                     if ( !IsVertical() )
    3565                 :       2815 :                         aStartPos.Y() += nSBL;
    3566                 :            :                     else
    3567                 :          0 :                         aStartPos.X() -= nSBL;
    3568                 :            :                 }
    3569                 :            : 
    3570                 :            :                 // no more visible actions?
    3571 [ +  - ][ +  + ]:      21002 :                 if ( !IsVertical() && ( aStartPos.Y() >= aClipRec.Bottom() ) )
                 [ +  + ]
    3572                 :        756 :                     break;
    3573 [ -  + ][ #  # ]:      20246 :                 else if ( IsVertical() && ( aStartPos.X() <= aClipRec.Left() ) )
                 [ -  + ]
    3574                 :          0 :                     break;
    3575                 :            :             }
    3576                 :            : 
    3577         [ +  - ]:      18187 :             if ( !aStatus.IsOutliner() )
    3578                 :            :             {
    3579         [ +  - ]:      18187 :                 const SvxULSpaceItem& rULItem = (const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
    3580                 :      18187 :                 long nUL = GetYValue( rULItem.GetLower() );
    3581         [ +  - ]:      18187 :                 if ( !IsVertical() )
    3582                 :      18187 :                     aStartPos.Y() += nUL;
    3583                 :            :                 else
    3584                 :      18187 :                     aStartPos.X() -= nUL;
    3585                 :            :             }
    3586                 :            :         }
    3587                 :            :         else
    3588                 :            :         {
    3589         [ #  # ]:          0 :             if ( !IsVertical() )
    3590                 :          0 :                 aStartPos.Y() += nParaHeight;
    3591                 :            :             else
    3592                 :          0 :                 aStartPos.X() -= nParaHeight;
    3593                 :            :         }
    3594                 :            : 
    3595         [ -  + ]:      18187 :         if ( pPDFExtOutDevData )
    3596         [ #  # ]:          0 :             pPDFExtOutDevData->EndStructureElement();
    3597                 :            : 
    3598                 :            :         // no more visible actions?
    3599 [ +  - ][ +  + ]:      18187 :         if ( !IsVertical() && ( aStartPos.Y() > aClipRec.Bottom() ) )
                 [ +  + ]
    3600                 :        756 :             break;
    3601 [ -  + ][ #  # ]:      17431 :         if ( IsVertical() && ( aStartPos.X() < aClipRec.Left() ) )
                 [ -  + ]
    3602                 :          0 :             break;
    3603                 :            :     }
    3604         [ -  + ]:      16003 :     if ( aStatus.DoRestoreFont() )
    3605 [ #  # ][ +  - ]:      16003 :         pOutDev->SetFont( aOldFont );
         [ -  + ][ +  - ]
                 [ +  - ]
    3606                 :            : }
    3607                 :            : 
    3608                 :        791 : void ImpEditEngine::Paint( ImpEditView* pView, const Rectangle& rRec, sal_Bool bUseVirtDev )
    3609                 :            : {
    3610                 :            :     DBG_ASSERT( pView, "No View - No Paint!" );
    3611                 :            :     DBG_CHKOBJ( GetEditEnginePtr(), EditEngine, 0 );
    3612                 :            : 
    3613 [ +  - ][ -  + ]:        791 :     if ( !GetUpdateMode() || IsInUndo() )
                 [ +  - ]
    3614                 :            :         return;
    3615                 :            : 
    3616                 :            :     // Intersection of paint area and output area.
    3617                 :        791 :     Rectangle aClipRec( pView->GetOutputArea() );
    3618         [ +  - ]:        791 :     aClipRec.Intersection( rRec );
    3619                 :            : 
    3620                 :        791 :     Window* pOutWin = pView->GetWindow();
    3621                 :            : 
    3622         [ +  + ]:        791 :     if ( bUseVirtDev )
    3623                 :            :     {
    3624         [ +  - ]:        271 :         Rectangle aClipRecPixel( pOutWin->LogicToPixel( aClipRec ) );
    3625         [ +  - ]:        271 :         if ( !IsVertical() )
    3626                 :            :         {
    3627                 :            :             // etwas mehr, falls abgerundet!
    3628                 :        271 :             aClipRecPixel.Right() += 1;
    3629                 :        271 :             aClipRecPixel.Bottom() += 1;
    3630                 :            :         }
    3631                 :            :         else
    3632                 :            :         {
    3633                 :          0 :             aClipRecPixel.Left() -= 1;
    3634                 :          0 :             aClipRecPixel.Bottom() += 1;
    3635                 :            :         }
    3636                 :            : 
    3637                 :            :         // If aClipRecPixel > XXXX, then invalidate?!
    3638                 :            : 
    3639         [ +  - ]:        271 :         VirtualDevice* pVDev = GetVirtualDevice( pOutWin->GetMapMode(), pOutWin->GetDrawMode() );
    3640         [ +  - ]:        271 :         pVDev->SetDigitLanguage( GetRefDevice()->GetDigitLanguage() );
    3641                 :            : 
    3642                 :            :         {
    3643         [ +  - ]:        271 :             Color aBackgroundColor( pView->GetBackgroundColor() );
    3644                 :            :             // #i47161# Check if text is visible on background
    3645         [ +  - ]:        271 :             SvxFont aTmpFont;
    3646         [ +  - ]:        271 :             ContentNode* pNode = GetEditDoc().GetObject( 0 );
    3647         [ +  - ]:        271 :             SeekCursor( pNode, 1, aTmpFont );
    3648         [ +  - ]:        271 :             Color aFontColor( aTmpFont.GetColor() );
    3649 [ +  + ][ -  + ]:        271 :             if( (aFontColor == COL_AUTO) || IsForceAutoColor() )
         [ +  - ][ +  + ]
    3650         [ +  - ]:         66 :                 aFontColor = GetAutoColor();
    3651                 :            : 
    3652                 :            :             // #i69346# check for reverse color of input method attribute
    3653 [ -  + ][ #  # ]:        271 :             if( mpIMEInfos && (mpIMEInfos->aPos.GetNode() == pNode &&
         [ #  # ][ #  # ]
                 [ -  + ]
    3654                 :            :                 mpIMEInfos->pAttribs))
    3655                 :            :             {
    3656                 :          0 :                 sal_uInt16 nAttr = mpIMEInfos->pAttribs[ 0 ];
    3657         [ #  # ]:          0 :                 if ( nAttr & EXTTEXTINPUT_ATTR_HIGHLIGHT )
    3658                 :            :                 {
    3659         [ #  # ]:          0 :                     const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    3660                 :          0 :                     aFontColor = rStyleSettings.GetHighlightColor() ;
    3661                 :            :                 }
    3662                 :            :             }
    3663                 :            : 
    3664         [ +  - ]:        271 :             sal_uInt8 nColorDiff = aFontColor.GetColorError( aBackgroundColor );
    3665         [ -  + ]:        271 :             if( nColorDiff < 8 )
    3666 [ #  # ][ #  # ]:          0 :                 aBackgroundColor = aFontColor.IsDark() ? COL_WHITE : COL_BLACK;
    3667 [ +  - ][ +  - ]:        271 :             pVDev->SetBackground( aBackgroundColor );
         [ +  - ][ +  - ]
    3668                 :            :         }
    3669                 :            : 
    3670                 :        271 :         sal_Bool bVDevValid = sal_True;
    3671                 :        271 :         Size aOutSz( pVDev->GetOutputSizePixel() );
    3672 [ +  + ][ -  + ]:        319 :         if ( (  aOutSz.Width() < aClipRecPixel.GetWidth() ) ||
         [ +  + ][ +  - ]
    3673         [ +  - ]:         48 :              (  aOutSz.Height() < aClipRecPixel.GetHeight() ) )
    3674                 :            :         {
    3675 [ +  - ][ +  - ]:        223 :             bVDevValid = pVDev->SetOutputSizePixel( aClipRecPixel.GetSize() );
    3676                 :            :         }
    3677                 :            :         else
    3678                 :            :         {
    3679                 :            :             // The VirtDev can become very big during a Resize =>
    3680                 :            :             // eventually make it smaller!
    3681 [ +  - ][ +  - ]:         96 :             if ( ( aOutSz.Height() > ( aClipRecPixel.GetHeight() + RESDIFF ) ) ||
         [ -  + ][ -  + ]
    3682         [ +  - ]:         48 :                  ( aOutSz.Width() > ( aClipRecPixel.GetWidth() + RESDIFF ) ) )
    3683                 :            :             {
    3684 [ #  # ][ #  # ]:          0 :                 bVDevValid = pVDev->SetOutputSizePixel( aClipRecPixel.GetSize() );
    3685                 :            :             }
    3686                 :            :             else
    3687                 :            :             {
    3688         [ +  - ]:         48 :                 pVDev->Erase();
    3689                 :            :             }
    3690                 :            :         }
    3691                 :            :         DBG_ASSERT( bVDevValid, "VDef could not be enlarged!" );
    3692         [ -  + ]:        271 :         if ( !bVDevValid )
    3693                 :            :         {
    3694         [ #  # ]:          0 :             Paint( pView, rRec, sal_False /* ohne VDev */ );
    3695                 :            :             return;
    3696                 :            :         }
    3697                 :            : 
    3698                 :            :         // PaintRect for VDev not with aligned size,
    3699                 :            :         // Otherwise, the line below must also be printed out:
    3700 [ +  - ][ +  - ]:        271 :         Rectangle aTmpRec( Point( 0, 0 ), aClipRec.GetSize() );
    3701                 :            : 
    3702         [ +  - ]:        271 :         aClipRec = pOutWin->PixelToLogic( aClipRecPixel );
    3703                 :        271 :         Point aStartPos;
    3704         [ +  - ]:        271 :         if ( !IsVertical() )
    3705                 :            :         {
    3706                 :        271 :             aStartPos = aClipRec.TopLeft();
    3707         [ +  - ]:        271 :             aStartPos = pView->GetDocPos( aStartPos );
    3708                 :        271 :             aStartPos.X() *= (-1);
    3709                 :        271 :             aStartPos.Y() *= (-1);
    3710                 :            :         }
    3711                 :            :         else
    3712                 :            :         {
    3713         [ #  # ]:          0 :             aStartPos = aClipRec.TopRight();
    3714         [ #  # ]:          0 :             Point aDocPos( pView->GetDocPos( aStartPos ) );
    3715         [ #  # ]:          0 :             aStartPos.X() = aClipRec.GetSize().Width() + aDocPos.Y();
    3716                 :          0 :             aStartPos.Y() = -aDocPos.X();
    3717                 :            :         }
    3718                 :            : 
    3719         [ +  - ]:        271 :         Paint( pVDev, aTmpRec, aStartPos );
    3720                 :            : 
    3721                 :        271 :         sal_Bool bClipRegion = sal_False;
    3722         [ +  - ]:        271 :         Region aOldRegion;
    3723         [ +  - ]:        271 :         MapMode aOldMapMode;
    3724         [ -  + ]:        271 :         if ( GetTextRanger() )
    3725                 :            :         {
    3726                 :            :             // Some problems here with push/pop, why?!
    3727                 :          0 :             bClipRegion = pOutWin->IsClipRegion();
    3728 [ #  # ][ #  # ]:          0 :             aOldRegion = pOutWin->GetClipRegion();
                 [ #  # ]
    3729                 :            :             // How do I get the polygon to the right place??
    3730                 :            :             // The polygon is based on the view, not the Window
    3731                 :            :             // => reset origin...
    3732         [ #  # ]:          0 :             aOldMapMode = pOutWin->GetMapMode();
    3733                 :          0 :             Point aOrigin = aOldMapMode.GetOrigin();
    3734                 :          0 :             Point aViewPos = pView->GetOutputArea().TopLeft();
    3735                 :          0 :             aOrigin.Move( aViewPos.X(), aViewPos.Y() );
    3736         [ #  # ]:          0 :             aClipRec.Move( -aViewPos.X(), -aViewPos.Y() );
    3737         [ #  # ]:          0 :             MapMode aNewMapMode( aOldMapMode );
    3738         [ #  # ]:          0 :             aNewMapMode.SetOrigin( aOrigin );
    3739         [ #  # ]:          0 :             pOutWin->SetMapMode( aNewMapMode );
    3740 [ #  # ][ #  # ]:          0 :             pOutWin->SetClipRegion( Region( GetTextRanger()->GetPolyPolygon() ) );
         [ #  # ][ #  # ]
    3741                 :            :         }
    3742                 :            : 
    3743                 :            :         pOutWin->DrawOutDev( aClipRec.TopLeft(), aClipRec.GetSize(),
    3744 [ +  - ][ +  - ]:        271 :                             Point(0,0), aClipRec.GetSize(), *pVDev );
                 [ +  - ]
    3745                 :            : 
    3746         [ -  + ]:        271 :         if ( GetTextRanger() )
    3747                 :            :         {
    3748         [ #  # ]:          0 :             if ( bClipRegion )
    3749         [ #  # ]:          0 :                 pOutWin->SetClipRegion( aOldRegion );
    3750                 :            :             else
    3751         [ #  # ]:          0 :                 pOutWin->SetClipRegion();
    3752         [ #  # ]:          0 :             pOutWin->SetMapMode( aOldMapMode );
    3753                 :            :         }
    3754                 :            : 
    3755                 :            : 
    3756 [ +  - ][ +  - ]:        271 :         pView->DrawSelection();
                 [ +  - ]
    3757                 :            :     }
    3758                 :            :     else
    3759                 :            :     {
    3760                 :        520 :         Point aStartPos;
    3761         [ +  - ]:        520 :         if ( !IsVertical() )
    3762                 :            :         {
    3763                 :        520 :             aStartPos = pView->GetOutputArea().TopLeft();
    3764                 :        520 :             aStartPos.X() -= pView->GetVisDocLeft();
    3765                 :        520 :             aStartPos.Y() -= pView->GetVisDocTop();
    3766                 :            :         }
    3767                 :            :         else
    3768                 :            :         {
    3769         [ #  # ]:          0 :             aStartPos = pView->GetOutputArea().TopRight();
    3770                 :          0 :             aStartPos.X() += pView->GetVisDocTop();
    3771                 :          0 :             aStartPos.Y() -= pView->GetVisDocLeft();
    3772                 :            :         }
    3773                 :            : 
    3774                 :            :         // If Doc-width < Output Area,Width and not wrapped fields,
    3775                 :            :         // the fields usually protrude if > line.
    3776                 :            :         // (Not at the top, since there the Doc-width from formatting is already
    3777                 :            :         // there)
    3778 [ +  - ][ +  - ]:        520 :         if ( !IsVertical() && ( pView->GetOutputArea().GetWidth() > GetPaperSize().Width() ) )
         [ -  + ][ -  + ]
    3779                 :            :         {
    3780                 :          0 :             long nMaxX = pView->GetOutputArea().Left() + GetPaperSize().Width();
    3781         [ #  # ]:          0 :             if ( aClipRec.Left() > nMaxX )
    3782                 :            :                 return;
    3783         [ #  # ]:          0 :             if ( aClipRec.Right() > nMaxX )
    3784                 :          0 :                 aClipRec.Right() = nMaxX;
    3785                 :            :         }
    3786                 :            : 
    3787                 :        520 :         sal_Bool bClipRegion = pOutWin->IsClipRegion();
    3788         [ +  - ]:        520 :         Region aOldRegion = pOutWin->GetClipRegion();
    3789         [ +  - ]:        520 :         pOutWin->IntersectClipRegion( aClipRec );
    3790                 :            : 
    3791         [ +  - ]:        520 :         Paint( pOutWin, aClipRec, aStartPos );
    3792                 :            : 
    3793         [ -  + ]:        520 :         if ( bClipRegion )
    3794         [ #  # ]:          0 :             pOutWin->SetClipRegion( aOldRegion );
    3795                 :            :         else
    3796         [ +  - ]:        520 :             pOutWin->SetClipRegion();
    3797                 :            : 
    3798 [ +  - ][ +  - ]:        791 :         pView->DrawSelection();
    3799                 :            :     }
    3800                 :            : 
    3801                 :            : }
    3802                 :            : 
    3803                 :          0 : void ImpEditEngine::InsertContent( ContentNode* pNode, sal_uInt16 nPos )
    3804                 :            : {
    3805                 :            :     DBG_ASSERT( pNode, "NULL-Pointer in InsertContent! " );
    3806                 :            :     DBG_ASSERT( IsInUndo(), "InsertContent only for Undo()!" );
    3807         [ #  # ]:          0 :     ParaPortion* pNew = new ParaPortion( pNode );
    3808                 :          0 :     GetParaPortions().Insert(nPos, pNew);
    3809                 :          0 :     aEditDoc.Insert(nPos, pNode);
    3810         [ #  # ]:          0 :     if ( IsCallParaInsertedOrDeleted() )
    3811                 :          0 :         GetEditEnginePtr()->ParagraphInserted( nPos );
    3812                 :          0 : }
    3813                 :            : 
    3814                 :          0 : EditPaM ImpEditEngine::SplitContent( sal_uInt16 nNode, sal_uInt16 nSepPos )
    3815                 :            : {
    3816         [ #  # ]:          0 :     ContentNode* pNode = aEditDoc.GetObject( nNode );
    3817                 :            :     DBG_ASSERT( pNode, "Invalid Node in SplitContent" );
    3818                 :            :     DBG_ASSERT( IsInUndo(), "SplitContent only for Undo()!" );
    3819                 :            :     DBG_ASSERT( nSepPos <= pNode->Len(), "Index out of range: SplitContent" );
    3820         [ #  # ]:          0 :     EditPaM aPaM( pNode, nSepPos );
    3821         [ #  # ]:          0 :     return ImpInsertParaBreak( aPaM );
    3822                 :            : }
    3823                 :            : 
    3824                 :          0 : EditPaM ImpEditEngine::ConnectContents( sal_uInt16 nLeftNode, sal_Bool bBackward )
    3825                 :            : {
    3826                 :          0 :     ContentNode* pLeftNode = aEditDoc.GetObject( nLeftNode );
    3827                 :          0 :     ContentNode* pRightNode = aEditDoc.GetObject( nLeftNode+1 );
    3828                 :            :     DBG_ASSERT( pLeftNode, "Invalid left node in ConnectContents ");
    3829                 :            :     DBG_ASSERT( pRightNode, "Invalid right node in ConnectContents ");
    3830                 :            :     DBG_ASSERT( IsInUndo(), "ConnectContent only for Undo()!" );
    3831                 :          0 :     return ImpConnectParagraphs( pLeftNode, pRightNode, bBackward );
    3832                 :            : }
    3833                 :            : 
    3834                 :    2206307 : void ImpEditEngine::SetUpdateMode( bool bUp, EditView* pCurView, sal_Bool bForceUpdate )
    3835                 :            : {
    3836                 :    2206307 :     bool bChanged = ( GetUpdateMode() != bUp );
    3837                 :            : 
    3838                 :            :     // When switching from sal_True to sal_False, all selections were visible,
    3839                 :            :     // => paint over
    3840                 :            :     // the other hand, were all invisible => paint
    3841                 :            :     // If !bFormatted, e.g. after SetText, then if UpdateMode=sal_True
    3842                 :            :     // formatting is not needed immediately, probably because more text is coming.
    3843                 :            :     // At latest it is formatted at a Paint/CalcTextWidth.
    3844                 :    2206307 :     bUpdate = bUp;
    3845 [ +  + ][ +  + ]:    2206307 :     if ( bUpdate && ( bChanged || bForceUpdate ) )
                 [ +  + ]
    3846                 :     305577 :         FormatAndUpdate( pCurView );
    3847                 :    2206307 : }
    3848                 :            : 
    3849                 :          0 : void ImpEditEngine::ShowParagraph( sal_uInt16 nParagraph, bool bShow )
    3850                 :            : {
    3851                 :          0 :     ParaPortion* pPPortion = GetParaPortions().SafeGetObject( nParagraph );
    3852                 :            :     DBG_ASSERT( pPPortion, "ShowParagraph: Paragraph does not exist! ");
    3853 [ #  # ][ #  # ]:          0 :     if ( pPPortion && ( pPPortion->IsVisible() != bShow ) )
                 [ #  # ]
    3854                 :            :     {
    3855                 :          0 :         pPPortion->SetVisible( bShow );
    3856                 :            : 
    3857         [ #  # ]:          0 :         if ( !bShow )
    3858                 :            :         {
    3859                 :            :             // Mark as deleted, so that no selection will end or begin at
    3860                 :            :             // this paragraph...
    3861                 :          0 :             DeletedNodeInfo* pDelInfo = new DeletedNodeInfo( (sal_uIntPtr)pPPortion->GetNode(), nParagraph );
    3862                 :          0 :             aDeletedNodes.push_back(pDelInfo);
    3863                 :          0 :             UpdateSelections();
    3864                 :            :             // The region below will not be invalidated if UpdateMode = sal_False!
    3865                 :            :             // If anyway, then save as sal_False before SetVisible !
    3866                 :            :         }
    3867                 :            : 
    3868 [ #  # ][ #  # ]:          0 :         if ( bShow && ( pPPortion->IsInvalid() || !pPPortion->nHeight ) )
         [ #  # ][ #  # ]
    3869                 :            :         {
    3870         [ #  # ]:          0 :             if ( !GetTextRanger() )
    3871                 :            :             {
    3872         [ #  # ]:          0 :                 if ( pPPortion->IsInvalid() )
    3873                 :            :                 {
    3874         [ #  # ]:          0 :                     Font aOldFont( GetRefDevice()->GetFont() );
    3875         [ #  # ]:          0 :                     CreateLines( nParagraph, 0 );   // 0: No TextRanger
    3876         [ #  # ]:          0 :                     if ( aStatus.DoRestoreFont() )
    3877 [ #  # ][ #  # ]:          0 :                         GetRefDevice()->SetFont( aOldFont );
    3878                 :            :                 }
    3879                 :            :                 else
    3880                 :            :                 {
    3881                 :          0 :                     CalcHeight( pPPortion );
    3882                 :            :                 }
    3883                 :          0 :                 nCurTextHeight += pPPortion->GetHeight();
    3884                 :            :             }
    3885                 :            :             else
    3886                 :            :             {
    3887                 :          0 :                 nCurTextHeight = 0x7fffffff;
    3888                 :            :             }
    3889                 :            :         }
    3890                 :            : 
    3891                 :          0 :         pPPortion->SetMustRepaint( sal_True );
    3892 [ #  # ][ #  # ]:          0 :         if ( GetUpdateMode() && !IsInUndo() && !GetTextRanger() )
         [ #  # ][ #  # ]
    3893                 :            :         {
    3894                 :          0 :             aInvalidRec = Rectangle(    Point( 0, GetParaPortions().GetYOffset( pPPortion ) ),
    3895 [ #  # ][ #  # ]:          0 :                                         Point( GetPaperSize().Width(), nCurTextHeight ) );
    3896                 :          0 :             UpdateViews( GetActiveView() );
    3897                 :            :         }
    3898                 :            :     }
    3899                 :          0 : }
    3900                 :            : 
    3901                 :          0 : EditSelection ImpEditEngine::MoveParagraphs( Range aOldPositions, sal_uInt16 nNewPos, EditView* pCurView )
    3902                 :            : {
    3903                 :            :     DBG_ASSERT( GetParaPortions().Count() != 0, "No paragraphs found: MoveParagraphs" );
    3904 [ #  # ][ #  # ]:          0 :     if ( GetParaPortions().Count() == 0 )
    3905         [ #  # ]:          0 :         return EditSelection();
    3906                 :          0 :     aOldPositions.Justify();
    3907                 :            : 
    3908         [ #  # ]:          0 :     EditSelection aSel( ImpMoveParagraphs( aOldPositions, nNewPos ) );
    3909                 :            : 
    3910 [ #  # ][ #  # ]:          0 :     if ( nNewPos >= GetParaPortions().Count() )
    3911         [ #  # ]:          0 :         nNewPos = GetParaPortions().Count() - 1;
    3912                 :            : 
    3913                 :            :     // Where the paragraph was inserted it has to be properly redrawn:
    3914                 :            :     // Where the paragraph was removed it has to be properly redrawn:
    3915                 :            :     // ( and correspondingly in between as well...)
    3916 [ #  # ][ #  # ]:          0 :     if ( pCurView && ( GetUpdateMode() == sal_True ) )
                 [ #  # ]
    3917                 :            :     {
    3918                 :            :         // in this case one can redraw directly whithout invalidating the
    3919                 :            :         // Portions
    3920                 :          0 :         sal_uInt16 nFirstPortion = Min( (sal_uInt16)aOldPositions.Min(), nNewPos );
    3921                 :          0 :         sal_uInt16 nLastPortion = Max( (sal_uInt16)aOldPositions.Max(), nNewPos );
    3922                 :            : 
    3923         [ #  # ]:          0 :         ParaPortion* pUpperPortion = GetParaPortions().SafeGetObject( nFirstPortion );
    3924         [ #  # ]:          0 :         ParaPortion* pLowerPortion = GetParaPortions().SafeGetObject( nLastPortion );
    3925                 :            : 
    3926         [ #  # ]:          0 :         aInvalidRec = Rectangle();  // make empty
    3927                 :          0 :         aInvalidRec.Left() = 0;
    3928                 :          0 :         aInvalidRec.Right() = aPaperSize.Width();
    3929         [ #  # ]:          0 :         aInvalidRec.Top() = GetParaPortions().GetYOffset( pUpperPortion );
    3930         [ #  # ]:          0 :         aInvalidRec.Bottom() = GetParaPortions().GetYOffset( pLowerPortion ) + pLowerPortion->GetHeight();
    3931                 :            : 
    3932         [ #  # ]:          0 :         UpdateViews( pCurView );
    3933                 :            :     }
    3934                 :            :     else
    3935                 :            :     {
    3936                 :            :         // redraw from the upper invalid position
    3937                 :          0 :         sal_uInt16 nFirstInvPara = Min( (sal_uInt16)aOldPositions.Min(), nNewPos );
    3938         [ #  # ]:          0 :         InvalidateFromParagraph( nFirstInvPara );
    3939                 :            :     }
    3940         [ #  # ]:          0 :     return aSel;
    3941                 :            : }
    3942                 :            : 
    3943                 :          0 : void ImpEditEngine::InvalidateFromParagraph( sal_uInt16 nFirstInvPara )
    3944                 :            : {
    3945                 :            :     // The following paragraphs are not invalidated, since ResetHeight()
    3946                 :            :     // => size change => all the following are re-issued anyway.
    3947                 :            :     ParaPortion* pTmpPortion;
    3948         [ #  # ]:          0 :     if ( nFirstInvPara != 0 )
    3949                 :            :     {
    3950                 :          0 :         pTmpPortion = GetParaPortions()[nFirstInvPara-1];
    3951                 :          0 :         pTmpPortion->MarkInvalid( pTmpPortion->GetNode()->Len(), 0 );
    3952                 :            :     }
    3953                 :            :     else
    3954                 :            :     {
    3955                 :          0 :         pTmpPortion = GetParaPortions()[0];
    3956                 :          0 :         pTmpPortion->MarkSelectionInvalid( 0, pTmpPortion->GetNode()->Len() );
    3957                 :            :     }
    3958                 :          0 :     pTmpPortion->ResetHeight();
    3959                 :          0 : }
    3960                 :            : 
    3961                 :          0 : IMPL_LINK_NOARG_INLINE_START(ImpEditEngine, StatusTimerHdl)
    3962                 :            : {
    3963                 :          0 :     CallStatusHdl();
    3964                 :          0 :     return 0;
    3965                 :            : }
    3966                 :          0 : IMPL_LINK_NOARG_INLINE_END(ImpEditEngine, StatusTimerHdl)
    3967                 :            : 
    3968                 :     647119 : void ImpEditEngine::CallStatusHdl()
    3969                 :            : {
    3970 [ +  + ][ +  + ]:     647119 :     if ( aStatusHdlLink.IsSet() && aStatus.GetStatusWord() )
                 [ +  + ]
    3971                 :            :     {
    3972                 :            :         // The Status has to be reset before the Call,
    3973                 :            :         // since other Flags might be set in the handler...
    3974                 :       3187 :         EditStatus aTmpStatus( aStatus );
    3975                 :       3187 :         aStatus.Clear();
    3976         [ +  - ]:       3187 :         aStatusHdlLink.Call( &aTmpStatus );
    3977         [ +  - ]:       3187 :         aStatusTimer.Stop();    // If called by hand ...
    3978                 :            :     }
    3979                 :     647119 : }
    3980                 :            : 
    3981                 :          0 : ContentNode* ImpEditEngine::GetPrevVisNode( ContentNode* pCurNode )
    3982                 :            : {
    3983                 :          0 :     const ParaPortion* pPortion = FindParaPortion( pCurNode );
    3984                 :            :     DBG_ASSERT( pPortion, "GetPrevVisibleNode: No matching portion!" );
    3985                 :          0 :     pPortion = GetPrevVisPortion( pPortion );
    3986         [ #  # ]:          0 :     if ( pPortion )
    3987                 :          0 :         return pPortion->GetNode();
    3988                 :          0 :     return 0;
    3989                 :            : }
    3990                 :            : 
    3991                 :          0 : ContentNode* ImpEditEngine::GetNextVisNode( ContentNode* pCurNode )
    3992                 :            : {
    3993                 :          0 :     const ParaPortion* pPortion = FindParaPortion( pCurNode );
    3994                 :            :     DBG_ASSERT( pPortion, "GetNextVisibleNode: No matching portion!" );
    3995                 :          0 :     pPortion = GetNextVisPortion( pPortion );
    3996         [ #  # ]:          0 :     if ( pPortion )
    3997                 :          0 :         return pPortion->GetNode();
    3998                 :          0 :     return 0;
    3999                 :            : }
    4000                 :            : 
    4001                 :          0 : const ParaPortion* ImpEditEngine::GetPrevVisPortion( const ParaPortion* pCurPortion ) const
    4002                 :            : {
    4003                 :          0 :     sal_uInt16 nPara = GetParaPortions().GetPos( pCurPortion );
    4004                 :            :     DBG_ASSERT( nPara < GetParaPortions().Count() , "Portion not found: GetPrevVisPortion" );
    4005         [ #  # ]:          0 :     const ParaPortion* pPortion = nPara ? GetParaPortions()[--nPara] : 0;
    4006 [ #  # ][ #  # ]:          0 :     while ( pPortion && !pPortion->IsVisible() )
                 [ #  # ]
    4007         [ #  # ]:          0 :         pPortion = nPara ? GetParaPortions()[--nPara] : 0;
    4008                 :            : 
    4009                 :          0 :     return pPortion;
    4010                 :            : }
    4011                 :            : 
    4012                 :          0 : const ParaPortion* ImpEditEngine::GetNextVisPortion( const ParaPortion* pCurPortion ) const
    4013                 :            : {
    4014                 :          0 :     sal_uInt16 nPara = GetParaPortions().GetPos( pCurPortion );
    4015                 :            :     DBG_ASSERT( nPara < GetParaPortions().Count() , "Portion not found: GetPrevVisNode" );
    4016                 :          0 :     const ParaPortion* pPortion = GetParaPortions().SafeGetObject( ++nPara );
    4017 [ #  # ][ #  # ]:          0 :     while ( pPortion && !pPortion->IsVisible() )
                 [ #  # ]
    4018                 :          0 :         pPortion = GetParaPortions().SafeGetObject( ++nPara );
    4019                 :            : 
    4020                 :          0 :     return pPortion;
    4021                 :            : }
    4022                 :            : 
    4023                 :      16003 : long ImpEditEngine::CalcVertLineSpacing(Point& rStartPos) const
    4024                 :            : {
    4025                 :      16003 :     long nTotalOccupiedHeight = 0;
    4026                 :      16003 :     sal_uInt16 nTotalLineCount = 0;
    4027                 :      16003 :     const ParaPortionList& rParaPortions = GetParaPortions();
    4028                 :      16003 :     sal_uInt16 nParaCount = rParaPortions.Count();
    4029                 :            : 
    4030         [ +  + ]:      16120 :     for (sal_uInt16 i = 0; i < nParaCount; ++i)
    4031                 :            :     {
    4032         [ +  + ]:      16003 :         if (GetVerJustification(i) != SVX_VER_JUSTIFY_BLOCK)
    4033                 :            :             // All paragraphs must have the block justification set.
    4034                 :      15886 :             return 0;
    4035                 :            : 
    4036                 :        117 :         const ParaPortion* pPortion = rParaPortions[i];
    4037                 :        117 :         nTotalOccupiedHeight += pPortion->GetFirstLineOffset();
    4038                 :            : 
    4039                 :        117 :         const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem(EE_PARA_SBL);
    4040                 :        117 :         sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
    4041         [ -  + ]:        117 :                             ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
    4042                 :            : 
    4043                 :        117 :         const SvxULSpaceItem& rULItem = (const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem(EE_PARA_ULSPACE);
    4044                 :        117 :         long nUL = GetYValue( rULItem.GetLower() );
    4045                 :            : 
    4046                 :        117 :         const EditLineList& rLines = pPortion->GetLines();
    4047                 :        117 :         sal_uInt16 nLineCount = rLines.Count();
    4048                 :        117 :         nTotalLineCount += nLineCount;
    4049         [ +  + ]:        583 :         for (sal_uInt16 j = 0; j < nLineCount; ++j)
    4050                 :            :         {
    4051                 :        466 :             const EditLine* pLine = rLines[j];
    4052                 :        466 :             nTotalOccupiedHeight += pLine->GetHeight();
    4053         [ +  + ]:        466 :             if (j < nLineCount-1)
    4054                 :        349 :                 nTotalOccupiedHeight += nSBL;
    4055                 :        466 :             nTotalOccupiedHeight += nUL;
    4056                 :            :         }
    4057                 :            :     }
    4058                 :            : 
    4059         [ -  + ]:        117 :     long nTotalSpace = IsVertical() ? aPaperSize.Width() : aPaperSize.Height();
    4060                 :        117 :     nTotalSpace -= nTotalOccupiedHeight;
    4061 [ -  + ][ #  # ]:        117 :     if (nTotalSpace <= 0 || nTotalLineCount <= 1)
    4062                 :        117 :         return 0;
    4063                 :            : 
    4064         [ #  # ]:          0 :     if (IsVertical())
    4065                 :            :         // Shift the text to the right for the asian layout mode.
    4066                 :          0 :         rStartPos.X() += nTotalSpace;
    4067                 :            : 
    4068                 :      16003 :     return nTotalSpace / (nTotalLineCount-1);
    4069                 :            : }
    4070                 :            : 
    4071                 :        492 : EditPaM ImpEditEngine::InsertParagraph( sal_uInt16 nPara )
    4072                 :            : {
    4073         [ +  - ]:        492 :     EditPaM aPaM;
    4074         [ +  - ]:        492 :     if ( nPara != 0 )
    4075                 :            :     {
    4076         [ +  - ]:        492 :         ContentNode* pNode = GetEditDoc().GetObject( nPara-1 );
    4077         [ -  + ]:        492 :         if ( !pNode )
    4078 [ #  # ][ #  # ]:          0 :             pNode = GetEditDoc().GetObject( GetEditDoc().Count() - 1 );
    4079                 :            :         DBG_ASSERT( pNode, "Not a single paragraph in InsertParagraph ?" );
    4080 [ +  - ][ +  - ]:        492 :         aPaM = EditPaM( pNode, pNode->Len() );
                 [ +  - ]
    4081                 :            :     }
    4082                 :            :     else
    4083                 :            :     {
    4084         [ #  # ]:          0 :         ContentNode* pNode = GetEditDoc().GetObject( 0 );
    4085 [ #  # ][ #  # ]:          0 :         aPaM = EditPaM( pNode, 0 );
    4086                 :            :     }
    4087                 :            : 
    4088         [ +  - ]:        492 :     return ImpInsertParaBreak( aPaM );
    4089                 :            : }
    4090                 :            : 
    4091                 :      23786 : EditSelection* ImpEditEngine::SelectParagraph( sal_uInt16 nPara )
    4092                 :            : {
    4093                 :      23786 :     EditSelection* pSel = 0;
    4094                 :      23786 :     ContentNode* pNode = GetEditDoc().GetObject( nPara );
    4095                 :            :     DBG_ASSERTWARNING( pNode, "Paragraph does not exist: SelectParagraph" );
    4096         [ +  - ]:      23786 :     if ( pNode )
    4097 [ +  - ][ +  - ]:      23786 :         pSel = new EditSelection( EditPaM( pNode, 0 ), EditPaM( pNode, pNode->Len() ) );
         [ +  - ][ +  - ]
    4098                 :            : 
    4099                 :      23786 :     return pSel;
    4100                 :            : }
    4101                 :            : 
    4102                 :    1074774 : void ImpEditEngine::FormatAndUpdate( EditView* pCurView )
    4103                 :            : {
    4104         [ -  + ]:    1074774 :     if ( bDowning )
    4105                 :    1074774 :         return ;
    4106                 :            : 
    4107         [ -  + ]:    1074774 :     if ( IsInUndo() )
    4108                 :          0 :         IdleFormatAndUpdate( pCurView );
    4109                 :            :     else
    4110                 :            :     {
    4111                 :    1074774 :         FormatDoc();
    4112                 :    1074774 :         UpdateViews( pCurView );
    4113                 :            :     }
    4114                 :            : }
    4115                 :            : 
    4116                 :          0 : void ImpEditEngine::SetFlatMode( sal_Bool bFlat )
    4117                 :            : {
    4118         [ #  # ]:          0 :     if ( bFlat != aStatus.UseCharAttribs() )
    4119                 :          0 :         return;
    4120                 :            : 
    4121         [ #  # ]:          0 :     if ( !bFlat )
    4122                 :          0 :         aStatus.TurnOnFlags( EE_CNTRL_USECHARATTRIBS );
    4123                 :            :     else
    4124                 :          0 :         aStatus.TurnOffFlags( EE_CNTRL_USECHARATTRIBS );
    4125                 :            : 
    4126                 :          0 :     aEditDoc.CreateDefFont( !bFlat );
    4127                 :            : 
    4128                 :          0 :     FormatFullDoc();
    4129                 :          0 :     UpdateViews( (EditView*) 0);
    4130         [ #  # ]:          0 :     if ( pActiveView )
    4131                 :          0 :         pActiveView->ShowCursor();
    4132                 :            : }
    4133                 :            : 
    4134                 :     353541 : void ImpEditEngine::SetCharStretching( sal_uInt16 nX, sal_uInt16 nY )
    4135                 :            : {
    4136                 :     353541 :     bool bChanged(false);
    4137         [ +  - ]:     353541 :     if ( !IsVertical() )
    4138                 :            :     {
    4139 [ +  - ][ -  + ]:     353541 :         bChanged = nStretchX!=nX || nStretchY!=nY;
    4140                 :     353541 :         nStretchX = nX;
    4141                 :     353541 :         nStretchY = nY;
    4142                 :            :     }
    4143                 :            :     else
    4144                 :            :     {
    4145 [ #  # ][ #  # ]:          0 :         bChanged = nStretchX!=nY || nStretchY!=nX;
    4146                 :          0 :         nStretchX = nY;
    4147                 :          0 :         nStretchY = nX;
    4148                 :            :     }
    4149                 :            : 
    4150 [ -  + ][ #  # ]:     353541 :     if (bChanged && aStatus.DoStretch())
                 [ -  + ]
    4151                 :            :     {
    4152                 :          0 :         FormatFullDoc();
    4153                 :            :         // (potentially) need everything redrawn
    4154                 :          0 :         aInvalidRec=Rectangle(0,0,1000000,1000000);
    4155                 :          0 :         UpdateViews( GetActiveView() );
    4156                 :            :     }
    4157                 :     353541 : }
    4158                 :            : 
    4159                 :     415076 : const SvxNumberFormat* ImpEditEngine::GetNumberFormat( const ContentNode *pNode ) const
    4160                 :            : {
    4161                 :     415076 :     const SvxNumberFormat *pRes = 0;
    4162                 :            : 
    4163         [ +  - ]:     415076 :     if (pNode)
    4164                 :            :     {
    4165                 :            :         // get index of paragraph
    4166                 :     415076 :         sal_uInt16 nPara = GetEditDoc().GetPos( const_cast< ContentNode * >(pNode) );
    4167                 :            :         DBG_ASSERT( nPara < USHRT_MAX, "node not found in array" );
    4168         [ +  - ]:     415076 :         if (nPara < USHRT_MAX)
    4169                 :            :         {
    4170                 :            :             // the called function may be overloaded by an OutlinerEditEng object to provide
    4171                 :            :             // access to the SvxNumberFormat of the Outliner.
    4172                 :            :             // The EditEngine implementation will just return 0.
    4173                 :     415076 :             pRes = pEditEngine->GetNumberFormat( nPara );
    4174                 :            :         }
    4175                 :            :     }
    4176                 :            : 
    4177                 :     415076 :     return pRes;
    4178                 :            : }
    4179                 :            : 
    4180                 :     415076 : sal_Int32 ImpEditEngine::GetSpaceBeforeAndMinLabelWidth(
    4181                 :            :     const ContentNode *pNode,
    4182                 :            :     sal_Int32 *pnSpaceBefore, sal_Int32 *pnMinLabelWidth ) const
    4183                 :            : {
    4184                 :            :     // nSpaceBefore     matches the ODF attribut text:space-before
    4185                 :            :     // nMinLabelWidth   matches the ODF attribut text:min-label-width
    4186                 :            : 
    4187                 :     415076 :     const SvxNumberFormat *pNumFmt = GetNumberFormat( pNode );
    4188                 :            : 
    4189                 :            :     // if no number format was found we have no Outliner or the numbering level
    4190                 :            :     // within the Outliner is -1 which means no number format should be applied.
    4191                 :            :     // Thus the default values to be returned are 0.
    4192                 :     415076 :     sal_Int32 nSpaceBefore   = 0;
    4193                 :     415076 :     sal_Int32 nMinLabelWidth = 0;
    4194                 :            : 
    4195         [ +  + ]:     415076 :     if (pNumFmt)
    4196                 :            :     {
    4197                 :       3045 :         nMinLabelWidth = -pNumFmt->GetFirstLineOffset();
    4198                 :       3045 :         nSpaceBefore   = pNumFmt->GetAbsLSpace() - nMinLabelWidth;
    4199                 :            :         DBG_ASSERT( nMinLabelWidth >= 0, "ImpEditEngine::GetSpaceBeforeAndMinLabelWidth: min-label-width < 0 encountered" );
    4200                 :            :     }
    4201         [ +  + ]:     415076 :     if (pnSpaceBefore)
    4202                 :     324600 :         *pnSpaceBefore      = nSpaceBefore;
    4203         [ +  + ]:     415076 :     if (pnMinLabelWidth)
    4204                 :     114343 :         *pnMinLabelWidth    = nMinLabelWidth;
    4205                 :            : 
    4206                 :     415076 :     return nSpaceBefore + nMinLabelWidth;
    4207                 :            : }
    4208                 :            : 
    4209                 :     415076 : const SvxLRSpaceItem& ImpEditEngine::GetLRSpaceItem( ContentNode* pNode )
    4210                 :            : {
    4211         [ -  + ]:     415076 :     return (const SvxLRSpaceItem&)pNode->GetContentAttribs().GetItem( aStatus.IsOutliner() ? EE_PARA_OUTLLRSPACE : EE_PARA_LRSPACE );
    4212                 :            : }
    4213                 :            : 
    4214                 :            : // Either sets the digit mode at the output device or
    4215                 :            : // modifies the passed string according to the text numeral setting:
    4216                 :     459980 : void ImpEditEngine::ImplInitDigitMode( OutputDevice* pOutDev, String* pString, xub_StrLen nStt, xub_StrLen nLen, LanguageType eCurLang )
    4217                 :            : {
    4218                 :            :     // #114278# Also setting up digit language from Svt options
    4219                 :            :     // (cannot reliably inherit the outdev's setting)
    4220         [ -  + ]:     459980 :     if( !pCTLOptions )
    4221         [ #  # ]:          0 :         pCTLOptions = new SvtCTLOptions;
    4222                 :            : 
    4223                 :     459980 :     LanguageType eLang = eCurLang;
    4224                 :     459980 :     const SvtCTLOptions::TextNumerals nCTLTextNumerals = pCTLOptions->GetCTLTextNumerals();
    4225                 :            : 
    4226         [ -  + ]:     459980 :     if ( SvtCTLOptions::NUMERALS_HINDI == nCTLTextNumerals )
    4227                 :          0 :         eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
    4228         [ +  - ]:     459980 :     else if ( SvtCTLOptions::NUMERALS_ARABIC == nCTLTextNumerals )
    4229                 :     459980 :         eLang = LANGUAGE_ENGLISH;
    4230         [ #  # ]:          0 :     else if ( SvtCTLOptions::NUMERALS_SYSTEM == nCTLTextNumerals )
    4231                 :          0 :         eLang = (LanguageType) Application::GetSettings().GetLanguage();
    4232                 :            : 
    4233         [ +  + ]:     459980 :     if(pOutDev)
    4234                 :            :     {
    4235                 :     441946 :         pOutDev->SetDigitLanguage( eLang );
    4236                 :            :     }
    4237         [ +  - ]:      18034 :     else if (pString)
    4238                 :            :     {
    4239                 :            :         // see sallayout.cxx in vcl
    4240                 :            :         int nOffset;
    4241      [ +  -  - ]:      18034 :         switch( eLang & LANGUAGE_MASK_PRIMARY )
    4242                 :            :         {
    4243                 :            :             default:
    4244                 :      18034 :                 nOffset = 0;
    4245                 :      18034 :                 break;
    4246                 :            :             case LANGUAGE_ARABIC_SAUDI_ARABIA  & LANGUAGE_MASK_PRIMARY:
    4247                 :          0 :                 nOffset = 0x0660 - '0';  // arabic-indic digits
    4248                 :          0 :                 break;
    4249                 :            :             case LANGUAGE_URDU          & LANGUAGE_MASK_PRIMARY:
    4250                 :            :             case LANGUAGE_PUNJABI       & LANGUAGE_MASK_PRIMARY: //???
    4251                 :            :             case LANGUAGE_SINDHI        & LANGUAGE_MASK_PRIMARY:
    4252                 :          0 :                 nOffset = 0x06F0 - '0';  // eastern arabic-indic digits
    4253                 :          0 :                 break;
    4254                 :            :         }
    4255         [ -  + ]:      18034 :         if (nOffset)
    4256                 :            :         {
    4257                 :          0 :             const xub_StrLen nEnd = nStt + nLen;
    4258         [ #  # ]:          0 :             for( xub_StrLen nIdx = nStt; nIdx < nEnd; ++nIdx )
    4259                 :            :             {
    4260                 :          0 :                 sal_Unicode nChar = pString->GetChar( nIdx );
    4261 [ #  # ][ #  # ]:          0 :                 if( (nChar < '0') || ('9' < nChar) )
    4262                 :          0 :                     continue;
    4263                 :          0 :                 nChar = (sal_Unicode)(nChar + nOffset);
    4264                 :          0 :                 pString->SetChar( nIdx, nChar );
    4265                 :            :             }
    4266                 :            :         }
    4267                 :            :     }
    4268                 :     459980 : }
    4269                 :            : 
    4270                 :     229472 : void ImpEditEngine::ImplInitLayoutMode( OutputDevice* pOutDev, sal_uInt16 nPara, sal_uInt16 nIndex )
    4271                 :            : {
    4272                 :     229472 :     sal_Bool bCTL = sal_False;
    4273                 :     229472 :     sal_uInt8 bR2L = sal_False;
    4274         [ +  + ]:     229472 :     if ( nIndex == 0xFFFF )
    4275                 :            :     {
    4276                 :     208354 :         bCTL = HasScriptType( nPara, i18n::ScriptType::COMPLEX );
    4277                 :     208354 :         bR2L = IsRightToLeft( nPara );
    4278                 :            :     }
    4279                 :            :     else
    4280                 :            :     {
    4281                 :      21118 :         ContentNode* pNode = GetEditDoc().GetObject( nPara );
    4282         [ +  - ]:      21118 :         short nScriptType = GetScriptType( EditPaM( pNode, nIndex+1 ) );
    4283                 :      21118 :         bCTL = nScriptType == i18n::ScriptType::COMPLEX;
    4284                 :      21118 :         bR2L = GetRightToLeft( nPara, nIndex + 1);  // this change was discussed in issue 37190
    4285                 :            :                                                     // it also works for issue 55927
    4286                 :            :     }
    4287                 :            : 
    4288                 :     229472 :     sal_uLong nLayoutMode = pOutDev->GetLayoutMode();
    4289                 :            : 
    4290                 :            :     // We always use the left postion for DrawText()
    4291                 :     229472 :     nLayoutMode &= ~(TEXT_LAYOUT_BIDI_RTL);
    4292                 :            : 
    4293 [ +  + ][ +  - ]:     229472 :     if ( !bCTL && !bR2L)
    4294                 :            :     {
    4295                 :            :         // No CTL/Bidi checking neccessary
    4296                 :     227024 :         nLayoutMode |= ( TEXT_LAYOUT_COMPLEX_DISABLED | TEXT_LAYOUT_BIDI_STRONG );
    4297                 :            :     }
    4298                 :            :     else
    4299                 :            :     {
    4300                 :            :         // CTL/Bidi checking neccessary
    4301                 :            :         // Don't use BIDI_STRONG, VCL must do some checks.
    4302                 :       2448 :         nLayoutMode &= ~( TEXT_LAYOUT_COMPLEX_DISABLED | TEXT_LAYOUT_BIDI_STRONG );
    4303                 :            : 
    4304         [ +  - ]:       2448 :         if ( bR2L )
    4305                 :       2448 :             nLayoutMode |= TEXT_LAYOUT_BIDI_RTL|TEXT_LAYOUT_TEXTORIGIN_LEFT;
    4306                 :            :     }
    4307                 :            : 
    4308                 :     229472 :     pOutDev->SetLayoutMode( nLayoutMode );
    4309                 :            : 
    4310                 :            :     // #114278# Also setting up digit language from Svt options
    4311                 :            :     // (cannot reliably inherit the outdev's setting)
    4312                 :            :     LanguageType eLang;
    4313                 :            : 
    4314         [ +  + ]:     229472 :     if( !pCTLOptions )
    4315         [ +  - ]:       4095 :         pCTLOptions = new SvtCTLOptions;
    4316                 :            : 
    4317         [ -  + ]:     229472 :     if ( SvtCTLOptions::NUMERALS_HINDI == pCTLOptions->GetCTLTextNumerals() )
    4318                 :          0 :         eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
    4319         [ +  - ]:     229472 :     else if ( SvtCTLOptions::NUMERALS_ARABIC == pCTLOptions->GetCTLTextNumerals() )
    4320                 :     229472 :         eLang = LANGUAGE_ENGLISH;
    4321                 :            :     else
    4322                 :          0 :         eLang = (LanguageType) Application::GetSettings().GetLanguage();
    4323                 :            : 
    4324                 :     229472 :     pOutDev->SetDigitLanguage( eLang );
    4325                 :     229472 : }
    4326                 :            : 
    4327                 :     284090 : Reference < i18n::XBreakIterator > ImpEditEngine::ImplGetBreakIterator() const
    4328                 :            : {
    4329         [ +  + ]:     284090 :     if ( !xBI.is() )
    4330                 :            :     {
    4331         [ +  - ]:      20421 :         Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() );
    4332 [ +  - ][ +  - ]:      20421 :         xBI.set( xMSF->createInstance( OUString( "com.sun.star.i18n.BreakIterator" ) ), UNO_QUERY );
                 [ +  - ]
    4333                 :            :     }
    4334                 :     284090 :     return xBI;
    4335                 :            : }
    4336                 :            : 
    4337                 :          0 : Reference < i18n::XExtendedInputSequenceChecker > ImpEditEngine::ImplGetInputSequenceChecker() const
    4338                 :            : {
    4339         [ #  # ]:          0 :     if ( !xISC.is() )
    4340                 :            :     {
    4341         [ #  # ]:          0 :         Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
    4342 [ #  # ][ #  # ]:          0 :         Reference < XInterface > xI = xMSF->createInstance( OUString( "com.sun.star.i18n.InputSequenceChecker" ) );
    4343         [ #  # ]:          0 :         if ( xI.is() )
    4344                 :            :         {
    4345 [ #  # ][ #  # ]:          0 :             Any x = xI->queryInterface( ::getCppuType((const Reference< i18n::XExtendedInputSequenceChecker >*)0) );
                 [ #  # ]
    4346         [ #  # ]:          0 :             x >>= xISC;
    4347                 :          0 :         }
    4348                 :            :     }
    4349                 :          0 :     return xISC;
    4350                 :            : }
    4351                 :            : 
    4352                 :      17004 : Color ImpEditEngine::GetAutoColor() const
    4353                 :            : {
    4354                 :      17004 :     Color aColor = const_cast<ImpEditEngine*>(this)->GetColorConfig().GetColorValue( svtools::FONTCOLOR ).nColor;
    4355                 :            : 
    4356         [ +  + ]:      17004 :     if ( GetBackgroundColor() != COL_AUTO )
    4357                 :            :     {
    4358 [ +  - ][ +  + ]:       6634 :         if ( GetBackgroundColor().IsDark() && aColor.IsDark() )
         [ +  - ][ +  - ]
                 [ +  - ]
           [ +  +  #  # ]
    4359                 :          1 :             aColor = COL_WHITE;
    4360 [ +  - ][ +  + ]:       6633 :         else if ( GetBackgroundColor().IsBright() && aColor.IsBright() )
         [ +  - ][ -  + ]
                 [ +  - ]
           [ -  +  #  # ]
    4361                 :          0 :             aColor = COL_BLACK;
    4362                 :            :     }
    4363                 :            : 
    4364                 :      17004 :     return aColor;
    4365                 :            : }
    4366                 :            : 
    4367                 :            : 
    4368                 :          0 : sal_Bool ImpEditEngine::ImplCalcAsianCompression( ContentNode* pNode, TextPortion* pTextPortion, sal_uInt16 nStartPos, sal_Int32* pDXArray, sal_uInt16 n100thPercentFromMax, sal_Bool bManipulateDXArray )
    4369                 :            : {
    4370                 :            :     DBG_ASSERT( GetAsianCompressionMode(), "ImplCalcAsianCompression - Why?" );
    4371                 :            :     DBG_ASSERT( pTextPortion->GetLen(), "ImplCalcAsianCompression - Empty Portion?" );
    4372                 :            : 
    4373                 :            :     // Percent is 1/100 Percent...
    4374         [ #  # ]:          0 :     if ( n100thPercentFromMax == 10000 )
    4375                 :          0 :         pTextPortion->SetExtraInfos( NULL );
    4376                 :            : 
    4377                 :          0 :     sal_Bool bCompressed = sal_False;
    4378                 :            : 
    4379 [ #  # ][ #  # ]:          0 :     if ( GetScriptType( EditPaM( pNode, nStartPos+1 ) ) == i18n::ScriptType::ASIAN )
    4380                 :            :     {
    4381                 :          0 :         long nNewPortionWidth = pTextPortion->GetSize().Width();
    4382                 :          0 :         sal_uInt16 nPortionLen = pTextPortion->GetLen();
    4383         [ #  # ]:          0 :         for ( sal_uInt16 n = 0; n < nPortionLen; n++ )
    4384                 :            :         {
    4385                 :          0 :             sal_uInt8 nType = GetCharTypeForCompression( pNode->GetChar( n+nStartPos ) );
    4386                 :            : 
    4387 [ #  # ][ #  # ]:          0 :             sal_Bool bCompressPunctuation = ( nType == CHAR_PUNCTUATIONLEFT ) || ( nType == CHAR_PUNCTUATIONRIGHT );
    4388 [ #  # ][ #  # ]:          0 :             sal_Bool bCompressKana = ( nType == CHAR_KANA ) && ( GetAsianCompressionMode() == text::CharacterCompressionType::PUNCTUATION_AND_KANA );
    4389                 :            : 
    4390                 :            :             // create Extra infos only if needed...
    4391 [ #  # ][ #  # ]:          0 :             if ( bCompressPunctuation || bCompressKana )
    4392                 :            :             {
    4393         [ #  # ]:          0 :                 if ( !pTextPortion->GetExtraInfos() )
    4394                 :            :                 {
    4395         [ #  # ]:          0 :                     ExtraPortionInfo* pExtraInfos = new ExtraPortionInfo;
    4396                 :          0 :                     pTextPortion->SetExtraInfos( pExtraInfos );
    4397                 :          0 :                     pExtraInfos->nOrgWidth = pTextPortion->GetSize().Width();
    4398                 :          0 :                     pExtraInfos->nAsianCompressionTypes = CHAR_NORMAL;
    4399                 :            :                 }
    4400                 :          0 :                 pTextPortion->GetExtraInfos()->nMaxCompression100thPercent = n100thPercentFromMax;
    4401                 :          0 :                 pTextPortion->GetExtraInfos()->nAsianCompressionTypes |= nType;
    4402                 :            : 
    4403                 :            :                 long nOldCharWidth;
    4404         [ #  # ]:          0 :                 if ( (n+1) < nPortionLen )
    4405                 :            :                 {
    4406                 :          0 :                     nOldCharWidth = pDXArray[n];
    4407                 :            :                 }
    4408                 :            :                 else
    4409                 :            :                 {
    4410         [ #  # ]:          0 :                     if ( bManipulateDXArray )
    4411                 :          0 :                         nOldCharWidth = nNewPortionWidth - pTextPortion->GetExtraInfos()->nPortionOffsetX;
    4412                 :            :                     else
    4413                 :          0 :                         nOldCharWidth = pTextPortion->GetExtraInfos()->nOrgWidth;
    4414                 :            :                 }
    4415         [ #  # ]:          0 :                 nOldCharWidth -= ( n ? pDXArray[n-1] : 0 );
    4416                 :            : 
    4417                 :          0 :                 long nCompress = 0;
    4418                 :            : 
    4419         [ #  # ]:          0 :                 if ( bCompressPunctuation )
    4420                 :            :                 {
    4421                 :          0 :                     nCompress = nOldCharWidth / 2;
    4422                 :            :                 }
    4423                 :            :                 else // Kana
    4424                 :            :                 {
    4425                 :          0 :                     nCompress = nOldCharWidth / 10;
    4426                 :            :                 }
    4427                 :            : 
    4428         [ #  # ]:          0 :                 if ( n100thPercentFromMax != 10000 )
    4429                 :            :                 {
    4430                 :          0 :                     nCompress *= n100thPercentFromMax;
    4431                 :          0 :                     nCompress /= 10000;
    4432                 :            :                 }
    4433                 :            : 
    4434         [ #  # ]:          0 :                 if ( nCompress )
    4435                 :            :                 {
    4436                 :          0 :                     bCompressed = sal_True;
    4437                 :          0 :                     nNewPortionWidth -= nCompress;
    4438                 :          0 :                     pTextPortion->GetExtraInfos()->bCompressed = sal_True;
    4439                 :            : 
    4440                 :            : 
    4441                 :            :                     // Special handling for rightpunctuation: For the 'compression' we must
    4442                 :            :                     // start the output before the normal char position....
    4443 [ #  # ][ #  # ]:          0 :                     if ( bManipulateDXArray && ( pTextPortion->GetLen() > 1 ) )
                 [ #  # ]
    4444                 :            :                     {
    4445         [ #  # ]:          0 :                         if ( !pTextPortion->GetExtraInfos()->pOrgDXArray )
    4446                 :          0 :                             pTextPortion->GetExtraInfos()->SaveOrgDXArray( pDXArray, pTextPortion->GetLen()-1 );
    4447                 :            : 
    4448         [ #  # ]:          0 :                         if ( nType == CHAR_PUNCTUATIONRIGHT )
    4449                 :            :                         {
    4450                 :            :                             // If it's the first char, I must handle it in Paint()...
    4451         [ #  # ]:          0 :                             if ( n )
    4452                 :            :                             {
    4453                 :            :                                 // -1: No entry for the last character
    4454         [ #  # ]:          0 :                                 for ( sal_uInt16 i = n-1; i < (nPortionLen-1); i++ )
    4455                 :          0 :                                     pDXArray[i] -= nCompress;
    4456                 :            :                             }
    4457                 :            :                             else
    4458                 :            :                             {
    4459                 :          0 :                                 pTextPortion->GetExtraInfos()->bFirstCharIsRightPunktuation = sal_True;
    4460                 :          0 :                                 pTextPortion->GetExtraInfos()->nPortionOffsetX = -nCompress;
    4461                 :            :                             }
    4462                 :            :                         }
    4463                 :            :                         else
    4464                 :            :                         {
    4465                 :            :                             // -1: No entry for the last character
    4466         [ #  # ]:          0 :                             for ( sal_uInt16 i = n; i < (nPortionLen-1); i++ )
    4467                 :          0 :                                 pDXArray[i] -= nCompress;
    4468                 :            :                         }
    4469                 :            :                     }
    4470                 :            :                 }
    4471                 :            :             }
    4472                 :            :         }
    4473                 :            : 
    4474 [ #  # ][ #  # ]:          0 :         if ( bCompressed && ( n100thPercentFromMax == 10000 ) )
    4475                 :          0 :             pTextPortion->GetExtraInfos()->nWidthFullCompression = nNewPortionWidth;
    4476                 :            : 
    4477                 :          0 :         pTextPortion->GetSize().Width() = nNewPortionWidth;
    4478                 :            : 
    4479 [ #  # ][ #  # ]:          0 :         if ( pTextPortion->GetExtraInfos() && ( n100thPercentFromMax != 10000 ) )
                 [ #  # ]
    4480                 :            :         {
    4481                 :            :             // Maybe rounding errors in nNewPortionWidth, assure that width not bigger than expected
    4482                 :          0 :             long nShrink = pTextPortion->GetExtraInfos()->nOrgWidth - pTextPortion->GetExtraInfos()->nWidthFullCompression;
    4483                 :          0 :             nShrink *= n100thPercentFromMax;
    4484                 :          0 :             nShrink /= 10000;
    4485                 :          0 :             long nNewWidth = pTextPortion->GetExtraInfos()->nOrgWidth - nShrink;
    4486         [ #  # ]:          0 :             if ( nNewWidth < pTextPortion->GetSize().Width() )
    4487                 :          0 :             pTextPortion->GetSize().Width() = nNewWidth;
    4488                 :            :         }
    4489                 :            :     }
    4490                 :          0 :     return bCompressed;
    4491                 :            : }
    4492                 :            : 
    4493                 :            : 
    4494                 :          0 : void ImpEditEngine::ImplExpandCompressedPortions( EditLine* pLine, ParaPortion* pParaPortion, long nRemainingWidth )
    4495                 :            : {
    4496                 :          0 :     sal_Bool bFoundCompressedPortion = sal_False;
    4497                 :          0 :     long nCompressed = 0;
    4498         [ #  # ]:          0 :     std::vector<TextPortion*> aCompressedPortions;
    4499                 :            : 
    4500                 :          0 :     sal_uInt16 nPortion = pLine->GetEndPortion();
    4501         [ #  # ]:          0 :     TextPortion* pTP = pParaPortion->GetTextPortions()[ nPortion ];
    4502 [ #  # ][ #  # ]:          0 :     while ( pTP && ( pTP->GetKind() == PORTIONKIND_TEXT ) )
                 [ #  # ]
    4503                 :            :     {
    4504 [ #  # ][ #  # ]:          0 :         if ( pTP->GetExtraInfos() && pTP->GetExtraInfos()->bCompressed )
                 [ #  # ]
    4505                 :            :         {
    4506                 :          0 :             bFoundCompressedPortion = sal_True;
    4507                 :          0 :             nCompressed += pTP->GetExtraInfos()->nOrgWidth - pTP->GetSize().Width();
    4508         [ #  # ]:          0 :             aCompressedPortions.push_back(pTP);
    4509                 :            :         }
    4510 [ #  # ][ #  # ]:          0 :         pTP = ( nPortion > pLine->GetStartPortion() ) ? pParaPortion->GetTextPortions()[ --nPortion ] : NULL;
    4511                 :            :     }
    4512                 :            : 
    4513         [ #  # ]:          0 :     if ( bFoundCompressedPortion )
    4514                 :            :     {
    4515                 :          0 :         long nCompressPercent = 0;
    4516         [ #  # ]:          0 :         if ( nCompressed > nRemainingWidth )
    4517                 :            :         {
    4518                 :          0 :             nCompressPercent = nCompressed - nRemainingWidth;
    4519                 :            :             DBG_ASSERT( nCompressPercent < 200000, "ImplExpandCompressedPortions - Overflow!" );
    4520                 :          0 :             nCompressPercent *= 10000;
    4521                 :          0 :             nCompressPercent /= nCompressed;
    4522                 :            :         }
    4523                 :            : 
    4524         [ #  # ]:          0 :         for (size_t i = 0, n = aCompressedPortions.size(); i < n; ++i)
    4525                 :            :         {
    4526                 :          0 :             pTP = aCompressedPortions[i];
    4527                 :          0 :             pTP->GetExtraInfos()->bCompressed = sal_False;
    4528                 :          0 :             pTP->GetSize().Width() = pTP->GetExtraInfos()->nOrgWidth;
    4529         [ #  # ]:          0 :             if ( nCompressPercent )
    4530                 :            :             {
    4531         [ #  # ]:          0 :                 size_t nTxtPortion = pParaPortion->GetTextPortions().GetPos( pTP );
    4532         [ #  # ]:          0 :                 sal_uInt16 nTxtPortionStart = pParaPortion->GetTextPortions().GetStartPos( nTxtPortion );
    4533                 :            :                 DBG_ASSERT( nTxtPortionStart >= pLine->GetStart(), "Portion doesn't belong to the line!!!" );
    4534                 :          0 :                 sal_Int32* pDXArray = NULL;
    4535 [ #  # ][ #  # ]:          0 :                 if (!pLine->GetCharPosArray().empty())
    4536 [ #  # ][ #  # ]:          0 :                     pDXArray = &pLine->GetCharPosArray()[0]+( nTxtPortionStart-pLine->GetStart() );
    4537         [ #  # ]:          0 :                 if ( pTP->GetExtraInfos()->pOrgDXArray )
    4538                 :          0 :                     memcpy( pDXArray, pTP->GetExtraInfos()->pOrgDXArray, (pTP->GetLen()-1)*sizeof(sal_Int32) );
    4539         [ #  # ]:          0 :                 ImplCalcAsianCompression( pParaPortion->GetNode(), pTP, nTxtPortionStart, pDXArray, (sal_uInt16)nCompressPercent, sal_True );
    4540                 :            :             }
    4541                 :            :         }
    4542                 :          0 :     }
    4543                 :          0 : }
    4544                 :            : 
    4545                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10