LCOV - code coverage report
Current view: top level - sw/source/core/txtnode - fntcache.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 560 1201 46.6 %
Date: 2012-08-25 Functions: 21 25 84.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 634 1998 31.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <i18npool/mslangid.hxx>
      30                 :            : #include <vcl/outdev.hxx>
      31                 :            : #include <vcl/print.hxx>
      32                 :            : #include <vcl/lineinfo.hxx>
      33                 :            : #include <vcl/metric.hxx>
      34                 :            : #include <vcl/window.hxx>
      35                 :            : #include <vcl/svapp.hxx>
      36                 :            : #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
      37                 :            : #include <com/sun/star/i18n/WordType.hpp>
      38                 :            : #include <breakit.hxx>
      39                 :            : #include <viewsh.hxx>
      40                 :            : #include <viewopt.hxx>
      41                 :            : #include <fntcache.hxx>
      42                 :            : #include <IDocumentSettingAccess.hxx>
      43                 :            : #include <swfont.hxx>       // CH_BLANK + CH_BULLET
      44                 :            : #include <wrong.hxx>
      45                 :            : #include "dbg_lay.hxx"
      46                 :            : #include <txtfrm.hxx>       // SwTxtFrm
      47                 :            : #include <pagefrm.hxx>
      48                 :            : #include <pagedesc.hxx> // SwPageDesc
      49                 :            : #include <tgrditem.hxx>
      50                 :            : #include <scriptinfo.hxx>
      51                 :            : #include <editeng/brshitem.hxx>
      52                 :            : #include <tools/shl.hxx>
      53                 :            : #include <swmodule.hxx>
      54                 :            : #include <accessibilityoptions.hxx>
      55                 :            : #include <svtools/accessibilityoptions.hxx>
      56                 :            : #include <doc.hxx>
      57                 :            : #include <editeng/fhgtitem.hxx>
      58                 :            : #include <docsh.hxx>
      59                 :            : #include <poolfmt.hrc>
      60                 :            : 
      61                 :            : using namespace ::com::sun::star;
      62                 :            : 
      63                 :            : // global variables declared in fntcache.hxx
      64                 :            : // FontCache is created in txtinit.cxx _TextInit and deleted in _TextFinit
      65                 :            : SwFntCache *pFntCache = NULL;
      66                 :            : // last Font set by ChgFntCache
      67                 :            : SwFntObj *pLastFont = NULL;
      68                 :            : // "MagicNumber" used to identify Fonts
      69                 :            : sal_uInt8* pMagicNo = NULL;
      70                 :            : 
      71                 :            : Color *pWaveCol = 0;
      72                 :            : 
      73                 :            : long SwFntObj::nPixWidth;
      74                 :            : MapMode* SwFntObj::pPixMap = NULL;
      75                 :            : OutputDevice* SwFntObj::pPixOut = NULL;
      76                 :            : 
      77                 :            : extern sal_uInt16 UnMapDirection( sal_uInt16 nDir, const sal_Bool bVertFormat );
      78                 :          0 : sal_uInt16 GetDefaultFontHeight( SwDrawTextInfo &rInf )
      79                 :            : {
      80                 :          0 :     SwDocShell* pDocShell = rInf.GetShell()->GetDoc()->GetDocShell();
      81         [ #  # ]:          0 :     SfxStyleSheetBasePool* pBasePool = pDocShell->GetStyleSheetPool();
      82                 :            : 
      83         [ #  # ]:          0 :     String aString(SW_RES(STR_POOLCOLL_STANDARD));
      84                 :            : 
      85         [ #  # ]:          0 :     SfxStyleSheetBase* pStyle = pBasePool->Find( aString, (SfxStyleFamily)SFX_STYLE_FAMILY_PARA );
      86         [ #  # ]:          0 :     SfxItemSet& aTmpSet = pStyle->GetItemSet();
      87         [ #  # ]:          0 :     SvxFontHeightItem &aDefaultFontItem = (SvxFontHeightItem&)aTmpSet.Get(RES_CHRATR_CJK_FONTSIZE);
      88         [ #  # ]:          0 :     return (sal_uInt16)aDefaultFontItem.GetHeight();
      89                 :            : }
      90                 :            : 
      91                 :            : 
      92                 :            : 
      93                 :            : /*************************************************************************
      94                 :            : |*
      95                 :            : |*  SwFntCache::Flush()
      96                 :            : |*
      97                 :            : |*************************************************************************/
      98                 :            : 
      99                 :       1363 : void SwFntCache::Flush( )
     100                 :            : {
     101         [ +  + ]:       1363 :     if ( pLastFont )
     102                 :            :     {
     103                 :       1288 :         pLastFont->Unlock();
     104                 :       1288 :         pLastFont = NULL;
     105                 :            :     }
     106                 :       1363 :     SwCache::Flush( );
     107                 :       1363 : }
     108                 :            : 
     109                 :            : /*************************************************************************
     110                 :            : |*
     111                 :            : |*  SwFntObj::SwFntObj(), ~SwFntObj()
     112                 :            : |*
     113                 :            : |*************************************************************************/
     114                 :            : 
     115                 :       2288 : SwFntObj::SwFntObj( const SwSubFont &rFont, const void *pOwn, ViewShell *pSh ) :
     116                 :            :     SwCacheObj( (void*)pOwn ),
     117                 :            :     aFont( rFont ),
     118                 :            :     pScrFont( NULL ),
     119                 :            :     pPrtFont( &aFont ),
     120                 :            :     pPrinter( NULL ),
     121         [ +  - ]:       2288 :     nPropWidth( rFont.GetPropWidth() )
     122                 :            : {
     123         [ +  + ]:       2288 :     nZoom = pSh ? pSh->GetViewOptions()->GetZoom() : USHRT_MAX;
     124                 :       2288 :     nGuessedLeading = USHRT_MAX;
     125                 :       2288 :     nExtLeading = USHRT_MAX;
     126                 :       2288 :     nPrtAscent = USHRT_MAX;
     127                 :       2288 :     nPrtHeight = USHRT_MAX;
     128         [ +  - ]:       2288 :     bSymbol = RTL_TEXTENCODING_SYMBOL == aFont.GetCharSet();
     129         [ +  - ]:       2288 :     bPaintBlank = ( UNDERLINE_NONE != aFont.GetUnderline()
     130         [ +  - ]:       1970 :                  || UNDERLINE_NONE != aFont.GetOverline()
     131         [ +  - ]:       1970 :                  || STRIKEOUT_NONE != aFont.GetStrikeout() )
     132 [ +  + ][ +  - ]:       6228 :                  && !aFont.IsWordLineMode();
         [ +  + ][ +  - ]
                 [ +  + ]
     133         [ +  - ]:       2288 :     aFont.SetLanguage(rFont.GetLanguage());
     134                 :       2288 : }
     135                 :            : 
     136         [ +  - ]:       2288 : SwFntObj::~SwFntObj()
     137                 :            : {
     138         [ +  + ]:       2288 :     if ( pScrFont != pPrtFont )
     139 [ -  + ][ #  # ]:       1510 :         delete pScrFont;
     140         [ +  + ]:       2288 :     if ( pPrtFont != &aFont )
     141 [ +  - ][ +  - ]:        140 :         delete pPrtFont;
     142         [ -  + ]:       4576 : }
     143                 :            : 
     144                 :     281705 : void SwFntObj::CreatePrtFont( const OutputDevice& rPrt )
     145                 :            : {
     146 [ +  + ][ +  + ]:     281705 :     if ( nPropWidth != 100 && pPrinter != &rPrt )
     147                 :            :     {
     148         [ +  - ]:        464 :         if( pScrFont != pPrtFont )
     149 [ -  + ][ #  # ]:        464 :             delete pScrFont;
     150         [ +  + ]:        464 :         if( pPrtFont != &aFont )
     151 [ +  - ][ +  - ]:        324 :             delete pPrtFont;
     152                 :            : 
     153         [ +  - ]:        464 :         const Font aOldFnt( rPrt.GetFont() );
     154         [ +  - ]:        464 :         ((OutputDevice&)rPrt).SetFont( aFont );
     155         [ +  - ]:        464 :         const FontMetric aWinMet( rPrt.GetFontMetric() );
     156         [ +  - ]:        464 :         ((OutputDevice&)rPrt).SetFont( aOldFnt );
     157         [ +  - ]:        464 :         long nWidth = ( aWinMet.GetSize().Width() * nPropWidth ) / 100;
     158                 :            : 
     159         [ -  + ]:        464 :         if( !nWidth )
     160                 :          0 :             ++nWidth;
     161 [ +  - ][ +  - ]:        464 :         pPrtFont = new Font( aFont );
     162 [ +  - ][ +  - ]:        464 :         pPrtFont->SetSize( Size( nWidth, aFont.GetSize().Height() ) );
     163 [ +  - ][ +  - ]:        464 :         pScrFont = NULL;
     164                 :            :     }
     165                 :     281705 : }
     166                 :            : 
     167                 :            : /*************************************************************************
     168                 :            :  *
     169                 :            :  *  bool lcl_IsFontAdjustNecessary( rOutDev, rRefDev )
     170                 :            :  *
     171                 :            :  *  returns whether we have to adjust the output font to resemble
     172                 :            :  *  the formatting font
     173                 :            :  *
     174                 :            :  *  _Not_ necessary if
     175                 :            :  *
     176                 :            :  *  1. RefDef == OutDev (text formatting, online layout...)
     177                 :            :  *  2. PDF export from online layout
     178                 :            :  *  3. Prospect/PagePreview pringing
     179                 :            :  *
     180                 :            :  *************************************************************************/
     181                 :            : 
     182                 :     577428 : bool lcl_IsFontAdjustNecessary( const OutputDevice& rOutDev,
     183                 :            :                                 const OutputDevice& rRefDev )
     184                 :            : {
     185                 :            :     return &rRefDev != &rOutDev &&
     186                 :      62887 :            OUTDEV_WINDOW != rRefDev.GetOutDevType() &&
     187                 :      62772 :            ( OUTDEV_PRINTER != rRefDev.GetOutDevType() ||
     188   [ +  +  +  +  :     703087 :              OUTDEV_PRINTER != rOutDev.GetOutDevType() );
           +  + ][ +  - ]
     189                 :            : }
     190                 :            : 
     191                 :            : struct CalcLinePosData
     192                 :            : {
     193                 :            :     SwDrawTextInfo& rInf;
     194                 :            :     Font& rFont;
     195                 :            :     xub_StrLen nCnt;
     196                 :            :     const sal_Bool bSwitchH2V;
     197                 :            :     const sal_Bool bSwitchL2R;
     198                 :            :     long nHalfSpace;
     199                 :            :     sal_Int32* pKernArray;
     200                 :            :     const sal_Bool bBidiPor;
     201                 :            : 
     202                 :      22705 :     CalcLinePosData( SwDrawTextInfo& _rInf, Font& _rFont,
     203                 :            :                       xub_StrLen _nCnt, const sal_Bool _bSwitchH2V, const sal_Bool _bSwitchL2R,
     204                 :            :                       long _nHalfSpace, sal_Int32* _pKernArray, const sal_Bool _bBidiPor) :
     205                 :            :         rInf( _rInf ),
     206                 :            :         rFont( _rFont ),
     207                 :            :         nCnt( _nCnt ),
     208                 :            :         bSwitchH2V( _bSwitchH2V ),
     209                 :            :         bSwitchL2R( _bSwitchL2R ),
     210                 :            :         nHalfSpace( _nHalfSpace ),
     211                 :            :         pKernArray( _pKernArray ),
     212                 :      22705 :         bBidiPor( _bBidiPor )
     213                 :            :     {
     214                 :      22705 :     }
     215                 :            : };
     216                 :            : 
     217                 :            : /** Function: lcl_calcLinePos
     218                 :            : 
     219                 :            :    Computes the start and end position of an underline. This function is called
     220                 :            :    from the DrawText-method (for underlining misspelled words or smarttag terms).
     221                 :            : */
     222                 :            : 
     223                 :       3463 : void lcl_calcLinePos( const CalcLinePosData &rData,
     224                 :            :     Point &rStart, Point &rEnd, xub_StrLen nStart, xub_StrLen nWrLen )
     225                 :            : {
     226                 :       3463 :    long nBlank = 0;
     227                 :       3463 :    const xub_StrLen nEnd = nStart + nWrLen;
     228                 :       3463 :    const long nTmpSpaceAdd = rData.rInf.GetSpace() / SPACING_PRECISION_FACTOR;
     229                 :            : 
     230         [ +  + ]:       5746 :    if ( nEnd < rData.nCnt
           [ +  +  +  + ]
     231                 :       2283 :        && CH_BLANK == rData.rInf.GetText().GetChar( rData.rInf.GetIdx() + nEnd ) )
     232                 :            :    {
     233         [ +  + ]:       1464 :        if( nEnd + 1 == rData.nCnt )
     234                 :         78 :            nBlank -= nTmpSpaceAdd;
     235                 :            :        else
     236                 :       1386 :            nBlank -= rData.nHalfSpace;
     237                 :            :    }
     238                 :            : 
     239                 :            :    // determine start, end and length of wave line
     240         [ +  + ]:       3463 :    sal_Int32 nKernStart = nStart ? rData.pKernArray[ sal_uInt16( nStart - 1 ) ] : 0;
     241                 :       3463 :    sal_Int32 nKernEnd = rData.pKernArray[ sal_uInt16( nEnd - 1 ) ];
     242                 :            : 
     243                 :            :    sal_uInt16 nDir = rData.bBidiPor ? 1800 :
     244         [ +  - ]:       3463 :        UnMapDirection( rData.rFont.GetOrientation(), rData.bSwitchH2V );
     245                 :            : 
     246   [ +  -  -  -  :       3463 :    switch ( nDir )
                      - ]
     247                 :            :    {
     248                 :            :    case 0 :
     249                 :       3463 :        rStart.X() += nKernStart;
     250                 :       3463 :        rEnd.X() = nBlank + rData.rInf.GetPos().X() + nKernEnd;
     251                 :       3463 :        rEnd.Y() = rData.rInf.GetPos().Y();
     252                 :       3463 :        break;
     253                 :            :    case 900 :
     254                 :          0 :        rStart.Y() -= nKernStart;
     255                 :          0 :        rEnd.X() = rData.rInf.GetPos().X();
     256                 :          0 :        rEnd.Y() = nBlank + rData.rInf.GetPos().Y() - nKernEnd;
     257                 :          0 :        break;
     258                 :            :    case 1800 :
     259                 :          0 :        rStart.X() -= nKernStart;
     260                 :          0 :        rEnd.X() = rData.rInf.GetPos().X() - nKernEnd - nBlank;
     261                 :          0 :        rEnd.Y() = rData.rInf.GetPos().Y();
     262                 :          0 :        break;
     263                 :            :    case 2700 :
     264                 :          0 :        rStart.Y() += nKernStart;
     265                 :          0 :        rEnd.X() = rData.rInf.GetPos().X();
     266                 :          0 :        rEnd.Y() = nBlank + rData.rInf.GetPos().Y() + nKernEnd;
     267                 :          0 :        break;
     268                 :            :    }
     269                 :            : 
     270         [ -  + ]:       3463 :    if ( rData.bSwitchL2R )
     271                 :            :    {
     272                 :          0 :        rData.rInf.GetFrm()->SwitchLTRtoRTL( rStart );
     273                 :          0 :        rData.rInf.GetFrm()->SwitchLTRtoRTL( rEnd );
     274                 :            :    }
     275                 :            : 
     276         [ -  + ]:       3463 :    if ( rData.bSwitchH2V )
     277                 :            :    {
     278                 :          0 :        rData.rInf.GetFrm()->SwitchHorizontalToVertical( rStart );
     279                 :          0 :        rData.rInf.GetFrm()->SwitchHorizontalToVertical( rEnd );
     280                 :            :    }
     281                 :       3463 : }
     282                 :            : 
     283                 :            : /*************************************************************************
     284                 :            :  *
     285                 :            :  *  sal_uInt16 SwFntObj::GetFontAscent( const OutputDevice& rOut )
     286                 :            :  *
     287                 :            :  * Returns the Ascent of the Font on the given output device;
     288                 :            :  * it may be necessary to create the screen font first.
     289                 :            :  *************************************************************************/
     290                 :            : 
     291                 :     118601 : sal_uInt16 SwFntObj::GetFontAscent( const ViewShell *pSh, const OutputDevice& rOut )
     292                 :            : {
     293                 :     118601 :     sal_uInt16 nRet = 0;
     294         [ +  - ]:     118601 :     const OutputDevice& rRefDev = pSh ? pSh->GetRefDev() : rOut;
     295                 :            : 
     296 [ +  - ][ +  + ]:     118601 :     if ( pSh && lcl_IsFontAdjustNecessary( rOut, rRefDev ) )
                 [ +  + ]
     297                 :            :     {
     298                 :       1343 :         CreateScrFont( *pSh, rOut );
     299                 :            :         OSL_ENSURE( USHRT_MAX != nScrAscent, "nScrAscent is going berzerk" );
     300                 :       1343 :         nRet = nScrAscent;
     301                 :            :     }
     302                 :            :     else
     303                 :            :     {
     304         [ +  + ]:     117258 :         if (nPrtAscent == USHRT_MAX) // printer ascent unknown?
     305                 :            :         {
     306         [ +  - ]:       2167 :             CreatePrtFont( rOut );
     307         [ +  - ]:       2167 :             const Font aOldFnt( rRefDev.GetFont() );
     308         [ +  - ]:       2167 :             ((OutputDevice&)rRefDev).SetFont( *pPrtFont );
     309         [ +  - ]:       2167 :             const FontMetric aOutMet( rRefDev.GetFontMetric() );
     310         [ +  - ]:       2167 :             nPrtAscent = (sal_uInt16) aOutMet.GetAscent();
     311 [ +  - ][ +  - ]:       2167 :             ( (OutputDevice&)rRefDev).SetFont( aOldFnt );
                 [ +  - ]
     312                 :            :         }
     313                 :            : 
     314                 :     117258 :         nRet = nPrtAscent;
     315                 :            :     }
     316                 :            : 
     317                 :            : #if !defined(MACOSX) // #i89844# extleading is below the line for Mac
     318                 :            :     // TODO: move extleading below the line for all platforms too
     319                 :     118601 :     nRet += GetFontLeading( pSh, rRefDev );
     320                 :            : #endif
     321                 :            : 
     322                 :            :     OSL_ENSURE( USHRT_MAX != nRet, "GetFontAscent returned USHRT_MAX" );
     323                 :     118601 :     return nRet;
     324                 :            : }
     325                 :            : 
     326                 :            : /*************************************************************************
     327                 :            :  *
     328                 :            :  *  sal_uInt16 SwFntObj::GetFontHeight( const OutputDevice* pOut )
     329                 :            :  *
     330                 :            :  * Returns the height of the Font on the given output device;
     331                 :            :  * it may be necessary to create the screen font first.
     332                 :            :  *************************************************************************/
     333                 :            : 
     334                 :     124616 : sal_uInt16 SwFntObj::GetFontHeight( const ViewShell* pSh, const OutputDevice& rOut )
     335                 :            : {
     336                 :     124616 :     sal_uInt16 nRet = 0;
     337         [ +  - ]:     124616 :     const OutputDevice& rRefDev = pSh ? pSh->GetRefDev() : rOut;
     338                 :            : 
     339 [ +  - ][ +  + ]:     124616 :     if ( pSh && lcl_IsFontAdjustNecessary( rOut, rRefDev ) )
                 [ +  + ]
     340                 :            :     {
     341                 :       1178 :         CreateScrFont( *pSh, rOut );
     342                 :            :         OSL_ENSURE( USHRT_MAX != nScrHeight, "nScrHeight is going berzerk" );
     343                 :       1178 :         nRet = nScrHeight + GetFontLeading( pSh, rRefDev );
     344                 :            :     }
     345                 :            :     else
     346                 :            :     {
     347         [ +  + ]:     123438 :         if (nPrtHeight == USHRT_MAX) // printer height unknown?
     348                 :            :         {
     349         [ +  - ]:       2690 :             CreatePrtFont( rOut );
     350         [ +  - ]:       2690 :             const Font aOldFnt( rRefDev.GetFont() );
     351         [ +  - ]:       2690 :             ((OutputDevice&)rRefDev).SetFont( *pPrtFont );
     352         [ +  - ]:       2690 :             nPrtHeight = static_cast<sal_uInt16>(rRefDev.GetTextHeight());
     353                 :            : 
     354                 :            : #if OSL_DEBUG_LEVEL > 0
     355                 :            :             // Check if vcl did not change the meading of GetTextHeight
     356                 :            :             const FontMetric aOutMet( rRefDev.GetFontMetric() );
     357                 :            :             long nTmpPrtHeight = (sal_uInt16)aOutMet.GetAscent() + aOutMet.GetDescent();
     358                 :            :             (void) nTmpPrtHeight;
     359                 :            :             // #i106098#: do not compare with == here due to rounding error
     360                 :            :             OSL_ENSURE( abs(nTmpPrtHeight - nPrtHeight) < 3,
     361                 :            :                     "GetTextHeight != Ascent + Descent" );
     362                 :            : #endif
     363                 :            : 
     364 [ +  - ][ +  - ]:       2690 :             ((OutputDevice&)rRefDev).SetFont( aOldFnt );
     365                 :            :         }
     366                 :            : 
     367                 :     123438 :         nRet = nPrtHeight + GetFontLeading( pSh, rRefDev );
     368                 :            :     }
     369                 :            : 
     370                 :            :     OSL_ENSURE( USHRT_MAX != nRet, "GetFontHeight returned USHRT_MAX" );
     371                 :     124616 :     return nRet;
     372                 :            : }
     373                 :            : 
     374                 :     605640 : sal_uInt16 SwFntObj::GetFontLeading( const ViewShell *pSh, const OutputDevice& rOut )
     375                 :            : {
     376                 :     605640 :     sal_uInt16 nRet = 0;
     377                 :            : 
     378         [ +  + ]:     605640 :     if ( pSh )
     379                 :            :     {
     380 [ +  + ][ -  + ]:     605562 :         if ( USHRT_MAX == nGuessedLeading || USHRT_MAX == nExtLeading )
     381                 :            :         {
     382         [ +  - ]:       2693 :             SolarMutexGuard aGuard;
     383                 :            : 
     384         [ +  - ]:       2693 :             const Font aOldFnt( rOut.GetFont() );
     385         [ +  - ]:       2693 :             ((OutputDevice&)rOut).SetFont( *pPrtFont );
     386         [ +  - ]:       2693 :             const FontMetric aMet( rOut.GetFontMetric() );
     387         [ +  - ]:       2693 :             ((OutputDevice&)rOut).SetFont( aOldFnt );
     388         [ +  - ]:       2693 :             bSymbol = RTL_TEXTENCODING_SYMBOL == aMet.GetCharSet();
     389         [ +  - ]:       2693 :             GuessLeading( *pSh, aMet );
     390 [ +  - ][ +  - ]:       2693 :             nExtLeading = static_cast<sal_uInt16>(aMet.GetExtLeading());
         [ +  - ][ +  - ]
     391                 :            :         }
     392                 :            : 
     393                 :     605562 :         const IDocumentSettingAccess& rIDSA = *pSh->getIDocumentSettingAccess();
     394                 :     605562 :         const bool bBrowse = ( pSh->GetWin() &&
     395                 :     604958 :                                pSh->GetViewOptions()->getBrowseMode() &&
     396         [ +  - ]:    1210520 :                               !pSh->GetViewOptions()->IsPrtFormat() );
           [ +  +  +  + ]
     397                 :            : 
     398 [ +  + ][ +  + ]:     605562 :         if ( !bBrowse && rIDSA.get(IDocumentSettingAccess::ADD_EXT_LEADING) )
                 [ +  + ]
     399                 :     605216 :             nRet = nExtLeading;
     400                 :            :         else
     401                 :        346 :             nRet = nGuessedLeading;
     402                 :            :     }
     403                 :            : 
     404                 :            :     OSL_ENSURE( USHRT_MAX != nRet, "GetFontLeading returned USHRT_MAX" );
     405                 :     605640 :     return nRet;
     406                 :            : }
     407                 :            : 
     408                 :            : 
     409                 :            : /*************************************************************************
     410                 :            :  *
     411                 :            :  *  SwFntObj::CreateScrFont( const ViewShell& rSh, const OutputDevice& rOut )
     412                 :            :  *
     413                 :            :  *  pOut is the output device, not the reference device
     414                 :            :  *
     415                 :            :  *************************************************************************/
     416                 :            : 
     417                 :      64036 : void SwFntObj::CreateScrFont( const ViewShell& rSh, const OutputDevice& rOut )
     418                 :            : {
     419         [ +  + ]:      64036 :     if ( pScrFont )
     420                 :      64036 :         return;
     421                 :            : 
     422                 :            :     // any changes to the output device are reset at the end of the function
     423                 :        778 :     OutputDevice* pOut = (OutputDevice*)&rOut;
     424                 :            : 
     425                 :            :     // Save old font
     426         [ +  - ]:        778 :     Font aOldOutFont( pOut->GetFont() );
     427                 :            : 
     428                 :        778 :     nScrHeight = USHRT_MAX;
     429                 :            : 
     430                 :            :     // Condition for output font / refdev font adjustment
     431         [ +  - ]:        778 :     OutputDevice* pPrt = &rSh.GetRefDev();
     432                 :            : 
     433   [ +  +  -  +  :       1541 :     if( !rSh.GetWin() ||
           #  # ][ +  - ]
     434                 :        763 :         !rSh.GetViewOptions()->getBrowseMode() ||
     435                 :          0 :          rSh.GetViewOptions()->IsPrtFormat() )
     436                 :            :     {
     437                 :            :         // After CreatePrtFont pPrtFont is the font which is actually used
     438                 :            :         // by the reference device
     439         [ +  - ]:        778 :         CreatePrtFont( *pPrt );
     440                 :        778 :         pPrinter = pPrt;
     441                 :            : 
     442                 :            :         // save old reference device font
     443         [ +  - ]:        778 :         Font aOldPrtFnt( pPrt->GetFont() );
     444                 :            : 
     445                 :            :         // set the font used at the reference device at the reference device
     446                 :            :         // and the output device
     447         [ +  - ]:        778 :         pPrt->SetFont( *pPrtFont );
     448         [ +  - ]:        778 :         pOut->SetFont( *pPrtFont );
     449                 :            : 
     450                 :            :         // This should be the default for pScrFont.
     451                 :        778 :         pScrFont = pPrtFont;
     452                 :            : 
     453         [ +  - ]:        778 :         FontMetric aMet = pPrt->GetFontMetric( );
     454                 :            :         //Don't loose "faked" properties of the logical font that don't truly
     455                 :            :         //exist in the physical font metrics which vcl which fake up for us
     456 [ +  - ][ +  - ]:        778 :         aMet.SetWeight(pScrFont->GetWeight());
     457 [ +  - ][ +  - ]:        778 :         aMet.SetItalic(pScrFont->GetItalic());
     458                 :            : 
     459         [ +  - ]:        778 :         bSymbol = RTL_TEXTENCODING_SYMBOL == aMet.GetCharSet();
     460                 :            : 
     461         [ +  + ]:        778 :         if ( USHRT_MAX == nGuessedLeading )
     462         [ +  - ]:         92 :             GuessLeading( rSh, aMet );
     463                 :            : 
     464         [ +  + ]:        778 :         if ( USHRT_MAX == nExtLeading )
     465         [ +  - ]:         92 :             nExtLeading = static_cast<sal_uInt16>(aMet.GetExtLeading());
     466                 :            : 
     467                 :            :         // reset the original reference device font
     468 [ +  - ][ +  - ]:        778 :         pPrt->SetFont( aOldPrtFnt );
                 [ +  - ]
     469                 :            :     }
     470                 :            :     else
     471                 :            :     {
     472         [ #  # ]:          0 :         bSymbol = RTL_TEXTENCODING_SYMBOL == aFont.GetCharSet();
     473         [ #  # ]:          0 :         if ( nGuessedLeading == USHRT_MAX )
     474                 :          0 :             nGuessedLeading = 0;
     475                 :            : 
     476                 :            :         // no external leading in browse mode
     477         [ #  # ]:          0 :         if ( nExtLeading == USHRT_MAX )
     478                 :          0 :             nExtLeading = 0;
     479                 :            : 
     480                 :          0 :         pScrFont = pPrtFont;
     481                 :            :     }
     482                 :            : 
     483                 :            :     // check zoom factor, e.g. because of PrtOle2 during export
     484                 :            :     {
     485                 :            :         // In case the zoom factor of the output device differs from the
     486                 :            :         // one in the ViewOptions, this Font must not be cached,
     487                 :            :         // hence set zoom factor to an invalid value
     488                 :            :         long nTmp;
     489 [ +  - ][ +  - ]:       2334 :         if( pOut->GetMapMode().GetScaleX().IsValid() &&
         [ +  - ][ +  - ]
                 [ +  - ]
     490         [ +  - ]:        778 :             pOut->GetMapMode().GetScaleY().IsValid() &&
     491         [ +  - ]:        778 :             pOut->GetMapMode().GetScaleX() == pOut->GetMapMode().GetScaleY() )
     492                 :            :         {
     493                 :        778 :             nTmp = ( 100 * pOut->GetMapMode().GetScaleX().GetNumerator() ) /
     494                 :        778 :                      pOut->GetMapMode().GetScaleX().GetDenominator();
     495                 :            :         }
     496                 :            :         else
     497                 :          0 :             nTmp = 0;
     498         [ -  + ]:        778 :         if( nTmp != nZoom )
     499                 :          0 :             nZoom = USHRT_MAX - 1;
     500                 :            :     }
     501                 :            : 
     502 [ +  - ][ +  - ]:        778 :     nScrAscent = (sal_uInt16)pOut->GetFontMetric().GetAscent();
                 [ +  - ]
     503         [ +  - ]:        778 :     if ( USHRT_MAX == nScrHeight )
     504         [ +  - ]:        778 :         nScrHeight = (sal_uInt16)pOut->GetTextHeight();
     505                 :            : 
     506                 :            :     // reset original output device font
     507 [ +  - ][ +  - ]:      64036 :     pOut->SetFont( aOldOutFont );
     508                 :            : }
     509                 :            : 
     510                 :            : 
     511                 :       2785 : void SwFntObj::GuessLeading( const ViewShell&
     512                 :            : #if defined(WNT)
     513                 :            :                              rSh
     514                 :            : #endif
     515                 :            :                              , const FontMetric& rMet )
     516                 :            : {
     517                 :            :     // If leading >= 5, this seems to be enough leading.
     518                 :            :     // Nothing has to be done.
     519         [ +  + ]:       2785 :     if ( rMet.GetIntLeading() >= 5 )
     520                 :            :     {
     521                 :       2740 :         nGuessedLeading = 0;
     522                 :       2785 :         return;
     523                 :            :     }
     524                 :            : 
     525                 :            : #if defined(WNT)
     526                 :            :     OutputDevice *pWin = rSh.GetWin() ?
     527                 :            :                          rSh.GetWin() :
     528                 :            :                          GetpApp()->GetDefaultDevice();
     529                 :            :     if ( pWin )
     530                 :            :     {
     531                 :            :         MapMode aTmpMap( MAP_TWIP );
     532                 :            :         MapMode aOldMap = pWin->GetMapMode( );
     533                 :            :         pWin->SetMapMode( aTmpMap );
     534                 :            :         const Font aOldFnt( pWin->GetFont() );
     535                 :            :         pWin->SetFont( *pPrtFont );
     536                 :            :         const FontMetric aWinMet( pWin->GetFontMetric() );
     537                 :            :         const sal_uInt16 nWinHeight = sal_uInt16( aWinMet.GetSize().Height() );
     538                 :            :         if( pPrtFont->GetName().Search( aWinMet.GetName() ) < USHRT_MAX )
     539                 :            :         {
     540                 :            :             // If the Leading on the Window is also 0, then it has to stay
     541                 :            :             // that way (see also StarMath).
     542                 :            :             long nTmpLeading = (long)aWinMet.GetIntLeading();
     543                 :            :             if( nTmpLeading <= 0 )
     544                 :            :             {
     545                 :            :                 pWin->SetFont( rMet );
     546                 :            :                 nTmpLeading = (long)pWin->GetFontMetric().GetIntLeading();
     547                 :            :                 if( nTmpLeading < 0 )
     548                 :            :                     nGuessedLeading = 0;
     549                 :            :                 else
     550                 :            :                     nGuessedLeading = sal_uInt16(nTmpLeading);
     551                 :            :             }
     552                 :            :             else
     553                 :            :             {
     554                 :            :                 nGuessedLeading = sal_uInt16(nTmpLeading);
     555                 :            :                 // Manta-Hack #50153#:
     556                 :            :                 // Wer beim Leading luegt, luegt moeglicherweise auch beim
     557                 :            :                 // Ascent/Descent, deshalb wird hier ggf. der Font ein wenig
     558                 :            :                 // tiefergelegt, ohne dabei seine Hoehe zu aendern.
     559                 :            :                 // (above original comment preserved for cultural reasons)
     560                 :            :                 // Those who lie about their Leading, may lie about their
     561                 :            :                 // Ascent/Descent as well, hence the Font will be lowered a
     562                 :            :                 // litte without changing its height.
     563                 :            :                 long nDiff = Min( rMet.GetDescent() - aWinMet.GetDescent(),
     564                 :            :                     aWinMet.GetAscent() - rMet.GetAscent() - nTmpLeading );
     565                 :            :                 if( nDiff > 0 )
     566                 :            :                 {
     567                 :            :                     OSL_ENSURE( nPrtAscent < USHRT_MAX, "GuessLeading: PrtAscent-Fault" );
     568                 :            :                     if ( nPrtAscent < USHRT_MAX )
     569                 :            :                         nPrtAscent = nPrtAscent + (sal_uInt16)(( 2 * nDiff ) / 5);
     570                 :            :                 }
     571                 :            :             }
     572                 :            :         }
     573                 :            :         else
     574                 :            :         {
     575                 :            :             // If all else fails, take 15% of the height, as emprically
     576                 :            :             // determined by CL
     577                 :            :             nGuessedLeading = (nWinHeight * 15) / 100;
     578                 :            :         }
     579                 :            :         pWin->SetFont( aOldFnt );
     580                 :            :         pWin->SetMapMode( aOldMap );
     581                 :            :     }
     582                 :            :     else
     583                 :            : #endif
     584                 :         45 :         nGuessedLeading = 0;
     585                 :            : }
     586                 :            : 
     587                 :            : /*************************************************************************
     588                 :            :  *
     589                 :            :  *  void SwFntObj::SetDeviceFont( const OutputDevice *pOut ),
     590                 :            :  *
     591                 :            :  * Set the font at the given output device; for screens it may be
     592                 :            :  * necessary to do some adjustment first.
     593                 :            :  *
     594                 :            :  *************************************************************************/
     595                 :            : 
     596                 :     307835 : void SwFntObj::SetDevFont( const ViewShell *pSh, OutputDevice& rOut )
     597                 :            : {
     598         [ +  + ]:     307835 :     const OutputDevice& rRefDev = pSh ? pSh->GetRefDev() : rOut;
     599                 :            : 
     600 [ +  + ][ +  + ]:     307835 :     if ( pSh && lcl_IsFontAdjustNecessary( rOut, rRefDev ) )
                 [ +  + ]
     601                 :            :     {
     602                 :      33829 :         CreateScrFont( *pSh, rOut );
     603         [ +  + ]:      33829 :         if( !GetScrFont()->IsSameInstance( rOut.GetFont() ) )
     604                 :      26930 :             rOut.SetFont( *pScrFont );
     605 [ +  - ][ +  + ]:      33829 :         if( pPrinter && ( !pPrtFont->IsSameInstance( pPrinter->GetFont() ) ) )
                 [ +  + ]
     606                 :       2568 :             pPrinter->SetFont( *pPrtFont );
     607                 :            :     }
     608                 :            :     else
     609                 :            :     {
     610                 :     274006 :         CreatePrtFont( rOut );
     611         [ +  + ]:     274006 :         if( !pPrtFont->IsSameInstance( rOut.GetFont() ) )
     612                 :       5066 :             rOut.SetFont( *pPrtFont );
     613                 :            :     }
     614                 :            : 
     615                 :            :     // Here, we actually do not need the leading values, but by calling
     616                 :            :     // GetFontLeading() we assure that the values are calculated for later use.
     617                 :     307835 :     GetFontLeading( pSh, rRefDev );
     618                 :     307835 : }
     619                 :            : 
     620                 :            : #define WRONG_SHOW_MIN 5
     621                 :            : #define WRONG_SHOW_SMALL 11
     622                 :            : #define WRONG_SHOW_MEDIUM 15
     623                 :            : 
     624                 :            : /*************************************************************************
     625                 :            :  *
     626                 :            :  * void SwFntObj::DrawText( ... )
     627                 :            :  *
     628                 :            :  * Output text:
     629                 :            :  *      on screen              => DrawTextArray
     630                 :            :  *      on printer, !Kerning   => DrawText
     631                 :            :  *      on printer + Kerning   => DrawStretchText
     632                 :            :  *
     633                 :            :  *************************************************************************/
     634                 :            : 
     635                 :          0 : sal_uInt8 lcl_WhichPunctuation( xub_Unicode cChar )
     636                 :            : {
     637 [ #  # ][ #  # ]:          0 :     if ( ( cChar < 0x3001 || cChar > 0x3002 ) &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     638                 :            :             ( cChar < 0x3008 || cChar > 0x3011 ) &&
     639                 :            :             ( cChar < 0x3014 || cChar > 0x301F ) &&
     640                 :            :               0xFF62 != cChar && 0xFF63 != cChar )
     641                 :            :         // no punctuation
     642                 :          0 :         return SwScriptInfo::NONE;
     643 [ #  # ][ #  # ]:          0 :     else if ( 0x3001 == cChar || 0x3002 == cChar ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     644                 :            :               0x3009 == cChar || 0x300B == cChar ||
     645                 :            :               0x300D == cChar || 0x300F == cChar ||
     646                 :            :               0x3011 == cChar || 0x3015 == cChar ||
     647                 :            :               0x3017 == cChar || 0x3019 == cChar ||
     648                 :            :               0x301B == cChar || 0x301E == cChar ||
     649                 :            :               0x301F == cChar || 0xFF63 == cChar )
     650                 :            :         // right punctuation
     651                 :          0 :         return SwScriptInfo::SPECIAL_RIGHT;
     652                 :            : 
     653                 :          0 :     return SwScriptInfo::SPECIAL_LEFT;
     654                 :            : }
     655                 :            : 
     656                 :          0 : static sal_Bool lcl_IsMonoSpaceFont( const OutputDevice& rOut )
     657                 :            : {
     658                 :          0 :     const rtl::OUString aStr1( xub_Unicode( 0x3008 ) );
     659                 :          0 :     const rtl::OUString aStr2( xub_Unicode( 0x307C ) );
     660 [ #  # ][ #  # ]:          0 :     const long nWidth1 = rOut.GetTextWidth( aStr1 );
                 [ #  # ]
     661 [ #  # ][ #  # ]:          0 :     const long nWidth2 = rOut.GetTextWidth( aStr2 );
                 [ #  # ]
     662                 :          0 :     return nWidth1 == nWidth2;
     663                 :            : }
     664                 :            : 
     665                 :            : // ER 09.07.95 20:34
     666                 :            : // mit -Ox Optimierung stuerzt's unter win95 ab
     667                 :            : // JP 12.07.95: unter WNT auch (i386);       Alpha ??
     668                 :            : // global optimization off
     669                 :            : #ifdef _MSC_VER
     670                 :            : #pragma optimize("g",off)
     671                 :            : #endif
     672                 :            : 
     673                 :            : /* This helper structure (SwForbidden) contains the already marked parts of the string
     674                 :            :     to avoid double lines (e.g grammar + spell check error) */
     675                 :            : 
     676                 :            : typedef std::vector< std::pair< xub_StrLen, xub_StrLen > > SwForbidden;
     677                 :            : 
     678                 :      68115 : static void lcl_DrawLineForWrongListData(
     679                 :            :     SwForbidden &rForbidden,
     680                 :            :     const SwDrawTextInfo    &rInf,
     681                 :            :     const SwWrongList       *pWList,
     682                 :            :     const CalcLinePosData   &rCalcLinePosData,
     683                 :            :     const Size              &rPrtFontSize )
     684                 :            : {
     685         [ +  + ]:      68115 :     if (!pWList)
     686                 :      68115 :         return;
     687                 :            : 
     688                 :      33757 :     xub_StrLen nStart = rInf.GetIdx();
     689                 :      33757 :     xub_StrLen nWrLen = rInf.GetLen();
     690                 :            : 
     691                 :            :     // check if respective data is available in the current text range
     692 [ +  + ][ +  - ]:      33757 :     if (pWList->Check( nStart, nWrLen ))
     693                 :            :     {
     694                 :            :         // get line color to use...
     695                 :       2149 :         Color aLineColor;
     696         [ +  + ]:       2149 :         if (pWList == rInf.GetWrong())  // ... for spell checking
     697         [ +  - ]:       1754 :             aLineColor = SwViewOption::GetSpellColor();
     698         [ +  - ]:        395 :         else if (pWList == rInf.GetGrammarCheck())  // ... for grammar checking
     699                 :            :             // currently there is no specific color for grammar check errors available in the configuration
     700                 :        395 :             aLineColor = Color( COL_LIGHTBLUE );
     701         [ #  # ]:          0 :         else if (pWList == rInf.GetSmartTags())  // ... for smart tags
     702         [ #  # ]:          0 :             aLineColor = SwViewOption::GetSmarttagColor();
     703                 :            : 
     704         [ +  - ]:       2149 :         long nHght = rInf.GetOut().LogicToPixel( rPrtFontSize ).Height();
     705                 :            : 
     706                 :            :         // Draw wavy lines for spell and grammar errors only if font is large enough.
     707                 :            :         // Lines for smart tags will always be drawn.
     708 [ +  - ][ +  - ]:       2149 :         if (pWList == rInf.GetSmartTags() || WRONG_SHOW_MIN < nHght)
                 [ +  - ]
     709                 :            :         {
     710                 :       2149 :             SwForbidden::iterator pIter = rForbidden.begin();
     711         [ -  + ]:       2149 :             if (rInf.GetOut().GetConnectMetaFile())
     712         [ #  # ]:          0 :                 rInf.GetOut().Push();
     713                 :            : 
     714                 :       2149 :             const Color aCol( rInf.GetOut().GetLineColor() );
     715                 :       2149 :             const sal_Bool bColSave = aCol != aLineColor;
     716         [ +  - ]:       2149 :             if (bColSave)
     717         [ +  - ]:       2149 :                 rInf.GetOut().SetLineColor( aLineColor );
     718                 :            : 
     719                 :            :             // iterate over all ranges stored in the respective SwWrongList
     720 [ +  + ][ +  + ]:       5746 :             do
                 [ +  + ]
     721                 :            :             {
     722                 :       3463 :                 nStart = nStart - rInf.GetIdx();
     723                 :            : 
     724                 :       3463 :                 const xub_StrLen nEnd = nStart + nWrLen;
     725                 :       3463 :                 xub_StrLen nNext = nStart;
     726         [ +  + ]:       7067 :                 while( nNext < nEnd )
     727                 :            :                 {
     728 [ +  - ][ +  + ]:       8560 :                     while( pIter != rForbidden.end() && pIter->second <= nNext )
         [ +  - ][ +  + ]
                 [ +  - ]
           [ +  +  #  # ]
     729         [ +  - ]:       4956 :                         ++pIter;
     730                 :       3604 :                     xub_StrLen nNextStart = nNext;
     731                 :       3604 :                     xub_StrLen nNextEnd = nEnd;
     732 [ +  - ][ +  + ]:       3604 :                     if( pIter == rForbidden.end() || nNextEnd <= pIter->first )
         [ +  - ][ -  + ]
                 [ +  - ]
           [ +  +  #  # ]
     733                 :            :                     {
     734                 :            :                         // No overlapping mark up found
     735                 :       3301 :                         std::pair< xub_StrLen, xub_StrLen > aNew;
     736                 :       3301 :                         aNew.first = nNextStart;
     737                 :       3301 :                         aNew.second = nNextEnd;
     738         [ +  - ]:       3301 :                         rForbidden.insert( pIter, aNew );
     739                 :       3301 :                         pIter = rForbidden.begin();
     740                 :       3301 :                         nNext = nEnd;
     741                 :            :                     }
     742                 :            :                     else
     743                 :            :                     {
     744         [ +  - ]:        303 :                         nNext = pIter->second;
     745 [ +  - ][ +  + ]:        303 :                         if( nNextStart < pIter->first )
     746                 :            :                         {
     747         [ +  - ]:        162 :                             nNextEnd = pIter->first;
     748         [ +  - ]:        162 :                             pIter->first = nNextStart;
     749                 :            :                         }
     750                 :            :                         else
     751                 :        141 :                             continue;
     752                 :            :                     }
     753                 :            :                     // determine line pos
     754                 :       3463 :                     Point aStart( rInf.GetPos() );
     755                 :       3463 :                     Point aEnd;
     756         [ +  - ]:       3463 :                     lcl_calcLinePos( rCalcLinePosData, aStart, aEnd, nNextStart, nNextEnd - nNextStart );
     757                 :            : 
     758                 :            :                     // draw line for smart tags?
     759         [ -  + ]:       3463 :                     if (pWList == rInf.GetSmartTags())
     760                 :            :                     {
     761                 :          0 :                         aStart.Y() +=30;
     762                 :          0 :                         aEnd.Y() +=30;
     763                 :            : 
     764         [ #  # ]:          0 :                         LineInfo aLineInfo( LINE_DASH );
     765         [ #  # ]:          0 :                         aLineInfo.SetDistance( 40 );
     766         [ #  # ]:          0 :                         aLineInfo.SetDashLen( 1 );
     767         [ #  # ]:          0 :                         aLineInfo.SetDashCount(1);
     768                 :            : 
     769 [ #  # ][ #  # ]:          0 :                         rInf.GetOut().DrawLine( aStart, aEnd, aLineInfo );
     770                 :            :                     }
     771                 :            :                     else    // draw wavy lines for spell or grammar errors
     772                 :            :                     {
     773                 :            :                         // get wavy line type to use
     774                 :            :                         sal_uInt16 nWave =
     775                 :            :                             WRONG_SHOW_MEDIUM < nHght ? WAVE_NORMAL :
     776 [ +  + ][ +  + ]:       3463 :                             ( WRONG_SHOW_SMALL < nHght ? WAVE_SMALL : WAVE_FLAT );
     777                 :            : 
     778         [ +  - ]:       3463 :                         rInf.GetOut().DrawWaveLine( aStart, aEnd, nWave );
     779                 :            :                     }
     780                 :            :                 }
     781                 :            : 
     782                 :       3463 :                 nStart = nEnd + rInf.GetIdx();
     783                 :       3463 :                 nWrLen = rInf.GetIdx() + rInf.GetLen() - nStart;
     784                 :            :             }
     785         [ +  - ]:       2283 :             while (nWrLen && pWList->Check( nStart, nWrLen ));
     786                 :            : 
     787         [ +  - ]:       2149 :             if (bColSave)
     788         [ +  - ]:       2149 :                 rInf.GetOut().SetLineColor( aCol );
     789                 :            : 
     790         [ -  + ]:       2149 :             if (rInf.GetOut().GetConnectMetaFile())
     791         [ #  # ]:      68115 :                 rInf.GetOut().Pop();
     792                 :            :         }
     793                 :            :     }
     794                 :            : }
     795                 :            : 
     796                 :            : 
     797                 :      26445 : void SwFntObj::DrawText( SwDrawTextInfo &rInf )
     798                 :            : {
     799                 :            :     OSL_ENSURE( rInf.GetShell(), "SwFntObj::DrawText without shell" );
     800                 :            : 
     801         [ +  - ]:      26445 :     OutputDevice& rRefDev = rInf.GetShell()->GetRefDev();
     802                 :      26445 :     OutputDevice* pWin = rInf.GetShell()->GetWin();
     803                 :            : 
     804                 :            :     // true if pOut is the printer and the printer has been used for formatting
     805                 :      26445 :     const sal_Bool bPrt = OUTDEV_PRINTER == rInf.GetOut().GetOutDevType() &&
     806 [ #  # ][ -  + ]:      26445 :                       OUTDEV_PRINTER == rRefDev.GetOutDevType();
     807                 :            :     const sal_Bool bBrowse = ( pWin &&
     808                 :      26200 :                            rInf.GetShell()->GetViewOptions()->getBrowseMode() &&
     809                 :         23 :                           !rInf.GetShell()->GetViewOptions()->IsPrtFormat() &&
     810                 :         23 :                           !rInf.GetBullet() &&
     811                 :         46 :                            ( rInf.GetSpace() || !rInf.GetKern() ) &&
     812                 :         23 :                           !rInf.GetWrong() &&
     813                 :         23 :                           !rInf.GetGrammarCheck() &&
     814                 :         23 :                           !rInf.GetSmartTags() &&
     815   [ +  +  +  +  :      52806 :                           !rInf.GetGreyWave() );
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
                 [ +  - ]
     816                 :            : 
     817                 :            :     // bDirectPrint indicates that we can enter the branch which calls
     818                 :            :     // the DrawText functions instead of calling the DrawTextArray functions
     819 [ +  - ][ +  + ]:      26445 :     const sal_Bool bDirectPrint = bPrt || bBrowse;
     820                 :            : 
     821                 :            :     // Condition for output font / refdev font adjustment
     822                 :            :     const sal_Bool bUseScrFont =
     823                 :      26445 :         lcl_IsFontAdjustNecessary( rInf.GetOut(), rRefDev );
     824                 :            : 
     825         [ +  + ]:      26445 :     Font* pTmpFont = bUseScrFont ? pScrFont : pPrtFont;
     826                 :            : 
     827                 :            :     //
     828                 :            :     //  bDirectPrint and bUseScrFont should have these values:
     829                 :            :     //
     830                 :            :     //  Outdev / RefDef  | Printer | VirtPrinter | Window
     831                 :            :     // ----------------------------------------------------
     832                 :            :     //  Printer          | 1 - 0   | 0 - 1       | -
     833                 :            :     // ----------------------------------------------------
     834                 :            :     //  VirtPrinter/PDF  | 0 - 1   | 0 - 1       | -
     835                 :            :     // ----------------------------------------------------
     836                 :            :     //  Window/VirtWindow| 0 - 1   | 0 - 1       | 1 - 0
     837                 :            :     //
     838                 :            :     // Exception: During painting of a Writer OLE object, we do not have
     839                 :            :     // a window. Therefore bUseSrcFont is always 0 in this case.
     840                 :            :     //
     841                 :            : 
     842                 :            : #if OSL_DEBUG_LEVEL > 0
     843                 :            : 
     844                 :            :     const sal_Bool bNoAdjust = bPrt ||
     845                 :            :             (  pWin &&
     846                 :            :                rInf.GetShell()->GetViewOptions()->getBrowseMode() &&
     847                 :            :               !rInf.GetShell()->GetViewOptions()->IsPrtFormat() );
     848                 :            : 
     849                 :            :     if ( OUTDEV_PRINTER == rInf.GetOut().GetOutDevType() )
     850                 :            :     {
     851                 :            :         // Printer output
     852                 :            :         if ( OUTDEV_PRINTER == rRefDev.GetOutDevType() )
     853                 :            :         {
     854                 :            :             OSL_ENSURE( bNoAdjust == 1 && bUseScrFont == 0, "Outdev Check failed" );
     855                 :            :         }
     856                 :            :         else if ( OUTDEV_VIRDEV == rRefDev.GetOutDevType() )
     857                 :            :         {
     858                 :            :             OSL_ENSURE( bNoAdjust == 0 && bUseScrFont == 1, "Outdev Check failed" );
     859                 :            :         }
     860                 :            :         else
     861                 :            :         {
     862                 :            :             OSL_FAIL( "Outdev Check failed" );
     863                 :            :         }
     864                 :            :     }
     865                 :            :     else if ( OUTDEV_VIRDEV == rInf.GetOut().GetOutDevType() && ! pWin )
     866                 :            :     {
     867                 :            :         // PDF export
     868                 :            :         if ( OUTDEV_PRINTER == rRefDev.GetOutDevType() )
     869                 :            :         {
     870                 :            :             OSL_ENSURE( bNoAdjust == 0 && bUseScrFont == 1, "Outdev Check failed" );
     871                 :            :         }
     872                 :            :         else if ( OUTDEV_VIRDEV == rRefDev.GetOutDevType() )
     873                 :            :         {
     874                 :            :             OSL_ENSURE( bNoAdjust == 0 && bUseScrFont == 1, "Outdev Check failed" );
     875                 :            :         }
     876                 :            :         else
     877                 :            :         {
     878                 :            :             OSL_FAIL( "Outdev Check failed" );
     879                 :            :         }
     880                 :            :     }
     881                 :            :     else if ( OUTDEV_WINDOW == rInf.GetOut().GetOutDevType() ||
     882                 :            :                ( OUTDEV_VIRDEV == rInf.GetOut().GetOutDevType() && pWin ) )
     883                 :            :     {
     884                 :            :         // Window or virtual window
     885                 :            :         if ( OUTDEV_PRINTER == rRefDev.GetOutDevType() )
     886                 :            :         {
     887                 :            :             OSL_ENSURE( bNoAdjust == 0 && bUseScrFont == 1, "Outdev Check failed" );
     888                 :            :         }
     889                 :            :         else if ( OUTDEV_VIRDEV == rRefDev.GetOutDevType() )
     890                 :            :         {
     891                 :            :             OSL_ENSURE( bNoAdjust == 0 && bUseScrFont == 1, "Outdev Check failed" );
     892                 :            :         }
     893                 :            :         else if ( OUTDEV_WINDOW == rRefDev.GetOutDevType() )
     894                 :            :         {
     895                 :            :             OSL_ENSURE( bNoAdjust == 1 && bUseScrFont == 0, "Outdev Check failed" );
     896                 :            :         }
     897                 :            :         else
     898                 :            :         {
     899                 :            :             OSL_FAIL( "Outdev Check failed" );
     900                 :            :         }
     901                 :            :     }
     902                 :            :     else
     903                 :            :     {
     904                 :            :             OSL_FAIL( "Outdev Check failed" );
     905                 :            :     }
     906                 :            : 
     907                 :            : #endif
     908                 :            : 
     909                 :            :     // robust: better use the printer font instead of using no font at all
     910                 :            :     OSL_ENSURE( pTmpFont, "No screen or printer font?" );
     911         [ -  + ]:      26445 :     if ( ! pTmpFont )
     912                 :          0 :         pTmpFont = pPrtFont;
     913                 :            : 
     914                 :            :     // HACK: UNDERLINE_WAVE must not be abused any more, hence the grey wave
     915                 :            :     // line of the ExtendedAttributeSets will appear in the font color first
     916                 :            : 
     917 [ +  - ][ +  - ]:      26445 :     const sal_Bool bSwitchH2V = rInf.GetFrm() && rInf.GetFrm()->IsVertical();
                 [ -  + ]
     918         [ +  - ]:      52890 :     const sal_Bool bSwitchL2R = rInf.GetFrm() && rInf.GetFrm()->IsRightToLeft() &&
     919 [ -  + ][ #  # ]:      52890 :                             ! rInf.IsIgnoreFrmRTL();
                 [ +  - ]
     920                 :      26445 :     const sal_uLong nMode = rInf.GetOut().GetLayoutMode();
     921                 :            :     const sal_Bool bBidiPor = ( bSwitchL2R !=
     922                 :      26445 :                             ( 0 != ( TEXT_LAYOUT_BIDI_RTL & nMode ) ) );
     923                 :            : 
     924                 :            :     // be sure to have the correct layout mode at the printer
     925         [ +  - ]:      26445 :     if ( pPrinter )
     926                 :            :     {
     927         [ +  - ]:      26445 :         pPrinter->SetLayoutMode( rInf.GetOut().GetLayoutMode() );
     928         [ +  - ]:      26445 :         pPrinter->SetDigitLanguage( rInf.GetOut().GetDigitLanguage() );
     929                 :            :     }
     930                 :            : 
     931                 :      26445 :     Point aPos( rInf.GetPos() );
     932         [ +  - ]:      26445 :     if( !bPrt )
     933                 :            :     {
     934 [ +  + ][ +  - ]:      26445 :         if( rInf.GetpOut() != pPixOut || rInf.GetOut().GetMapMode() != *pPixMap )
         [ +  + ][ +  + ]
     935                 :            :         {
     936         [ +  - ]:        516 :             *pPixMap = rInf.GetOut().GetMapMode();
     937                 :        516 :             pPixOut = rInf.GetpOut();
     938                 :        516 :             Size aTmp( 1, 1 );
     939         [ +  - ]:        516 :             nPixWidth = rInf.GetOut().PixelToLogic( aTmp ).Width();
     940                 :            :         }
     941                 :            : 
     942 [ +  - ][ +  - ]:      26445 :         aPos.X() += rInf.GetFrm()->IsRightToLeft() ? 0 : nPixWidth;
     943                 :            :     }
     944                 :            : 
     945         [ +  - ]:      26445 :     Color aOldColor( pTmpFont->GetColor() );
     946         [ +  - ]:      26445 :     sal_Bool bChgColor = rInf.ApplyAutoColor( pTmpFont );
     947 [ +  - ][ +  + ]:      26445 :     if( !pTmpFont->IsSameInstance( rInf.GetOut().GetFont() ) )
     948         [ +  - ]:      25908 :         rInf.GetOut().SetFont( *pTmpFont );
     949         [ +  + ]:      26445 :     if ( bChgColor )
     950         [ +  - ]:      25908 :         pTmpFont->SetColor( aOldColor );
     951                 :            : 
     952         [ -  + ]:      26445 :     if ( STRING_LEN == rInf.GetLen() )
     953                 :          0 :         rInf.SetLen( rInf.GetText().Len() );
     954                 :            : 
     955                 :            : 
     956                 :            :     //
     957                 :            :     // ASIAN LINE AND CHARACTER GRID MODE START: snap to characters
     958                 :            :     //
     959                 :            : 
     960 [ +  - ][ +  + ]:      51647 :     if ( rInf.GetFrm() && rInf.SnapToGrid() && rInf.GetFont() &&
           [ +  -  -  + ]
                 [ -  + ]
     961                 :      25202 :          SW_CJK == rInf.GetFont()->GetActual() )
     962                 :            :     {
     963 [ #  # ][ #  # ]:          0 :         GETGRID( rInf.GetFrm()->FindPageFrm() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     964 [ #  # ][ #  # ]:          0 :         if ( pGrid && GRID_LINES_CHARS == pGrid->GetGridType() && pGrid->IsSnapToChars())
         [ #  # ][ #  # ]
     965                 :            :         {
     966                 :            :             //for textgrid refactor
     967                 :            :             //const sal_uInt16 nGridWidth = pGrid->GetBaseHeight();
     968                 :          0 :             const SwDoc* pDoc = rInf.GetShell()->GetDoc();
     969 [ #  # ][ #  # ]:          0 :             const sal_uInt16 nGridWidth = GETGRIDWIDTH(pGrid, pDoc);
     970         [ #  # ]:          0 :             sal_Int32* pKernArray = new sal_Int32[rInf.GetLen()];
     971                 :            : 
     972         [ #  # ]:          0 :             if ( pPrinter )
     973                 :          0 :                 pPrinter->GetTextArray( rInf.GetText(), pKernArray,
     974         [ #  # ]:          0 :                                         rInf.GetIdx(), rInf.GetLen() );
     975                 :            :             else
     976                 :          0 :                 rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray,
     977         [ #  # ]:          0 :                                             rInf.GetIdx(), rInf.GetLen() );
     978                 :            : 
     979                 :          0 :             long nWidthPerChar = pKernArray[ rInf.GetLen() - 1 ] / rInf.GetLen();
     980                 :            : 
     981                 :            :             const sal_uLong i = nWidthPerChar ?
     982                 :            :                                 ( nWidthPerChar - 1 ) / nGridWidth + 1:
     983         [ #  # ]:          0 :                                 1;
     984                 :            : 
     985                 :          0 :             nWidthPerChar = i * nGridWidth;
     986                 :            : 
     987                 :            :             // position of first character, we take the printer position
     988                 :          0 :             long nCharWidth = pKernArray[ 0 ];
     989                 :          0 :             sal_uLong nHalfWidth = nWidthPerChar / 2;
     990                 :            : 
     991                 :            :             long nNextFix;
     992                 :            : 
     993                 :            :             // punctuation characters are not centered
     994                 :          0 :             xub_Unicode cChar = rInf.GetText().GetChar( rInf.GetIdx() );
     995                 :          0 :             sal_uInt8 nType = lcl_WhichPunctuation( cChar );
     996      [ #  #  # ]:          0 :             switch ( nType )
     997                 :            :             {
     998                 :            :             case SwScriptInfo::NONE :
     999                 :          0 :                 aPos.X() += ( nWidthPerChar - nCharWidth ) / 2;
    1000                 :          0 :                 nNextFix = nCharWidth / 2;
    1001                 :          0 :                 break;
    1002                 :            :             case SwScriptInfo::SPECIAL_RIGHT :
    1003                 :          0 :                 nNextFix = nHalfWidth;
    1004                 :          0 :                 break;
    1005                 :            :             default:
    1006                 :          0 :                 aPos.X() += nWidthPerChar - nCharWidth;
    1007                 :          0 :                 nNextFix = nCharWidth - nHalfWidth;
    1008                 :            :             }
    1009                 :            : 
    1010                 :            :             // calculate offsets
    1011         [ #  # ]:          0 :             for ( xub_StrLen j = 1; j < rInf.GetLen(); ++j )
    1012                 :            :             {
    1013                 :          0 :                 long nScr = pKernArray[ j ] - pKernArray[ j - 1 ];
    1014                 :          0 :                 nNextFix += nWidthPerChar;
    1015                 :            : 
    1016                 :            :                 // punctuation characters are not centered
    1017                 :          0 :                 cChar = rInf.GetText().GetChar( rInf.GetIdx() + j );
    1018                 :          0 :                 nType = lcl_WhichPunctuation( cChar );
    1019      [ #  #  # ]:          0 :                 switch ( nType )
    1020                 :            :                 {
    1021                 :            :                 case SwScriptInfo::NONE :
    1022                 :          0 :                     pKernArray[ j - 1 ] = nNextFix - ( nScr / 2 );
    1023                 :          0 :                     break;
    1024                 :            :                 case SwScriptInfo::SPECIAL_RIGHT :
    1025                 :          0 :                     pKernArray[ j - 1 ] = nNextFix - nHalfWidth;
    1026                 :          0 :                     break;
    1027                 :            :                 default:
    1028                 :          0 :                     pKernArray[ j - 1 ] = nNextFix + nHalfWidth - nScr;
    1029                 :            :                 }
    1030                 :            :             }
    1031                 :            : 
    1032                 :            :             // the layout engine requires the total width of the output
    1033                 :          0 :             pKernArray[ rInf.GetLen() - 1 ] = rInf.GetWidth() -
    1034                 :          0 :                                               aPos.X() + rInf.GetPos().X() ;
    1035                 :            : 
    1036         [ #  # ]:          0 :             if ( bSwitchH2V )
    1037         [ #  # ]:          0 :                 rInf.GetFrm()->SwitchHorizontalToVertical( aPos );
    1038                 :            : 
    1039                 :          0 :             rInf.GetOut().DrawTextArray( aPos, rInf.GetText(),
    1040         [ #  # ]:          0 :                 pKernArray, rInf.GetIdx(), rInf.GetLen() );
    1041                 :            : 
    1042         [ #  # ]:          0 :             delete[] pKernArray;
    1043                 :            :             return;
    1044                 :            :         }
    1045                 :            :     }
    1046                 :            : 
    1047                 :            :     // For text grid refactor
    1048                 :            :     // ASIAN LINE AND CHARACTER GRID MODE START: not snap to characters
    1049                 :            :     //
    1050 [ +  - ][ +  + ]:      51647 :     if ( rInf.GetFrm() && rInf.SnapToGrid() && rInf.GetFont() &&
           [ +  -  -  + ]
                 [ -  + ]
    1051                 :      25202 :          SW_CJK == rInf.GetFont()->GetActual() )
    1052                 :            :     {
    1053 [ #  # ][ #  # ]:          0 :         GETGRID( rInf.GetFrm()->FindPageFrm() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1054                 :            : 
    1055 [ #  # ][ #  # ]:          0 :         if ( pGrid && GRID_LINES_CHARS == pGrid->GetGridType() && !pGrid->IsSnapToChars() )
         [ #  # ][ #  # ]
    1056                 :            :         {
    1057         [ #  # ]:          0 :             const sal_uInt16  nDefaultFontHeight = GetDefaultFontHeight( rInf );
    1058                 :            : 
    1059                 :          0 :             const SwDoc* pDoc = rInf.GetShell()->GetDoc();
    1060 [ #  # ][ #  # ]:          0 :             long nGridWidthAdd = GETGRIDWIDTH(pGrid, pDoc);
    1061         [ #  # ]:          0 :             if( SW_LATIN == rInf.GetFont()->GetActual() )
    1062                 :          0 :                 nGridWidthAdd = ( nGridWidthAdd - nDefaultFontHeight ) / 2;
    1063                 :            :             else
    1064                 :          0 :                 nGridWidthAdd = nGridWidthAdd - nDefaultFontHeight;
    1065                 :            : 
    1066         [ #  # ]:          0 :             sal_Int32*  pKernArray = new sal_Int32[rInf.GetLen()];
    1067                 :            : 
    1068         [ #  # ]:          0 :             if ( pPrinter )
    1069                 :          0 :                 pPrinter->GetTextArray( rInf.GetText(), pKernArray,
    1070         [ #  # ]:          0 :                 rInf.GetIdx(), rInf.GetLen() );
    1071                 :            :             else
    1072                 :          0 :                 rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray,
    1073         [ #  # ]:          0 :                 rInf.GetIdx(), rInf.GetLen() );
    1074         [ #  # ]:          0 :             if ( bSwitchH2V )
    1075         [ #  # ]:          0 :                 rInf.GetFrm()->SwitchHorizontalToVertical( aPos );
    1076 [ #  # ][ #  # ]:          0 :             if ( rInf.GetSpace() || rInf.GetKanaComp())
                 [ #  # ]
    1077                 :            :             {
    1078                 :          0 :                 long nSpaceAdd = rInf.GetSpace() / SPACING_PRECISION_FACTOR;
    1079                 :          0 :                 sal_Bool bSpecialJust = sal_False;
    1080 [ #  # ][ #  # ]:          0 :                 if ( rInf.GetFont() && rInf.GetLen() )
                 [ #  # ]
    1081                 :            :                 {
    1082                 :          0 :                     const SwScriptInfo* pSI = rInf.GetScriptInfo();
    1083                 :          0 :                     const sal_uInt8 nActual = rInf.GetFont()->GetActual();
    1084                 :            :                     ///Kana Compression
    1085         [ #  # ]:          0 :                     if( SW_CJK == nActual && rInf.GetKanaComp() &&
           [ #  #  #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1086                 :          0 :                         pSI && pSI->CountCompChg() &&
    1087         [ #  # ]:          0 :                         lcl_IsMonoSpaceFont( *(rInf.GetpOut()) ) )
    1088                 :            :                     {
    1089                 :          0 :                         pSI->Compress( pKernArray,rInf.GetIdx(), rInf.GetLen(),
    1090 [ #  # ][ #  # ]:          0 :                             rInf.GetKanaComp(), (sal_uInt16)aFont.GetSize().Height(),&aPos );
    1091                 :          0 :                         bSpecialJust = sal_True;
    1092                 :            :                     }
    1093                 :            :                     ///Asian Justification
    1094 [ #  # ][ #  # ]:          0 :                     if ( ( SW_CJK == nActual || SW_LATIN == nActual ) && nSpaceAdd )
                 [ #  # ]
    1095                 :            :                     {
    1096                 :          0 :                         LanguageType aLang = rInf.GetFont()->GetLanguage( SW_CJK );
    1097 [ #  # ][ #  # ]:          0 :                         if (MsLangId::isKorean(aLang))
    1098                 :            :                         {
    1099                 :          0 :                             long nSpaceSum = nSpaceAdd;
    1100         [ #  # ]:          0 :                             for ( sal_uInt16 nI = 0; nI < rInf.GetLen(); ++nI )
    1101                 :            :                             {
    1102                 :          0 :                                 pKernArray[ nI ] += nSpaceSum;
    1103                 :          0 :                                 nSpaceSum += nSpaceAdd;
    1104                 :            :                             }
    1105                 :          0 :                             bSpecialJust = sal_True;
    1106                 :          0 :                             nSpaceAdd = 0;
    1107                 :            :                         }
    1108                 :            :                     }
    1109                 :          0 :                     long nGridAddSum = nGridWidthAdd;
    1110         [ #  # ]:          0 :                     for(xub_StrLen i = 0; i < rInf.GetLen(); i++,nGridAddSum += nGridWidthAdd )
    1111                 :            :                     {
    1112                 :          0 :                         pKernArray[i] += nGridAddSum;
    1113                 :            :                     }
    1114                 :          0 :                     long nKernSum = rInf.GetKern();
    1115 [ #  # ][ #  # ]:          0 :                     if ( bSpecialJust || rInf.GetKern() )
                 [ #  # ]
    1116                 :            :                     {
    1117         [ #  # ]:          0 :                         for( xub_StrLen i = 0; i < rInf.GetLen(); i++, nKernSum += rInf.GetKern() )
    1118                 :            :                         {
    1119         [ #  # ]:          0 :                             if ( CH_BLANK == rInf.GetText().GetChar(rInf.GetIdx()+i) )
    1120                 :          0 :                                 nKernSum += nSpaceAdd;
    1121                 :          0 :                             pKernArray[i] += nKernSum;
    1122                 :            :                         }
    1123                 :            :                         ///With through/uderstr. Grouped style requires a blank at the end
    1124                 :            :                         ///of a text edition special measures:
    1125         [ #  # ]:          0 :                         if( bPaintBlank && rInf.GetLen() && (CH_BLANK ==
           [ #  #  #  # ]
                 [ #  # ]
    1126                 :          0 :                             rInf.GetText().GetChar( rInf.GetIdx() + rInf.GetLen() - 1) ) )
    1127                 :            :                         {
    1128                 :            :                             ///If it concerns a singular, underlined space acts,
    1129                 :            :                             ///we must spend two:
    1130         [ #  # ]:          0 :                             if( 1 == rInf.GetLen() )
    1131                 :            :                             {
    1132                 :          0 :                                 pKernArray[0] = rInf.GetWidth() + nSpaceAdd;
    1133                 :          0 :                                 rInf.GetOut().DrawTextArray( aPos, rInf.GetText(),
    1134         [ #  # ]:          0 :                                     pKernArray, rInf.GetIdx(), 1 );
    1135                 :            :                             }
    1136                 :            :                             else
    1137                 :            :                             {
    1138                 :          0 :                                 pKernArray[ rInf.GetLen() - 2] += nSpaceAdd;
    1139                 :          0 :                                 rInf.GetOut().DrawTextArray( aPos, rInf.GetText(),
    1140         [ #  # ]:          0 :                                     pKernArray, rInf.GetIdx(), rInf.GetLen() );
    1141                 :            :                             }
    1142                 :            :                         }
    1143                 :            :                         else
    1144                 :            :                         {
    1145                 :          0 :                             rInf.GetOut().DrawTextArray( aPos, rInf.GetText(),
    1146         [ #  # ]:          0 :                                 pKernArray, rInf.GetIdx(), rInf.GetLen() );
    1147                 :            :                         }
    1148                 :            :                     }
    1149                 :            :                     else
    1150                 :            :                     {
    1151                 :          0 :                         Point aTmpPos( aPos );
    1152                 :            :                         xub_StrLen i;
    1153                 :          0 :                         xub_StrLen j = 0;
    1154                 :          0 :                         long nSpaceSum = 0;
    1155         [ #  # ]:          0 :                         for( i = 0; i < rInf.GetLen(); i++ )
    1156                 :            :                         {
    1157         [ #  # ]:          0 :                             if( CH_BLANK == rInf.GetText().GetChar( rInf.GetIdx() + i) )
    1158                 :            :                             {
    1159                 :          0 :                                 nSpaceSum += nSpaceAdd;
    1160         [ #  # ]:          0 :                                 if( j < i)
    1161                 :          0 :                                     rInf.GetOut().DrawText( aTmpPos, rInf.GetText(),
    1162         [ #  # ]:          0 :                                     rInf.GetIdx() + j, i - j );
    1163                 :          0 :                                 j = i + 1;
    1164                 :          0 :                                 pKernArray[i] = pKernArray[i] + nSpaceSum;
    1165                 :          0 :                                 aTmpPos.X() = aPos.X() + pKernArray[ i ] + nKernSum;
    1166                 :            :                             }
    1167                 :            :                         }
    1168         [ #  # ]:          0 :                         if( j < i )
    1169                 :          0 :                             rInf.GetOut().DrawText( aTmpPos, rInf.GetText(),
    1170         [ #  # ]:          0 :                             rInf.GetIdx() +j , i - j );
    1171                 :            :                     }
    1172                 :            :                 }
    1173                 :            :             }
    1174                 :            :             else
    1175                 :            :             {
    1176                 :            :                 //long nKernAdd = rInf.GetKern();
    1177                 :          0 :         long nKernAdd = 0;
    1178                 :          0 :                 long nGridAddSum = nGridWidthAdd + nKernAdd;
    1179         [ #  # ]:          0 :                 for(xub_StrLen i = 0; i < rInf.GetLen(); i++,nGridAddSum += nGridWidthAdd + nKernAdd )
    1180                 :            :                 {
    1181                 :          0 :                     pKernArray[i] += nGridAddSum;
    1182                 :            :                 }
    1183                 :          0 :                 rInf.GetOut().DrawTextArray( aPos, rInf.GetText(),
    1184         [ #  # ]:          0 :                     pKernArray, rInf.GetIdx(), rInf.GetLen() );
    1185                 :            :             }
    1186         [ #  # ]:          0 :             delete[] pKernArray;
    1187                 :            :             return;
    1188                 :            :         }
    1189                 :            :     }
    1190                 :            : 
    1191                 :            :     //
    1192                 :            :     // DIRECT PAINTING WITHOUT SCREEN ADJUSTMENT
    1193                 :            :     //
    1194                 :            : 
    1195         [ +  + ]:      26445 :     if ( bDirectPrint )
    1196                 :            :     {
    1197         [ +  - ]:         23 :         const Fraction aTmp( 1, 1 );
    1198                 :         23 :         sal_Bool bStretch = rInf.GetWidth() && ( rInf.GetLen() > 1 ) && bPrt
    1199 [ #  # ][ #  # ]:         23 :                         && ( aTmp != rInf.GetOut().GetMapMode().GetScaleX() );
                 [ #  # ]
           [ -  +  #  # ]
    1200                 :            : 
    1201         [ -  + ]:         23 :         if ( bSwitchL2R )
    1202         [ #  # ]:          0 :             rInf.GetFrm()->SwitchLTRtoRTL( aPos );
    1203                 :            : 
    1204         [ -  + ]:         23 :         if ( bSwitchH2V )
    1205         [ #  # ]:          0 :             rInf.GetFrm()->SwitchHorizontalToVertical( aPos );
    1206                 :            : 
    1207                 :            :         // In the good old days we used to have a simple DrawText if the
    1208                 :            :         // output device is the printer. Now we need a DrawTextArray if
    1209                 :            :         // 1. KanaCompression is enabled
    1210                 :            :         // 2. Justified alignment
    1211                 :            :         // Simple kerning is handled by DrawStretchText
    1212 [ +  - ][ -  + ]:         23 :         if( rInf.GetSpace() || rInf.GetKanaComp() )
                 [ -  + ]
    1213                 :            :         {
    1214         [ #  # ]:          0 :             sal_Int32 *pKernArray = new sal_Int32[ rInf.GetLen() ];
    1215                 :          0 :             rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray,
    1216         [ #  # ]:          0 :                                        rInf.GetIdx(), rInf.GetLen() );
    1217                 :            : 
    1218         [ #  # ]:          0 :             if( bStretch )
    1219                 :            :             {
    1220                 :          0 :                 xub_StrLen nZwi = rInf.GetLen() - 1;
    1221                 :          0 :                 long nDiff = rInf.GetWidth() - pKernArray[ nZwi ]
    1222                 :          0 :                              - rInf.GetLen() * rInf.GetKern();
    1223                 :          0 :                 long nRest = nDiff % nZwi;
    1224                 :            :                 long nAdd;
    1225         [ #  # ]:          0 :                 if( nRest < 0 )
    1226                 :            :                 {
    1227                 :          0 :                     nAdd = -1;
    1228                 :          0 :                     nRest += nZwi;
    1229                 :            :                 }
    1230                 :            :                 else
    1231                 :            :                 {
    1232                 :          0 :                     nAdd = +1;
    1233                 :          0 :                     nRest = nZwi - nRest;
    1234                 :            :                 }
    1235                 :          0 :                 nDiff /= nZwi;
    1236                 :          0 :                 long nSum = nDiff;
    1237         [ #  # ]:          0 :                 for( xub_StrLen i = 0; i < nZwi; )
    1238                 :            :                 {
    1239                 :          0 :                     pKernArray[ i ] += nSum;
    1240         [ #  # ]:          0 :                     if( ++i == nRest )
    1241                 :          0 :                         nDiff += nAdd;
    1242                 :          0 :                     nSum += nDiff;
    1243                 :            :                 }
    1244                 :            :             }
    1245                 :            : 
    1246                 :            :             //
    1247                 :            :             // Modify Array for special justifications
    1248                 :            :             //
    1249                 :          0 :             long nSpaceAdd = rInf.GetSpace() / SPACING_PRECISION_FACTOR;
    1250                 :          0 :             sal_Bool bSpecialJust = sal_False;
    1251                 :            : 
    1252 [ #  # ][ #  # ]:          0 :             if ( rInf.GetFont() && rInf.GetLen() )
                 [ #  # ]
    1253                 :            :             {
    1254                 :          0 :                 const SwScriptInfo* pSI = rInf.GetScriptInfo();
    1255                 :          0 :                 const sal_uInt8 nActual = rInf.GetFont()->GetActual();
    1256                 :            : 
    1257                 :            :                 // Kana Compression
    1258         [ #  # ]:          0 :                 if ( SW_CJK == nActual && rInf.GetKanaComp() &&
           [ #  #  #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1259                 :          0 :                      pSI && pSI->CountCompChg() &&
    1260         [ #  # ]:          0 :                      lcl_IsMonoSpaceFont( rInf.GetOut() ) )
    1261                 :            :                 {
    1262                 :          0 :                     pSI->Compress( pKernArray, rInf.GetIdx(), rInf.GetLen(),
    1263                 :          0 :                                    rInf.GetKanaComp(),
    1264 [ #  # ][ #  # ]:          0 :                                    (sal_uInt16)aFont.GetSize().Height(), &aPos );
    1265                 :          0 :                     bSpecialJust = sal_True;
    1266                 :            :                 }
    1267                 :            : 
    1268                 :            :                 // Asian Justification
    1269 [ #  # ][ #  # ]:          0 :                 if ( SW_CJK == nActual && nSpaceAdd )
    1270                 :            :                 {
    1271                 :          0 :                     LanguageType aLang = rInf.GetFont()->GetLanguage( SW_CJK );
    1272                 :            : 
    1273 [ #  # ][ #  # ]:          0 :                     if (MsLangId::isKorean(aLang))
    1274                 :            :                     {
    1275                 :          0 :                         long nSpaceSum = nSpaceAdd;
    1276         [ #  # ]:          0 :                         for ( sal_uInt16 nI = 0; nI < rInf.GetLen(); ++nI )
    1277                 :            :                         {
    1278                 :          0 :                             pKernArray[ nI ] += nSpaceSum;
    1279                 :          0 :                             nSpaceSum += nSpaceAdd;
    1280                 :            :                         }
    1281                 :            : 
    1282                 :          0 :                         bSpecialJust = sal_True;
    1283                 :          0 :                         nSpaceAdd = 0;
    1284                 :            :                     }
    1285                 :            :                 }
    1286                 :            : 
    1287                 :            :                 // Kashida Justification
    1288 [ #  # ][ #  # ]:          0 :                 if ( SW_CTL == nActual && nSpaceAdd )
    1289                 :            :                 {
    1290 [ #  # ][ #  # ]:          0 :                     if ( SwScriptInfo::IsArabicText( rInf.GetText(), rInf.GetIdx(), rInf.GetLen() ) )
                 [ #  # ]
    1291                 :            :                     {
    1292 [ #  # ][ #  # ]:          0 :                         if ( pSI && pSI->CountKashida() &&
         [ #  # ][ #  # ]
    1293                 :          0 :                             pSI->KashidaJustify( pKernArray, 0, rInf.GetIdx(),
    1294         [ #  # ]:          0 :                                                  rInf.GetLen(), nSpaceAdd ) != STRING_LEN )
    1295                 :            :                         {
    1296                 :          0 :                             bSpecialJust = sal_True;
    1297                 :          0 :                             nSpaceAdd = 0;
    1298                 :            :                         }
    1299                 :            :                     }
    1300                 :            :                 }
    1301                 :            : 
    1302                 :            :                 // Thai Justification
    1303 [ #  # ][ #  # ]:          0 :                 if ( SW_CTL == nActual && nSpaceAdd )
    1304                 :            :                 {
    1305                 :          0 :                     LanguageType aLang = rInf.GetFont()->GetLanguage( SW_CTL );
    1306                 :            : 
    1307         [ #  # ]:          0 :                     if ( LANGUAGE_THAI == aLang )
    1308                 :            :                     {
    1309                 :            :                         // Use rInf.GetSpace() because it has more precision than
    1310                 :            :                         // nSpaceAdd:
    1311                 :          0 :                         SwScriptInfo::ThaiJustify( rInf.GetText(), pKernArray, 0,
    1312                 :          0 :                                                    rInf.GetIdx(), rInf.GetLen(),
    1313                 :          0 :                                                    rInf.GetNumberOfBlanks(),
    1314 [ #  # ][ #  # ]:          0 :                                                    rInf.GetSpace() );
    1315                 :            : 
    1316                 :            :                         // adding space to blanks is already done
    1317                 :          0 :                         bSpecialJust = sal_True;
    1318                 :          0 :                         nSpaceAdd = 0;
    1319                 :            :                     }
    1320                 :            :                 }
    1321                 :            :             }
    1322                 :            : 
    1323                 :          0 :             long nKernSum = rInf.GetKern();
    1324                 :            : 
    1325 [ #  # ][ #  # ]:          0 :             if ( bStretch || bPaintBlank || rInf.GetKern() || bSpecialJust )
         [ #  # ][ #  # ]
                 [ #  # ]
    1326                 :            :             {
    1327         [ #  # ]:          0 :                 for( xub_StrLen i = 0; i < rInf.GetLen(); i++,
    1328                 :            :                      nKernSum += rInf.GetKern() )
    1329                 :            :                 {
    1330         [ #  # ]:          0 :                     if ( CH_BLANK == rInf.GetText().GetChar(rInf.GetIdx()+i) )
    1331                 :          0 :                         nKernSum += nSpaceAdd;
    1332                 :          0 :                     pKernArray[i] += nKernSum;
    1333                 :            :                 }
    1334                 :            : 
    1335                 :            :                 // In case of underlined/strike-through justified text
    1336                 :            :                 // a blank at the end requires special handling:
    1337         [ #  # ]:          0 :                 if( bPaintBlank && rInf.GetLen() && ( CH_BLANK ==
           [ #  #  #  # ]
                 [ #  # ]
    1338                 :          0 :                     rInf.GetText().GetChar( rInf.GetIdx()+rInf.GetLen()-1 ) ) )
    1339                 :            :                 {
    1340                 :            :                     // If it is a single underlined space, output 2 spaces:
    1341         [ #  # ]:          0 :                     if( 1 == rInf.GetLen() )
    1342                 :            :                     {
    1343                 :          0 :                            pKernArray[0] = rInf.GetWidth() + nSpaceAdd;
    1344                 :            : 
    1345                 :          0 :                         rInf.GetOut().DrawTextArray( aPos, rInf.GetText(),
    1346         [ #  # ]:          0 :                                                      pKernArray, rInf.GetIdx(), 1 );
    1347                 :            :                     }
    1348                 :            :                     else
    1349                 :            :                     {
    1350                 :          0 :                         pKernArray[ rInf.GetLen() - 2 ] += nSpaceAdd;
    1351                 :          0 :                         rInf.GetOut().DrawTextArray( aPos, rInf.GetText(),
    1352         [ #  # ]:          0 :                             pKernArray, rInf.GetIdx(), rInf.GetLen() );
    1353                 :            :                     }
    1354                 :            :                 }
    1355                 :            :                 else
    1356                 :          0 :                     rInf.GetOut().DrawTextArray( aPos, rInf.GetText(),
    1357         [ #  # ]:          0 :                                                  pKernArray, rInf.GetIdx(), rInf.GetLen() );
    1358                 :            :             }
    1359                 :            :             else
    1360                 :            :             {
    1361                 :          0 :                 Point aTmpPos( aPos );
    1362                 :          0 :                 xub_StrLen j = 0;
    1363                 :            :                 xub_StrLen i;
    1364         [ #  # ]:          0 :                 for( i = 0; i < rInf.GetLen(); i++ )
    1365                 :            :                 {
    1366         [ #  # ]:          0 :                     if( CH_BLANK == rInf.GetText().GetChar( rInf.GetIdx()+i ) )
    1367                 :            :                     {
    1368                 :          0 :                         nKernSum += nSpaceAdd;
    1369         [ #  # ]:          0 :                         if( j < i )
    1370                 :          0 :                         rInf.GetOut().DrawText( aTmpPos, rInf.GetText(),
    1371         [ #  # ]:          0 :                                                 rInf.GetIdx() + j, i - j );
    1372                 :          0 :                         j = i + 1;
    1373                 :          0 :                         SwTwips nAdd = pKernArray[ i ] + nKernSum;
    1374         [ #  # ]:          0 :                         if ( ( TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL ) == nMode )
    1375                 :          0 :                             nAdd *= -1;
    1376                 :          0 :                         aTmpPos.X() = aPos.X() + nAdd;
    1377                 :            :                     }
    1378                 :            :                 }
    1379         [ #  # ]:          0 :                 if( j < i )
    1380                 :          0 :                     rInf.GetOut().DrawText( aTmpPos, rInf.GetText(),
    1381         [ #  # ]:          0 :                                             rInf.GetIdx() + j, i - j );
    1382                 :            :             }
    1383         [ #  # ]:          0 :             delete[] pKernArray;
    1384                 :            :         }
    1385         [ -  + ]:         23 :         else if( bStretch )
    1386                 :            :         {
    1387                 :          0 :             long nTmpWidth = rInf.GetWidth();
    1388 [ #  # ][ #  # ]:          0 :             if( rInf.GetKern() && rInf.GetLen() && nTmpWidth > rInf.GetKern() )
         [ #  # ][ #  # ]
    1389                 :          0 :                 nTmpWidth -= rInf.GetKern();
    1390                 :          0 :             rInf.GetOut().DrawStretchText( aPos, nTmpWidth,
    1391         [ #  # ]:          0 :                                            rInf.GetText(), rInf.GetIdx(), rInf.GetLen() );
    1392                 :            :         }
    1393         [ -  + ]:         23 :         else if( rInf.GetKern() )
    1394                 :            :         {
    1395         [ #  # ]:          0 :             const long nTmpWidth = GetTextSize( rInf ).Width();
    1396                 :            : 
    1397         [ #  # ]:          0 :             const Color aSaveColor( pTmpFont->GetColor() );
    1398         [ #  # ]:          0 :             const sal_Bool bColorChanged = rInf.ApplyAutoColor( pTmpFont );
    1399                 :            : 
    1400         [ #  # ]:          0 :             if( bColorChanged )
    1401                 :            :             {
    1402 [ #  # ][ #  # ]:          0 :                 if( !pTmpFont->IsSameInstance( rInf.GetOut().GetFont() ) )
    1403         [ #  # ]:          0 :                     rInf.GetOut().SetFont( *pTmpFont );
    1404         [ #  # ]:          0 :                 pTmpFont->SetColor( aSaveColor );
    1405                 :            :             }
    1406                 :            : 
    1407                 :          0 :             rInf.GetOut().DrawStretchText( aPos, (sal_uInt16)nTmpWidth,
    1408         [ #  # ]:          0 :                                            rInf.GetText(), rInf.GetIdx(), rInf.GetLen() );
    1409                 :            :         }
    1410                 :            :         else
    1411                 :         23 :             rInf.GetOut().DrawText( aPos, rInf.GetText(),
    1412         [ +  - ]:         46 :                                     rInf.GetIdx(), rInf.GetLen() );
    1413                 :            :     }
    1414                 :            : 
    1415                 :            :     //
    1416                 :            :     // PAINTING WITH FORMATTING DEVICE/SCREEN ADJUSTMENT
    1417                 :            :     //
    1418                 :            : 
    1419                 :            :     else
    1420                 :            :     {
    1421                 :      26422 :         const String* pStr = &rInf.GetText();
    1422         [ +  - ]:      26422 :         String aStr( aEmptyStr );
    1423                 :      26422 :         sal_Bool bBullet = rInf.GetBullet();
    1424         [ +  + ]:      26422 :         if( bSymbol )
    1425                 :         14 :             bBullet = sal_False;
    1426         [ +  - ]:      26422 :         sal_Int32 *pKernArray = new sal_Int32[ rInf.GetLen() ];
    1427         [ +  - ]:      26422 :         CreateScrFont( *rInf.GetShell(), rInf.GetOut() );
    1428                 :            :         long nScrPos;
    1429                 :            : 
    1430                 :            :         // get screen array
    1431         [ +  - ]:      26422 :         sal_Int32* pScrArray = new sal_Int32[ rInf.GetLen() ];
    1432                 :      26422 :         rInf.GetOut().GetTextArray( rInf.GetText(), pScrArray,
    1433         [ +  - ]:      52844 :                                     rInf.GetIdx(), rInf.GetLen() );
    1434                 :            : 
    1435                 :            :         // OLE: no printer available
    1436                 :            :         // OSL_ENSURE( pPrinter, "DrawText needs pPrinter" )
    1437         [ +  - ]:      26422 :         if ( pPrinter )
    1438                 :            :         {
    1439                 :            :             // pTmpFont has already been set as current font for rInf.GetOut()
    1440 [ -  + ][ #  # ]:      26422 :             if ( pPrinter != rInf.GetpOut() || pTmpFont != pPrtFont )
                 [ +  - ]
    1441                 :            :             {
    1442 [ +  - ][ +  + ]:      26422 :                 if( !pPrtFont->IsSameInstance( pPrinter->GetFont() ) )
    1443         [ +  - ]:      25885 :                     pPrinter->SetFont( *pPrtFont );
    1444                 :            :             }
    1445                 :      26422 :             pPrinter->GetTextArray( rInf.GetText(), pKernArray, rInf.GetIdx(),
    1446         [ +  - ]:      52844 :                                     rInf.GetLen() );
    1447                 :            :         }
    1448                 :            :         else
    1449                 :            :         {
    1450                 :          0 :             rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray,
    1451         [ #  # ]:          0 :                                         rInf.GetIdx(), rInf.GetLen() );
    1452                 :            :         }
    1453                 :            : 
    1454                 :            :         //
    1455                 :            :         // Modify Printer and ScreenArrays for special justifications
    1456                 :            :         //
    1457                 :      26422 :         long nSpaceAdd = rInf.GetSpace() / SPACING_PRECISION_FACTOR;
    1458                 :      26422 :         bool bNoHalfSpace = false;
    1459                 :            : 
    1460 [ +  - ][ +  - ]:      26422 :         if ( rInf.GetFont() && rInf.GetLen() )
                 [ +  - ]
    1461                 :            :         {
    1462                 :      26422 :             const sal_uInt8 nActual = rInf.GetFont()->GetActual();
    1463                 :      26422 :             const SwScriptInfo* pSI = rInf.GetScriptInfo();
    1464                 :            : 
    1465                 :            :             // Kana Compression
    1466         [ #  # ]:      26422 :             if ( SW_CJK == nActual && rInf.GetKanaComp() &&
           [ #  #  #  # ]
         [ #  # ][ -  + ]
                 [ -  + ]
    1467                 :          0 :                  pSI && pSI->CountCompChg() &&
    1468         [ #  # ]:          0 :                  lcl_IsMonoSpaceFont( rInf.GetOut() ) )
    1469                 :            :             {
    1470                 :          0 :                 Point aTmpPos( aPos );
    1471                 :          0 :                 pSI->Compress( pScrArray, rInf.GetIdx(), rInf.GetLen(),
    1472                 :          0 :                                rInf.GetKanaComp(),
    1473 [ #  # ][ #  # ]:          0 :                                (sal_uInt16)aFont.GetSize().Height(), &aTmpPos );
    1474                 :          0 :                 pSI->Compress( pKernArray, rInf.GetIdx(), rInf.GetLen(),
    1475                 :          0 :                                rInf.GetKanaComp(),
    1476 [ #  # ][ #  # ]:          0 :                                (sal_uInt16)aFont.GetSize().Height(), &aPos );
    1477                 :            :             }
    1478                 :            : 
    1479                 :            :             // Asian Justification
    1480 [ -  + ][ #  # ]:      26422 :             if ( SW_CJK == nActual && nSpaceAdd )
    1481                 :            :             {
    1482                 :          0 :                 LanguageType aLang = rInf.GetFont()->GetLanguage( SW_CJK );
    1483                 :            : 
    1484 [ #  # ][ #  # ]:          0 :                 if (MsLangId::isKorean(aLang))
    1485                 :            :                 {
    1486                 :          0 :                     long nSpaceSum = nSpaceAdd;
    1487         [ #  # ]:          0 :                     for ( sal_uInt16 nI = 0; nI < rInf.GetLen(); ++nI )
    1488                 :            :                     {
    1489                 :          0 :                         pKernArray[ nI ] += nSpaceSum;
    1490                 :          0 :                         pScrArray[ nI ] += nSpaceSum;
    1491                 :          0 :                         nSpaceSum += nSpaceAdd;
    1492                 :            :                     }
    1493                 :            : 
    1494                 :          0 :                     nSpaceAdd = 0;
    1495                 :            :                 }
    1496                 :            :             }
    1497                 :            : 
    1498                 :            :             // Kashida Justification
    1499 [ -  + ][ #  # ]:      26422 :             if ( SW_CTL == nActual && nSpaceAdd )
    1500                 :            :             {
    1501 [ #  # ][ #  # ]:          0 :                 if ( SwScriptInfo::IsArabicText( rInf.GetText(), rInf.GetIdx(), rInf.GetLen() ) )
                 [ #  # ]
    1502                 :            :                 {
    1503 [ #  # ][ #  # ]:          0 :                     if ( pSI && pSI->CountKashida() &&
         [ #  # ][ #  # ]
    1504                 :          0 :                          pSI->KashidaJustify( pKernArray, pScrArray, rInf.GetIdx(),
    1505         [ #  # ]:          0 :                                               rInf.GetLen(), nSpaceAdd ) != STRING_LEN )
    1506                 :          0 :                         nSpaceAdd = 0;
    1507                 :            :                     else
    1508                 :          0 :                         bNoHalfSpace = true;
    1509                 :            :                 }
    1510                 :            :             }
    1511                 :            : 
    1512                 :            :             // Thai Justification
    1513 [ -  + ][ #  # ]:      26422 :             if ( SW_CTL == nActual && nSpaceAdd )
    1514                 :            :             {
    1515                 :          0 :                 LanguageType aLang = rInf.GetFont()->GetLanguage( SW_CTL );
    1516                 :            : 
    1517         [ #  # ]:          0 :                 if ( LANGUAGE_THAI == aLang )
    1518                 :            :                 {
    1519                 :          0 :                     SwScriptInfo::ThaiJustify( rInf.GetText(), pKernArray,
    1520                 :          0 :                                                pScrArray, rInf.GetIdx(),
    1521                 :          0 :                                                rInf.GetLen(),
    1522                 :          0 :                                                rInf.GetNumberOfBlanks(),
    1523 [ #  # ][ #  # ]:          0 :                                                rInf.GetSpace() );
    1524                 :            : 
    1525                 :            :                     // adding space to blanks is already done
    1526                 :          0 :                     nSpaceAdd = 0;
    1527                 :            :                 }
    1528                 :            :             }
    1529                 :            :         }
    1530                 :            : 
    1531                 :      26422 :         nScrPos = pScrArray[ 0 ];
    1532                 :            : 
    1533         [ -  + ]:      26422 :         if( bBullet )
    1534                 :            :         {
    1535                 :            :             // !!! HACK !!!
    1536                 :            :             // The Arabic layout engine requires some context of the string
    1537                 :            :             // which should be painted.
    1538                 :          0 :             xub_StrLen nCopyStart = rInf.GetIdx();
    1539         [ #  # ]:          0 :             if ( nCopyStart )
    1540                 :          0 :                 --nCopyStart;
    1541                 :            : 
    1542                 :          0 :             xub_StrLen nCopyLen = rInf.GetLen();
    1543         [ #  # ]:          0 :             if ( nCopyStart + nCopyLen < rInf.GetText().Len() )
    1544                 :          0 :                 ++nCopyLen;
    1545                 :            : 
    1546 [ #  # ][ #  # ]:          0 :             aStr = rInf.GetText().Copy( nCopyStart, nCopyLen );
                 [ #  # ]
    1547                 :          0 :             pStr = &aStr;
    1548                 :            : 
    1549         [ #  # ]:          0 :             for( xub_StrLen i = 0; i < aStr.Len(); ++i )
    1550         [ #  # ]:          0 :                 if( CH_BLANK == aStr.GetChar( i ) )
    1551         [ #  # ]:          0 :                     aStr.SetChar( i, CH_BULLET );
    1552                 :            :         }
    1553                 :            : 
    1554                 :      26422 :         xub_StrLen nCnt = rInf.GetText().Len();
    1555         [ -  + ]:      26422 :         if ( nCnt < rInf.GetIdx() )
    1556                 :          0 :             nCnt = 0;
    1557                 :            :         else
    1558                 :      26422 :             nCnt = nCnt - rInf.GetIdx();
    1559                 :      26422 :         nCnt = Min( nCnt, rInf.GetLen() );
    1560                 :      26422 :         long nKernSum = rInf.GetKern();
    1561                 :      26422 :         xub_Unicode cChPrev = rInf.GetText().GetChar( rInf.GetIdx() );
    1562                 :            : 
    1563                 :            :         // In case of a single underlined space in justified text,
    1564                 :            :         // have to output 2 spaces:
    1565 [ -  + ][ #  # ]:      26422 :         if ( ( nCnt == 1 ) && rInf.GetSpace() && ( cChPrev == CH_BLANK ) )
         [ -  + ][ +  + ]
    1566                 :            :         {
    1567                 :          0 :             pKernArray[0] = rInf.GetWidth() +
    1568                 :          0 :                             rInf.GetKern() +
    1569                 :          0 :                           ( rInf.GetSpace() / SPACING_PRECISION_FACTOR );
    1570                 :            : 
    1571         [ #  # ]:          0 :             if ( bSwitchL2R )
    1572         [ #  # ]:          0 :                 rInf.GetFrm()->SwitchLTRtoRTL( aPos );
    1573                 :            : 
    1574         [ #  # ]:          0 :             if ( bSwitchH2V )
    1575         [ #  # ]:          0 :                 rInf.GetFrm()->SwitchHorizontalToVertical( aPos );
    1576                 :            : 
    1577                 :          0 :             rInf.GetOut().DrawTextArray( aPos, rInf.GetText(),
    1578         [ #  # ]:          0 :                                          pKernArray, rInf.GetIdx(), 1 );
    1579         [ #  # ]:          0 :             if( bBullet )
    1580                 :          0 :                 rInf.GetOut().DrawTextArray( aPos, *pStr, pKernArray,
    1581 [ #  # ][ #  # ]:          0 :                                              rInf.GetIdx() ? 1 : 0, 1 );
    1582                 :            :         }
    1583                 :            :         else
    1584                 :            :         {
    1585                 :            :             xub_Unicode nCh;
    1586                 :            : 
    1587                 :            :             // In case of Pair Kerning the printer influence on the positioning
    1588                 :            :             // grows
    1589                 :      26422 :             sal_uInt16 nMul = 3;
    1590                 :            : 
    1591 [ +  - ][ +  + ]:      26422 :             if ( pPrtFont->GetKerning() )
    1592                 :      26198 :                 nMul = 1;
    1593                 :            : 
    1594                 :      26422 :             const sal_uInt16 nDiv = nMul+1;
    1595                 :            : 
    1596                 :            :             // nSpaceSum contains the sum of the intermediate space distributed
    1597                 :            :             // among Spaces by the Justification.
    1598                 :            :             // The Spaces themselves will be positioned in the middle of the
    1599                 :            :             // intermediate space, hence the nSpace/2.
    1600                 :            :             // In case of word-by-word underlining they have to be positioned
    1601                 :            :             // at the beginning of the intermediate space, so that the space
    1602                 :            :             // is not underlined.
    1603                 :            :             // A Space at the beginning or end of the text must be positioned
    1604                 :            :             // before (resp. after) the whole intermediate space, otherwise
    1605                 :            :             // the underline/strike-through would have gaps.
    1606                 :      26422 :             long nSpaceSum = 0;
    1607                 :            :             // in word line mode and for Arabic, we disable the half space trick:
    1608 [ +  - ][ +  + ]:      26422 :             const long nHalfSpace = pPrtFont->IsWordLineMode() || bNoHalfSpace ? 0 : nSpaceAdd / 2;
                 [ +  - ]
    1609                 :      26422 :             const long nOtherHalf = nSpaceAdd - nHalfSpace;
    1610 [ -  + ][ #  # ]:      26422 :             if ( nSpaceAdd && ( cChPrev == CH_BLANK ) )
    1611                 :          0 :                 nSpaceSum = nHalfSpace;
    1612         [ +  + ]:    1424710 :             for ( xub_StrLen i=1; i<nCnt; ++i,nKernSum += rInf.GetKern() )
    1613                 :            :             {
    1614                 :    1398288 :                 nCh = rInf.GetText().GetChar( rInf.GetIdx() + i );
    1615                 :            : 
    1616                 :            :                 OSL_ENSURE( pScrArray, "Where is the screen array?" );
    1617                 :            :                 long nScr;
    1618                 :    1398288 :                 nScr = pScrArray[ i ] - pScrArray[ i - 1 ];
    1619                 :            : 
    1620                 :            :                 // If there is an (ex-)Space before us, position optimally,
    1621                 :            :                 // i.e., our right margin to the 100% printer position;
    1622                 :            :                 // if we _are_ an ex-Space, position us left-aligned to the
    1623                 :            :                 // printer position.
    1624         [ +  + ]:    1398288 :                 if ( nCh == CH_BLANK )
    1625                 :            :                 {
    1626                 :     134217 :                     nScrPos = pKernArray[i-1] + nScr;
    1627                 :            : 
    1628         [ +  + ]:     134217 :                     if ( cChPrev == CH_BLANK )
    1629                 :         22 :                         nSpaceSum += nOtherHalf;
    1630         [ +  + ]:     134217 :                     if ( i + 1 == nCnt )
    1631                 :      12269 :                         nSpaceSum += nSpaceAdd;
    1632                 :            :                     else
    1633                 :     121948 :                         nSpaceSum += nHalfSpace;
    1634                 :            :                 }
    1635                 :            :                 else
    1636                 :            :                 {
    1637         [ +  + ]:    1264071 :                     if ( cChPrev == CH_BLANK )
    1638                 :            :                     {
    1639                 :     122873 :                         nScrPos = pKernArray[i-1] + nScr;
    1640                 :            :                         // no Pixel is lost:
    1641                 :     122873 :                         nSpaceSum += nOtherHalf;
    1642                 :            :                     }
    1643         [ +  + ]:    1141198 :                     else if ( cChPrev == '-' )
    1644                 :       9136 :                         nScrPos = pKernArray[i-1] + nScr;
    1645                 :            :                     else
    1646                 :            :                     {
    1647                 :    1132062 :                         nScrPos += nScr;
    1648                 :    1132062 :                         nScrPos = ( nMul * nScrPos + pKernArray[i] ) / nDiv;
    1649                 :            :                     }
    1650                 :            :                 }
    1651                 :    1398288 :                 cChPrev = nCh;
    1652                 :    1398288 :                 pKernArray[i-1] = nScrPos - nScr + nKernSum + nSpaceSum;
    1653                 :            :                 // In word line mode and for Arabic, we disabled the half space trick. If a portion
    1654                 :            :                 // ends with a blank, the full nSpaceAdd value has been added to the character in
    1655                 :            :                 // front of the blank. This leads to painting artifacts, therefore we remove the
    1656                 :            :                 // nSpaceAdd value again:
    1657 [ +  - ][ +  - ]:    1398288 :                 if ( (bNoHalfSpace || pPrtFont->IsWordLineMode()) && i+1 == nCnt && nCh == CH_BLANK )
         [ +  + ][ +  + ]
         [ -  + ][ -  + ]
    1658                 :          0 :                     pKernArray[i-1] = pKernArray[i-1] - nSpaceAdd;
    1659                 :            :             }
    1660                 :            : 
    1661                 :            :             // the layout engine requires the total width of the output
    1662                 :      26422 :             pKernArray[ rInf.GetLen() - 1 ] += nKernSum + nSpaceSum;
    1663                 :            : 
    1664         [ -  + ]:      26422 :             if( rInf.GetGreyWave() )
    1665                 :            :             {
    1666         [ #  # ]:          0 :                 if( rInf.GetLen() )
    1667                 :            :                 {
    1668                 :          0 :                     long nHght = rInf.GetOut().LogicToPixel(
    1669   [ #  #  #  # ]:          0 :                                     pPrtFont->GetSize() ).Height();
    1670         [ #  # ]:          0 :                     if( WRONG_SHOW_MIN < nHght )
    1671                 :            :                     {
    1672         [ #  # ]:          0 :                         if ( rInf.GetOut().GetConnectMetaFile() )
    1673         [ #  # ]:          0 :                             rInf.GetOut().Push();
    1674                 :            : 
    1675                 :            :                         sal_uInt16 nWave =
    1676                 :            :                             WRONG_SHOW_MEDIUM < nHght ? WAVE_NORMAL :
    1677                 :            :                             ( WRONG_SHOW_SMALL < nHght ? WAVE_SMALL :
    1678 [ #  # ][ #  # ]:          0 :                             WAVE_FLAT );
    1679                 :          0 :                         Color aCol( rInf.GetOut().GetLineColor() );
    1680                 :          0 :                         sal_Bool bColSave = aCol != *pWaveCol;
    1681         [ #  # ]:          0 :                         if ( bColSave )
    1682         [ #  # ]:          0 :                             rInf.GetOut().SetLineColor( *pWaveCol );
    1683                 :            : 
    1684                 :          0 :                         Point aEnd;
    1685                 :          0 :                         long nKernVal = pKernArray[ sal_uInt16( rInf.GetLen() - 1 ) ];
    1686                 :            : 
    1687                 :            :                         sal_uInt16 nDir = bBidiPor ?
    1688                 :            :                                         1800 :
    1689                 :            :                                         UnMapDirection(
    1690         [ #  # ]:          0 :                                             GetFont()->GetOrientation(),
    1691 [ #  # ][ #  # ]:          0 :                                             bSwitchH2V );
    1692                 :            : 
    1693   [ #  #  #  #  :          0 :                         switch ( nDir )
                      # ]
    1694                 :            :                         {
    1695                 :            :                         case 0 :
    1696                 :          0 :                             aEnd.X() = rInf.GetPos().X() + nKernVal;
    1697                 :          0 :                             aEnd.Y() = rInf.GetPos().Y();
    1698                 :          0 :                             break;
    1699                 :            :                         case 900 :
    1700                 :          0 :                             aEnd.X() = rInf.GetPos().X();
    1701                 :          0 :                             aEnd.Y() = rInf.GetPos().Y() - nKernVal;
    1702                 :          0 :                             break;
    1703                 :            :                         case 1800 :
    1704                 :          0 :                             aEnd.X() = rInf.GetPos().X() - nKernVal;
    1705                 :          0 :                             aEnd.Y() = rInf.GetPos().Y();
    1706                 :          0 :                             break;
    1707                 :            :                         case 2700 :
    1708                 :          0 :                             aEnd.X() = rInf.GetPos().X();
    1709                 :          0 :                             aEnd.Y() = rInf.GetPos().Y() + nKernVal;
    1710                 :          0 :                             break;
    1711                 :            :                         }
    1712                 :            : 
    1713                 :          0 :                         Point aCurrPos( rInf.GetPos() );
    1714                 :            : 
    1715         [ #  # ]:          0 :                         if ( bSwitchL2R )
    1716                 :            :                         {
    1717         [ #  # ]:          0 :                             rInf.GetFrm()->SwitchLTRtoRTL( aCurrPos );
    1718         [ #  # ]:          0 :                             rInf.GetFrm()->SwitchLTRtoRTL( aEnd );
    1719                 :            :                         }
    1720                 :            : 
    1721         [ #  # ]:          0 :                         if ( bSwitchH2V )
    1722                 :            :                         {
    1723         [ #  # ]:          0 :                             rInf.GetFrm()->SwitchHorizontalToVertical( aCurrPos );
    1724         [ #  # ]:          0 :                             rInf.GetFrm()->SwitchHorizontalToVertical( aEnd );
    1725                 :            :                         }
    1726         [ #  # ]:          0 :                         rInf.GetOut().DrawWaveLine( aCurrPos, aEnd, nWave );
    1727                 :            : 
    1728         [ #  # ]:          0 :                         if ( bColSave )
    1729         [ #  # ]:          0 :                             rInf.GetOut().SetLineColor( aCol );
    1730                 :            : 
    1731         [ #  # ]:          0 :                         if ( rInf.GetOut().GetConnectMetaFile() )
    1732         [ #  # ]:          0 :                             rInf.GetOut().Pop();
    1733                 :            :                     }
    1734                 :            :                 }
    1735                 :            :             }
    1736 [ +  + ][ +  - ]:      26422 :             else if( !bSymbol && rInf.GetLen() )
                 [ +  + ]
    1737                 :            :             {
    1738                 :            :                 // anything to do?
    1739 [ +  + ][ +  + ]:      26408 :                 if (rInf.GetWrong() || rInf.GetGrammarCheck() || rInf.GetSmartTags())
         [ -  + ][ +  + ]
    1740                 :            :                 {
    1741                 :      22705 :                     CalcLinePosData aCalcLinePosData(rInf, *GetFont(),
    1742                 :            :                             nCnt, bSwitchH2V, bSwitchL2R,
    1743                 :      22705 :                             nHalfSpace, pKernArray, bBidiPor);
    1744                 :            : 
    1745         [ +  - ]:      22705 :                     SwForbidden aForbidden;
    1746                 :            :                     // draw line for smart tag data
    1747         [ +  - ]:      22705 :                     lcl_DrawLineForWrongListData( aForbidden, rInf, rInf.GetSmartTags(), aCalcLinePosData, Size() );
    1748                 :            :                     // draw wave line for spell check errors
    1749                 :            :                     // draw them BEFORE the grammar check lines to 'override' the latter in case of conflict.
    1750                 :            :                     // reason: some grammar errors can only be found if spelling errors are fixed,
    1751                 :            :                     // therefore we don't want the user to miss a spelling error.
    1752 [ +  - ][ +  - ]:      22705 :                     lcl_DrawLineForWrongListData( aForbidden, rInf, rInf.GetWrong(), aCalcLinePosData, pPrtFont->GetSize() );
    1753                 :            :                     // draw wave line for grammar check errors
    1754 [ +  - ][ +  - ]:      22705 :                     lcl_DrawLineForWrongListData( aForbidden, rInf, rInf.GetGrammarCheck(), aCalcLinePosData, pPrtFont->GetSize() );
    1755                 :            :                 }
    1756                 :            :             }
    1757                 :            : 
    1758                 :      26422 :             xub_StrLen nOffs = 0;
    1759                 :      26422 :             xub_StrLen nLen = rInf.GetLen();
    1760                 :            : 
    1761         [ +  - ]:      26422 :             if( nOffs < nLen )
    1762                 :            :             {
    1763                 :            :                 // If we paint bullets instead of spaces, we use a copy of
    1764                 :            :                 // the paragraph string. For the layout engine, the copy
    1765                 :            :                 // of the string has to be an environment of the range which
    1766                 :            :                 // is painted
    1767                 :            :                 xub_StrLen nTmpIdx = bBullet ?
    1768                 :          0 :                                               ( rInf.GetIdx() ? 1 : 0 ) :
    1769   [ -  +  #  # ]:      26422 :                                               rInf.GetIdx();
    1770                 :            : 
    1771         [ -  + ]:      26422 :                 if ( bSwitchL2R )
    1772         [ #  # ]:          0 :                     rInf.GetFrm()->SwitchLTRtoRTL( aPos );
    1773                 :            : 
    1774         [ -  + ]:      26422 :                 if ( bSwitchH2V )
    1775         [ #  # ]:          0 :                     rInf.GetFrm()->SwitchHorizontalToVertical( aPos );
    1776                 :            : 
    1777                 :      26422 :                 rInf.GetOut().DrawTextArray( aPos, *pStr, pKernArray + nOffs,
    1778         [ +  - ]:      26422 :                                              nTmpIdx + nOffs , nLen - nOffs );
    1779                 :            :             }
    1780                 :            :         }
    1781         [ +  - ]:      26422 :         delete[] pScrArray;
    1782 [ +  - ][ +  - ]:      26445 :         delete[] pKernArray;
    1783                 :            :     }
    1784                 :            : }
    1785                 :            : 
    1786                 :            : 
    1787                 :            : // optimization disabled for DrawText()
    1788                 :            : #ifdef _MSC_VER
    1789                 :            : #pragma optimize("",on)
    1790                 :            : #endif
    1791                 :            : 
    1792                 :            : 
    1793                 :            : /*************************************************************************
    1794                 :            :  *
    1795                 :            :  *  Size SwFntObj::GetTextSize( const OutputDevice *pOut, const String &rTxt,
    1796                 :            :  *           const sal_uInt16 nIdx, const sal_uInt16 nLen, const short nKern = 0 );
    1797                 :            :  *
    1798                 :            :  *  determine the TextSize (of the printer)
    1799                 :            :  *
    1800                 :            :  *************************************************************************/
    1801                 :            : 
    1802                 :      54588 : Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf )
    1803                 :            : {
    1804                 :      54588 :     Size aTxtSize;
    1805                 :      54588 :     const xub_StrLen nLn = ( STRING_LEN != rInf.GetLen() ) ? rInf.GetLen() :
    1806         [ +  - ]:      54588 :                            rInf.GetText().Len();
    1807                 :            : 
    1808                 :            :     // be sure to have the correct layout mode at the printer
    1809         [ +  + ]:      54588 :     if ( pPrinter )
    1810                 :            :     {
    1811                 :      54524 :         pPrinter->SetLayoutMode( rInf.GetOut().GetLayoutMode() );
    1812                 :      54524 :         pPrinter->SetDigitLanguage( rInf.GetOut().GetDigitLanguage() );
    1813                 :            :     }
    1814                 :            : 
    1815 [ +  + ][ +  - ]:     107056 :     if ( rInf.GetFrm() && nLn && rInf.SnapToGrid() && rInf.GetFont() &&
                 [ +  + ]
           [ +  -  +  + ]
                 [ +  + ]
    1816                 :      52468 :          SW_CJK == rInf.GetFont()->GetActual() )
    1817                 :            :     {
    1818 [ +  - ][ -  + ]:          3 :         GETGRID( rInf.GetFrm()->FindPageFrm() )
         [ #  # ][ -  + ]
    1819 [ -  + ][ #  # ]:          3 :         if ( pGrid && GRID_LINES_CHARS == pGrid->GetGridType() && pGrid->IsSnapToChars() )
         [ #  # ][ -  + ]
    1820                 :            :         {
    1821                 :          0 :             const SwDoc* pDoc = rInf.GetShell()->GetDoc();
    1822         [ #  # ]:          0 :             const sal_uInt16 nGridWidth = GETGRIDWIDTH(pGrid, pDoc);
    1823                 :            : 
    1824                 :            :             OutputDevice* pOutDev;
    1825                 :            : 
    1826         [ #  # ]:          0 :             if ( pPrinter )
    1827                 :            :             {
    1828         [ #  # ]:          0 :                 if( !pPrtFont->IsSameInstance( pPrinter->GetFont() ) )
    1829                 :          0 :                     pPrinter->SetFont(*pPrtFont);
    1830                 :          0 :                 pOutDev = pPrinter;
    1831                 :            :             }
    1832                 :            :             else
    1833                 :          0 :                 pOutDev = rInf.GetpOut();
    1834                 :            : 
    1835                 :          0 :             aTxtSize.Width() =
    1836                 :          0 :                     pOutDev->GetTextWidth( rInf.GetText(), rInf.GetIdx(), nLn );
    1837                 :            : 
    1838                 :            :             OSL_ENSURE( !rInf.GetShell() ||
    1839                 :            :                     ( USHRT_MAX != GetGuessedLeading() && USHRT_MAX != GetExtLeading() ),
    1840                 :            :                 "Leading values should be already calculated" );
    1841                 :          0 :             aTxtSize.Height() = pOutDev->GetTextHeight() +
    1842                 :          0 :                                 GetFontLeading( rInf.GetShell(), rInf.GetOut() );
    1843                 :            : 
    1844                 :          0 :             long nWidthPerChar = aTxtSize.Width() / nLn;
    1845                 :            : 
    1846                 :            :             const sal_uLong i = nWidthPerChar ?
    1847                 :            :                             ( nWidthPerChar - 1 ) / nGridWidth + 1:
    1848         [ #  # ]:          0 :                             1;
    1849                 :            : 
    1850                 :          0 :             aTxtSize.Width() = i * nGridWidth * nLn;
    1851                 :          0 :             rInf.SetKanaDiff( 0 );
    1852                 :          0 :             return aTxtSize;
    1853                 :            :         }
    1854                 :            :     }
    1855                 :            : 
    1856                 :            :     //for textgrid refactor
    1857 [ +  + ][ +  - ]:     107056 :     if ( rInf.GetFrm() && nLn && rInf.SnapToGrid() && rInf.GetFont() &&
                 [ +  + ]
           [ +  -  +  + ]
                 [ +  + ]
    1858                 :      52468 :          SW_CJK == rInf.GetFont()->GetActual() )
    1859                 :            :     {
    1860 [ +  - ][ -  + ]:          3 :         GETGRID( rInf.GetFrm()->FindPageFrm() )
         [ #  # ][ -  + ]
    1861 [ -  + ][ #  # ]:          3 :         if ( pGrid && GRID_LINES_CHARS == pGrid->GetGridType() && !pGrid->IsSnapToChars() )
         [ #  # ][ -  + ]
    1862                 :            :         {
    1863                 :          0 :             const sal_uInt16 nDefaultFontHeight = GetDefaultFontHeight( rInf );
    1864                 :            : 
    1865                 :          0 :             const SwDoc* pDoc = rInf.GetShell()->GetDoc();
    1866         [ #  # ]:          0 :             long nGridWidthAdd = GETGRIDWIDTH(pGrid, pDoc);
    1867         [ #  # ]:          0 :             if( SW_LATIN == rInf.GetFont()->GetActual() )
    1868                 :          0 :                 nGridWidthAdd = ( nGridWidthAdd - nDefaultFontHeight ) / 2;
    1869                 :            :             else
    1870                 :          0 :                 nGridWidthAdd = nGridWidthAdd - nDefaultFontHeight;
    1871                 :            :             OutputDevice* pOutDev;
    1872         [ #  # ]:          0 :             if ( pPrinter )
    1873                 :            :             {
    1874         [ #  # ]:          0 :                 if( !pPrtFont->IsSameInstance( pPrinter->GetFont() ) )
    1875                 :          0 :                     pPrinter->SetFont(*pPrtFont);
    1876                 :          0 :                 pOutDev = pPrinter;
    1877                 :            :             }
    1878                 :            :             else
    1879                 :          0 :                 pOutDev = rInf.GetpOut();
    1880                 :          0 :             aTxtSize.Width() = pOutDev->GetTextWidth( rInf.GetText(), rInf.GetIdx(), nLn );
    1881                 :          0 :             aTxtSize.Height() = pOutDev->GetTextHeight() +
    1882                 :          0 :                                 GetFontLeading( rInf.GetShell(), rInf.GetOut() );
    1883                 :          0 :             aTxtSize.Width() += (nLn) * long( nGridWidthAdd );
    1884                 :            :             //if ( rInf.GetKern() && nLn )
    1885                 :            :             //    aTxtSize.Width() += ( nLn ) * long( rInf.GetKern() );
    1886                 :            : 
    1887                 :          0 :             rInf.SetKanaDiff( 0 );
    1888                 :          0 :             return aTxtSize;
    1889                 :            :         }
    1890                 :            :     }
    1891                 :            : 
    1892                 :      54588 :     const sal_Bool bCompress = rInf.GetKanaComp() && nLn &&
    1893                 :          0 :                            rInf.GetFont() &&
    1894                 :          0 :                            SW_CJK == rInf.GetFont()->GetActual() &&
    1895                 :          0 :                            rInf.GetScriptInfo() &&
    1896                 :          0 :                            rInf.GetScriptInfo()->CountCompChg() &&
    1897   [ #  #  #  #  :      54588 :                            lcl_IsMonoSpaceFont( rInf.GetOut() );
          #  #  #  #  #  
              # ][ #  # ]
                 [ -  + ]
    1898                 :            : 
    1899                 :            :     OSL_ENSURE( !bCompress || ( rInf.GetScriptInfo() && rInf.GetScriptInfo()->
    1900                 :            :             CountCompChg()), "Compression without info" );
    1901                 :            : 
    1902                 :            :     // This is the part used e.g., for cursor travelling
    1903                 :            :     // See condition for DrawText or DrawTextArray (bDirectPrint)
    1904 [ +  + ][ +  + ]:      54588 :     if ( pPrinter && pPrinter != rInf.GetpOut() )
                 [ +  + ]
    1905                 :            :     {
    1906         [ -  + ]:       1264 :         if( !pPrtFont->IsSameInstance( pPrinter->GetFont() ) )
    1907                 :          0 :             pPrinter->SetFont(*pPrtFont);
    1908                 :       2528 :         aTxtSize.Width() = pPrinter->GetTextWidth( rInf.GetText(),
    1909                 :       2528 :                                                    rInf.GetIdx(), nLn );
    1910                 :       1264 :         aTxtSize.Height() = pPrinter->GetTextHeight();
    1911                 :       1264 :         sal_Int32 *pKernArray = new sal_Int32[nLn];
    1912                 :       1264 :         CreateScrFont( *rInf.GetShell(), rInf.GetOut() );
    1913         [ -  + ]:       1264 :         if( !GetScrFont()->IsSameInstance( rInf.GetOut().GetFont() ) )
    1914                 :          0 :             rInf.GetOut().SetFont( *pScrFont );
    1915                 :            :         long nScrPos;
    1916                 :            : 
    1917                 :       1264 :         pPrinter->GetTextArray( rInf.GetText(), pKernArray, rInf.GetIdx(),nLn );
    1918         [ -  + ]:       1264 :         if( bCompress )
    1919                 :            :             rInf.SetKanaDiff( rInf.GetScriptInfo()->Compress( pKernArray,
    1920                 :          0 :                 rInf.GetIdx(), nLn, rInf.GetKanaComp(),
    1921                 :          0 :                 (sal_uInt16)aFont.GetSize().Height() ) );
    1922                 :            :         else
    1923                 :       1264 :             rInf.SetKanaDiff( 0 );
    1924                 :            : 
    1925         [ -  + ]:       1264 :         if ( rInf.GetKanaDiff() )
    1926                 :          0 :             nScrPos = pKernArray[ nLn - 1 ];
    1927                 :            :         else
    1928                 :            :         {
    1929                 :       1264 :             sal_Int32* pScrArray = new sal_Int32[ rInf.GetLen() ];
    1930                 :       1264 :             rInf.GetOut().GetTextArray( rInf.GetText(), pScrArray,
    1931                 :       2528 :                                         rInf.GetIdx(), rInf.GetLen() );
    1932                 :       1264 :             nScrPos = pScrArray[ 0 ];
    1933                 :       1264 :             xub_StrLen nCnt = rInf.GetText().Len();
    1934         [ -  + ]:       1264 :             if ( nCnt < rInf.GetIdx() )
    1935                 :          0 :                 nCnt=0;
    1936                 :            :             else
    1937                 :       1264 :                 nCnt = nCnt - rInf.GetIdx();
    1938                 :       1264 :             nCnt = Min (nCnt, nLn);
    1939                 :       1264 :             xub_Unicode nChPrev = rInf.GetText().GetChar( rInf.GetIdx() );
    1940                 :            : 
    1941                 :            :             xub_Unicode nCh;
    1942                 :            : 
    1943                 :            :             // In case of Pair Kerning the printer influence on the positioning
    1944                 :            :             // grows
    1945                 :       1264 :             sal_uInt16 nMul = 3;
    1946         [ +  - ]:       1264 :             if ( pPrtFont->GetKerning() )
    1947                 :       1264 :                 nMul = 1;
    1948                 :       1264 :             const sal_uInt16 nDiv = nMul+1;
    1949         [ +  + ]:      10713 :             for( xub_StrLen i=1; i<nCnt; i++ )
    1950                 :            :             {
    1951                 :       9449 :                 nCh = rInf.GetText().GetChar( rInf.GetIdx() + i );
    1952                 :            :                 long nScr;
    1953                 :       9449 :                 nScr = pScrArray[ i ] - pScrArray[ i - 1 ];
    1954         [ +  + ]:       9449 :                 if ( nCh == CH_BLANK )
    1955                 :       1158 :                     nScrPos = pKernArray[i-1]+nScr;
    1956                 :            :                 else
    1957                 :            :                 {
    1958 [ +  + ][ +  + ]:       8291 :                     if ( nChPrev == CH_BLANK || nChPrev == '-' )
    1959                 :       1062 :                         nScrPos = pKernArray[i-1]+nScr;
    1960                 :            :                     else
    1961                 :            :                     {
    1962                 :       7229 :                         nScrPos += nScr;
    1963                 :       7229 :                         nScrPos = ( nMul * nScrPos + pKernArray[i] ) / nDiv;
    1964                 :            :                     }
    1965                 :            :                 }
    1966                 :       9449 :                 nChPrev = nCh;
    1967                 :       9449 :                 pKernArray[i-1] = nScrPos - nScr;
    1968                 :            :             }
    1969         [ +  - ]:       1264 :             delete[] pScrArray;
    1970                 :            :         }
    1971                 :            : 
    1972         [ +  - ]:       1264 :         delete[] pKernArray;
    1973                 :       1264 :         aTxtSize.Width() = nScrPos;
    1974                 :            :     }
    1975                 :            :     else
    1976                 :            :     {
    1977         [ -  + ]:      53324 :         if( !pPrtFont->IsSameInstance( rInf.GetOut().GetFont() ) )
    1978                 :          0 :             rInf.GetOut().SetFont( *pPrtFont );
    1979         [ -  + ]:      53324 :         if( bCompress )
    1980                 :            :         {
    1981                 :          0 :             sal_Int32 *pKernArray = new sal_Int32[nLn];
    1982                 :          0 :             rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray,
    1983                 :          0 :                                         rInf.GetIdx(), nLn );
    1984                 :            :             rInf.SetKanaDiff( rInf.GetScriptInfo()->Compress( pKernArray,
    1985                 :          0 :                 rInf.GetIdx(), nLn, rInf.GetKanaComp(),
    1986                 :          0 :                 (sal_uInt16) aFont.GetSize().Height() ) );
    1987                 :          0 :             aTxtSize.Width() = pKernArray[ nLn - 1 ];
    1988         [ #  # ]:          0 :             delete[] pKernArray;
    1989                 :            :         }
    1990                 :            :         else
    1991                 :            :         {
    1992                 :     106648 :             aTxtSize.Width() = rInf.GetOut().GetTextWidth( rInf.GetText(),
    1993                 :     106648 :                                                            rInf.GetIdx(), nLn );
    1994                 :      53324 :             rInf.SetKanaDiff( 0 );
    1995                 :            :         }
    1996                 :            : 
    1997                 :      53324 :         aTxtSize.Height() = rInf.GetOut().GetTextHeight();
    1998                 :            :     }
    1999                 :            : 
    2000 [ +  + ][ +  - ]:      54588 :     if ( rInf.GetKern() && nLn )
                 [ +  + ]
    2001                 :        284 :         aTxtSize.Width() += ( nLn - 1 ) * long( rInf.GetKern() );
    2002                 :            : 
    2003                 :            :     OSL_ENSURE( !rInf.GetShell() ||
    2004                 :            :             ( USHRT_MAX != GetGuessedLeading() && USHRT_MAX != GetExtLeading() ),
    2005                 :            :               "Leading values should be already calculated" );
    2006                 :      54588 :     aTxtSize.Height() += GetFontLeading( rInf.GetShell(), rInf.GetOut() );
    2007                 :      54588 :     return aTxtSize;
    2008                 :            : }
    2009                 :            : 
    2010                 :            : 
    2011                 :          0 : xub_StrLen SwFntObj::GetCrsrOfst( SwDrawTextInfo &rInf )
    2012                 :            : {
    2013                 :          0 :     long nSpaceAdd =       rInf.GetSpace() / SPACING_PRECISION_FACTOR;
    2014                 :          0 :     const long nSperren = -rInf.GetSperren() / SPACING_PRECISION_FACTOR;
    2015                 :          0 :     long nKern = rInf.GetKern();
    2016                 :            : 
    2017         [ #  # ]:          0 :     if( 0 != nSperren )
    2018                 :          0 :         nKern -= nSperren;
    2019                 :            : 
    2020         [ #  # ]:          0 :     sal_Int32 *pKernArray = new sal_Int32[ rInf.GetLen() ];
    2021                 :            : 
    2022                 :            :     // be sure to have the correct layout mode at the printer
    2023         [ #  # ]:          0 :     if ( pPrinter )
    2024                 :            :     {
    2025         [ #  # ]:          0 :         pPrinter->SetLayoutMode( rInf.GetOut().GetLayoutMode() );
    2026         [ #  # ]:          0 :         pPrinter->SetDigitLanguage( rInf.GetOut().GetDigitLanguage() );
    2027                 :          0 :         pPrinter->GetTextArray( rInf.GetText(), pKernArray,
    2028         [ #  # ]:          0 :                                 rInf.GetIdx(), rInf.GetLen() );
    2029                 :            :     }
    2030                 :            :     else
    2031                 :          0 :         rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray,
    2032         [ #  # ]:          0 :                                     rInf.GetIdx(), rInf.GetLen() );
    2033                 :            : 
    2034                 :          0 :     const SwScriptInfo* pSI = rInf.GetScriptInfo();
    2035 [ #  # ][ #  # ]:          0 :     if ( rInf.GetFont() && rInf.GetLen() )
                 [ #  # ]
    2036                 :            :     {
    2037                 :          0 :         const sal_uInt8 nActual = rInf.GetFont()->GetActual();
    2038                 :            : 
    2039                 :            :         // Kana Compression
    2040         [ #  # ]:          0 :         if ( SW_CJK == nActual && rInf.GetKanaComp() &&
           [ #  #  #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2041                 :          0 :              pSI && pSI->CountCompChg() &&
    2042         [ #  # ]:          0 :              lcl_IsMonoSpaceFont( rInf.GetOut() ) )
    2043                 :            :         {
    2044                 :          0 :             pSI->Compress( pKernArray, rInf.GetIdx(), rInf.GetLen(),
    2045                 :          0 :                            rInf.GetKanaComp(),
    2046 [ #  # ][ #  # ]:          0 :                            (sal_uInt16) aFont.GetSize().Height() );
    2047                 :            :         }
    2048                 :            : 
    2049                 :            :         // Asian Justification
    2050         [ #  # ]:          0 :         if ( SW_CJK == rInf.GetFont()->GetActual() )
    2051                 :            :         {
    2052                 :          0 :             LanguageType aLang = rInf.GetFont()->GetLanguage( SW_CJK );
    2053                 :            : 
    2054 [ #  # ][ #  # ]:          0 :             if (MsLangId::isKorean(aLang))
    2055                 :            :             {
    2056                 :          0 :                 long nSpaceSum = nSpaceAdd;
    2057         [ #  # ]:          0 :                 for ( sal_uInt16 nI = 0; nI < rInf.GetLen(); ++nI )
    2058                 :            :                 {
    2059                 :          0 :                     pKernArray[ nI ] += nSpaceSum;
    2060                 :          0 :                     nSpaceSum += nSpaceAdd;
    2061                 :            :                 }
    2062                 :            : 
    2063                 :          0 :                 nSpaceAdd = 0;
    2064                 :            :             }
    2065                 :            : 
    2066                 :            :         }
    2067                 :            : 
    2068                 :            :         // Kashida Justification
    2069 [ #  # ][ #  # ]:          0 :         if ( SW_CTL == nActual && rInf.GetSpace() )
                 [ #  # ]
    2070                 :            :         {
    2071 [ #  # ][ #  # ]:          0 :             if ( SwScriptInfo::IsArabicText( rInf.GetText(), rInf.GetIdx(), rInf.GetLen() ) )
                 [ #  # ]
    2072                 :            :             {
    2073 [ #  # ][ #  # ]:          0 :                 if ( pSI && pSI->CountKashida() &&
         [ #  # ][ #  # ]
    2074                 :          0 :                     pSI->KashidaJustify( pKernArray, 0, rInf.GetIdx(), rInf.GetLen(),
    2075         [ #  # ]:          0 :                                          nSpaceAdd ) != STRING_LEN )
    2076                 :          0 :                     nSpaceAdd = 0;
    2077                 :            :             }
    2078                 :            :         }
    2079                 :            : 
    2080                 :            :         // Thai Justification
    2081 [ #  # ][ #  # ]:          0 :         if ( SW_CTL == nActual && nSpaceAdd )
    2082                 :            :         {
    2083                 :          0 :             LanguageType aLang = rInf.GetFont()->GetLanguage( SW_CTL );
    2084                 :            : 
    2085         [ #  # ]:          0 :             if ( LANGUAGE_THAI == aLang )
    2086                 :            :             {
    2087                 :          0 :                 SwScriptInfo::ThaiJustify( rInf.GetText(), pKernArray, 0,
    2088                 :          0 :                                            rInf.GetIdx(), rInf.GetLen(),
    2089                 :          0 :                                            rInf.GetNumberOfBlanks(),
    2090 [ #  # ][ #  # ]:          0 :                                            rInf.GetSpace() );
    2091                 :            : 
    2092                 :            :                 // adding space to blanks is already done
    2093                 :          0 :                 nSpaceAdd = 0;
    2094                 :            :             }
    2095                 :            :         }
    2096                 :            :     }
    2097                 :            : 
    2098                 :          0 :     long nLeft = 0;
    2099                 :          0 :     long nRight = 0;
    2100                 :          0 :     xub_StrLen nCnt = 0;
    2101                 :          0 :     long nSpaceSum = 0;
    2102                 :          0 :     long nKernSum = 0;
    2103                 :            : 
    2104 [ #  # ][ #  # ]:          0 :     if ( rInf.GetFrm() && rInf.GetLen() && rInf.SnapToGrid() &&
           [ #  #  #  #  
           #  # ][ #  # ]
    2105                 :          0 :          rInf.GetFont() && SW_CJK == rInf.GetFont()->GetActual() )
    2106                 :            :     {
    2107 [ #  # ][ #  # ]:          0 :         GETGRID( rInf.GetFrm()->FindPageFrm() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2108 [ #  # ][ #  # ]:          0 :         if ( pGrid && GRID_LINES_CHARS == pGrid->GetGridType() && pGrid->IsSnapToChars() )
         [ #  # ][ #  # ]
    2109                 :            :         {
    2110                 :          0 :             const SwDoc* pDoc = rInf.GetShell()->GetDoc();
    2111 [ #  # ][ #  # ]:          0 :             const sal_uInt16 nGridWidth = GETGRIDWIDTH(pGrid, pDoc);
    2112                 :            : 
    2113                 :          0 :             long nWidthPerChar = pKernArray[ rInf.GetLen() - 1 ] / rInf.GetLen();
    2114                 :            : 
    2115                 :            :             sal_uLong i = nWidthPerChar ?
    2116                 :            :                       ( nWidthPerChar - 1 ) / nGridWidth + 1:
    2117         [ #  # ]:          0 :                       1;
    2118                 :            : 
    2119                 :          0 :             nWidthPerChar = i * nGridWidth;
    2120                 :            : 
    2121                 :          0 :             nCnt = (sal_uInt16)(rInf.GetOfst() / nWidthPerChar);
    2122         [ #  # ]:          0 :             if ( 2 * ( rInf.GetOfst() - nCnt * nWidthPerChar ) > nWidthPerChar )
    2123                 :          0 :                 ++nCnt;
    2124                 :            : 
    2125         [ #  # ]:          0 :             delete[] pKernArray;
    2126                 :          0 :             return nCnt;
    2127                 :            :         }
    2128                 :            :     }
    2129                 :            : 
    2130                 :            :     //for textgrid refactor
    2131 [ #  # ][ #  # ]:          0 :     if ( rInf.GetFrm() && rInf.GetLen() && rInf.SnapToGrid() &&
           [ #  #  #  #  
           #  # ][ #  # ]
    2132                 :          0 :          rInf.GetFont() && SW_CJK == rInf.GetFont()->GetActual() )
    2133                 :            :     {
    2134 [ #  # ][ #  # ]:          0 :         GETGRID( rInf.GetFrm()->FindPageFrm() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2135 [ #  # ][ #  # ]:          0 :         if ( pGrid && GRID_LINES_CHARS == pGrid->GetGridType() && !pGrid->IsSnapToChars() )
         [ #  # ][ #  # ]
    2136                 :            :         {
    2137                 :            : 
    2138         [ #  # ]:          0 :             const sal_uInt16 nDefaultFontHeight = GetDefaultFontHeight( rInf );
    2139                 :            : 
    2140                 :          0 :             const SwDoc* pDoc = rInf.GetShell()->GetDoc();
    2141 [ #  # ][ #  # ]:          0 :             long nGridWidthAdd = GETGRIDWIDTH(pGrid, pDoc);
    2142         [ #  # ]:          0 :             if( SW_LATIN == rInf.GetFont()->GetActual() )
    2143                 :          0 :                 nGridWidthAdd = ( nGridWidthAdd - nDefaultFontHeight ) / 2;
    2144                 :            :             else
    2145                 :          0 :                 nGridWidthAdd = nGridWidthAdd - nDefaultFontHeight;
    2146                 :            : 
    2147         [ #  # ]:          0 :             for(xub_StrLen j = 0; j < rInf.GetLen(); j++)
    2148                 :            :             {
    2149                 :          0 :                 long nScr = pKernArray[ j ] + ( nSpaceAdd + nGridWidthAdd  ) * ( j + 1 );
    2150         [ #  # ]:          0 :                 if( nScr >= rInf.GetOfst())
    2151                 :            :                 {
    2152                 :          0 :                     nCnt = j;
    2153                 :          0 :                     break;
    2154                 :            :                 }
    2155                 :            :             }
    2156         [ #  # ]:          0 :             delete[] pKernArray;
    2157                 :          0 :             return nCnt;
    2158                 :            :         }
    2159                 :            :     }
    2160                 :            : 
    2161                 :          0 :     sal_uInt16 nItrMode = i18n::CharacterIteratorMode::SKIPCELL;
    2162                 :          0 :     sal_Int32 nDone = 0;
    2163                 :          0 :     LanguageType aLang = LANGUAGE_NONE;
    2164                 :          0 :     bool bSkipCharacterCells = false;
    2165                 :          0 :     xub_StrLen nIdx = rInf.GetIdx();
    2166                 :          0 :     xub_StrLen nLastIdx = nIdx;
    2167                 :          0 :     const xub_StrLen nEnd = rInf.GetIdx() + rInf.GetLen();
    2168                 :            : 
    2169                 :            :     // #i105901#
    2170                 :            :     // skip character cells for all script types
    2171 [ #  # ][ #  # ]:          0 :     if ( pBreakIt->GetBreakIter().is() )
    2172                 :            :     {
    2173                 :          0 :         aLang = rInf.GetFont()->GetLanguage();
    2174                 :          0 :         bSkipCharacterCells = true;
    2175                 :            :     }
    2176                 :            : 
    2177 [ #  # ][ #  # ]:          0 :     while ( ( nRight < long( rInf.GetOfst() ) ) && ( nIdx < nEnd ) )
                 [ #  # ]
    2178                 :            :     {
    2179 [ #  # ][ #  # ]:          0 :         if ( nSpaceAdd && CH_BLANK == rInf.GetText().GetChar( nIdx ) )
                 [ #  # ]
    2180                 :          0 :             nSpaceSum += nSpaceAdd;
    2181                 :            : 
    2182                 :            :         // go to next character (cell).
    2183                 :          0 :         nLastIdx = nIdx;
    2184                 :            : 
    2185         [ #  # ]:          0 :         if ( bSkipCharacterCells )
    2186                 :            :         {
    2187 [ #  # ][ #  # ]:          0 :             nIdx = (xub_StrLen)pBreakIt->GetBreakIter()->nextCharacters( rInf.GetText(),
    2188   [ #  #  #  # ]:          0 :                         nIdx, pBreakIt->GetLocale( aLang ), nItrMode, 1, nDone );
                 [ #  # ]
    2189         [ #  # ]:          0 :             if ( nIdx <= nLastIdx )
    2190                 :          0 :                 break;
    2191                 :            :         }
    2192                 :            :         else
    2193                 :          0 :             ++nIdx;
    2194                 :            : 
    2195                 :          0 :         nLeft = nRight;
    2196                 :          0 :         nRight = pKernArray[ nIdx - rInf.GetIdx() - 1 ] + nKernSum + nSpaceSum;
    2197                 :            : 
    2198                 :          0 :         nKernSum += nKern;
    2199                 :            :     }
    2200                 :            : 
    2201                 :            :     // step back if position is before the middle of the character
    2202                 :            :     // or if we do not want to go to the next character
    2203   [ #  #  #  #  :          0 :     if ( nIdx > rInf.GetIdx() &&
             #  #  #  # ]
                 [ #  # ]
    2204                 :          0 :          ( rInf.IsPosMatchesBounds() ||
    2205                 :          0 :            ( ( nRight > long( rInf.GetOfst() ) ) &&
    2206                 :          0 :              ( nRight - rInf.GetOfst() > rInf.GetOfst() - nLeft ) ) ) )
    2207                 :          0 :         nCnt = nLastIdx - rInf.GetIdx(); // first half
    2208                 :            :     else
    2209                 :          0 :         nCnt = nIdx - rInf.GetIdx(); // second half
    2210                 :            : 
    2211         [ #  # ]:          0 :     if ( pSI )
    2212         [ #  # ]:          0 :         rInf.SetCursorBidiLevel( pSI->DirType( nLastIdx ) );
    2213                 :            : 
    2214         [ #  # ]:          0 :     delete[] pKernArray;
    2215                 :          0 :     return nCnt;
    2216                 :            : }
    2217                 :            : 
    2218                 :            : 
    2219                 :            : /*************************************************************************
    2220                 :            : |*
    2221                 :            : |*  SwFntAccess::SwFntAccess()
    2222                 :            : |*
    2223                 :            : |*************************************************************************/
    2224                 :            : 
    2225                 :     547177 : SwFntAccess::SwFntAccess( const void* &rMagic,
    2226                 :            :                 sal_uInt16 &rIndex, const void *pOwn, ViewShell *pSh,
    2227                 :            :                 sal_Bool bCheck ) :
    2228                 :            :   SwCacheAccess( *pFntCache, rMagic, rIndex ),
    2229                 :     547177 :   pShell( pSh )
    2230                 :            : {
    2231                 :            :     // the used ctor of SwCacheAccess searches for rMagic+rIndex in the cache
    2232         [ +  + ]:     547177 :     if ( IsAvail() )
    2233                 :            :     {
    2234                 :            :         // fast case: known Font (rMagic), no need to check printer and zoom
    2235         [ +  + ]:     528873 :         if ( !bCheck )
    2236                 :     234121 :             return;
    2237                 :            : 
    2238                 :            :         // Font is known, but has to be checked
    2239                 :            :     }
    2240                 :            :     else
    2241                 :            :     {   // Font not known, must be searched
    2242                 :      18304 :         bCheck = sal_False;
    2243                 :            :     }
    2244                 :            : 
    2245                 :            : 
    2246                 :            :     {
    2247                 :     313056 :         OutputDevice* pOut = 0;
    2248                 :     313056 :         sal_uInt16 nZoom = USHRT_MAX;
    2249                 :            : 
    2250                 :            :         // Get the reference device
    2251         [ +  + ]:     313056 :         if ( pSh )
    2252                 :            :         {
    2253         [ +  - ]:     312978 :             pOut = &pSh->GetRefDev();
    2254                 :     312978 :             nZoom = pSh->GetViewOptions()->GetZoom();
    2255                 :            :         }
    2256                 :            : 
    2257                 :            :         SwFntObj *pFntObj;
    2258         [ +  + ]:     313056 :         if ( bCheck )
    2259                 :            :         {
    2260         [ +  - ]:     294752 :             pFntObj = Get();
    2261         [ +  + ]:     586681 :             if ( ( pFntObj->GetZoom( ) == nZoom ) &&
           [ +  +  +  - ]
                 [ +  + ]
    2262                 :            :                  ( pFntObj->pPrinter == pOut ) &&
    2263                 :     291929 :                    pFntObj->GetPropWidth() ==
    2264                 :     291929 :                         ((SwSubFont*)pOwn)->GetPropWidth() )
    2265                 :            :             {
    2266                 :     291929 :                 return; // result of Check: Drucker+Zoom okay.
    2267                 :            :             }
    2268                 :       2823 :             pFntObj->Unlock(); // forget this object, printer/zoom differs
    2269                 :       2823 :             pObj = NULL;
    2270                 :            :         }
    2271                 :            : 
    2272                 :            :         // Search by font comparison, quite expensive!
    2273                 :            :         // Look for same font and same printer
    2274                 :      21127 :         pFntObj = pFntCache->First();
    2275 [ +  + ][ +  - ]:      58271 :         while ( pFntObj && !( pFntObj->aFont == *(Font *)pOwn &&
         [ +  + ][ +  + ]
    2276                 :      19920 :                               pFntObj->GetZoom() == nZoom &&
    2277                 :      18885 :                               pFntObj->GetPropWidth() ==
    2278                 :      18885 :                               ((SwSubFont*)pOwn)->GetPropWidth() &&
    2279 [ +  + ][ +  + ]:      38805 :                               ( !pFntObj->pPrinter || pFntObj->pPrinter == pOut ) ) )
           [ +  +  +  + ]
    2280                 :      17224 :             pFntObj = pFntCache->Next( pFntObj );
    2281                 :            : 
    2282 [ +  + ][ +  + ]:      21127 :         if( pFntObj && pFntObj->pPrinter != pOut )
    2283                 :            :         {
    2284                 :            :             // found one without printer, let's see if there is one with
    2285                 :            :             // the same printer as well
    2286                 :       2064 :             SwFntObj *pTmpObj = pFntObj;
    2287 [ +  + ][ +  - ]:      12913 :             while( pTmpObj && !( pTmpObj->aFont == *(Font *)pOwn &&
         [ +  + ][ +  + ]
    2288                 :       2107 :                    pTmpObj->GetZoom()==nZoom && pTmpObj->pPrinter==pOut &&
    2289                 :         12 :                    pTmpObj->GetPropWidth() ==
    2290   [ +  +  +  - ]:       2119 :                         ((SwSubFont*)pOwn)->GetPropWidth() ) )
                 [ +  + ]
    2291                 :       8742 :                 pTmpObj = pFntCache->Next( pTmpObj );
    2292         [ -  + ]:       2064 :             if( pTmpObj )
    2293                 :          0 :                 pFntObj = pTmpObj;
    2294                 :            :         }
    2295                 :            : 
    2296         [ +  + ]:      21127 :         if ( !pFntObj ) // Font has not been found, create one
    2297                 :            :         {
    2298                 :            :             // Have to create new Object, hence Owner must be a SwFont, later
    2299                 :            :             // the Owner will be the "MagicNumber"
    2300                 :       2288 :             SwCacheAccess::pOwner = pOwn;
    2301         [ +  - ]:       2288 :             pFntObj = Get(); // will create via NewObj() and lock
    2302                 :            :             OSL_ENSURE(pFntObj, "No Font, no Fun.");
    2303                 :            :         }
    2304                 :            :         else  // Font has been found, so we lock it.
    2305                 :            :         {
    2306                 :      18839 :             pFntObj->Lock();
    2307         [ +  + ]:      18839 :             if (pFntObj->pPrinter != pOut) // if no printer is known by now
    2308                 :            :             {
    2309                 :            :                 OSL_ENSURE( !pFntObj->pPrinter, "SwFntAccess: Printer Changed" );
    2310         [ +  - ]:       2064 :                 pFntObj->CreatePrtFont( *pOut );
    2311                 :       2064 :                 pFntObj->pPrinter = pOut;
    2312                 :       2064 :                 pFntObj->pScrFont = NULL;
    2313                 :       2064 :                 pFntObj->nGuessedLeading = USHRT_MAX;
    2314                 :       2064 :                 pFntObj->nExtLeading = USHRT_MAX;
    2315                 :       2064 :                 pFntObj->nPrtAscent = USHRT_MAX;
    2316                 :       2064 :                 pFntObj->nPrtHeight = USHRT_MAX;
    2317                 :            :             }
    2318                 :      18839 :             pObj = pFntObj;
    2319                 :            :         }
    2320                 :            : 
    2321                 :            :         // no matter if new or found, now the Owner of the Object is a
    2322                 :            :         // MagicNumber, and will be given to the SwFont, as well as the Index
    2323                 :            :         // for later direct access
    2324                 :      21127 :         rMagic = pFntObj->GetOwner();
    2325                 :      21127 :         SwCacheAccess::pOwner = rMagic;
    2326                 :     547177 :         rIndex = pFntObj->GetCachePos();
    2327                 :            :     }
    2328                 :            : }
    2329                 :            : 
    2330                 :       2288 : SwCacheObj *SwFntAccess::NewObj( )
    2331                 :            : {
    2332                 :            :     // a new Font, a new "MagicNumber".
    2333         [ +  - ]:       2288 :     return new SwFntObj( *(SwSubFont *)pOwner, ++pMagicNo, pShell );
    2334                 :            : }
    2335                 :            : 
    2336                 :            : extern xub_StrLen lcl_CalcCaseMap( const SwFont& rFnt,
    2337                 :            :                                    const XubString& rOrigString,
    2338                 :            :                                    xub_StrLen nOfst,
    2339                 :            :                                    xub_StrLen nLen,
    2340                 :            :                                    xub_StrLen nIdx );
    2341                 :            : 
    2342                 :      42491 : xub_StrLen SwFont::GetTxtBreak( SwDrawTextInfo& rInf, long nTextWidth )
    2343                 :            : {
    2344                 :      42491 :     ChgFnt( rInf.GetShell(), rInf.GetOut() );
    2345                 :            : 
    2346                 :      42491 :     const sal_Bool bCompress = rInf.GetKanaComp() && rInf.GetLen() &&
    2347                 :          0 :                            SW_CJK == GetActual() &&
    2348                 :          0 :                            rInf.GetScriptInfo() &&
    2349                 :          0 :                            rInf.GetScriptInfo()->CountCompChg() &&
    2350 [ #  # ][ -  +  :      42491 :                            lcl_IsMonoSpaceFont( rInf.GetOut() );
          #  #  #  #  #  
                #  #  # ]
    2351                 :            : 
    2352                 :            :     OSL_ENSURE( !bCompress || ( rInf.GetScriptInfo() && rInf.GetScriptInfo()->
    2353                 :            :             CountCompChg()), "Compression without info" );
    2354                 :            : 
    2355                 :      42491 :     sal_uInt16 nTxtBreak = 0;
    2356                 :      42491 :     long nKern = 0;
    2357                 :            : 
    2358                 :      42491 :     sal_uInt16 nLn = ( rInf.GetLen() == STRING_LEN ? rInf.GetText().Len()
    2359         [ -  + ]:      42491 :                                                : rInf.GetLen() );
    2360                 :            : 
    2361 [ +  - ][ +  - ]:     120587 :     if ( rInf.GetFrm() && nLn && rInf.SnapToGrid() &&
           [ +  +  +  -  
           -  + ][ -  + ]
    2362                 :      78096 :          rInf.GetFont() && SW_CJK == rInf.GetFont()->GetActual() )
    2363                 :            :     {
    2364 [ #  # ][ #  # ]:          0 :         GETGRID( rInf.GetFrm()->FindPageFrm() )
         [ #  # ][ #  # ]
    2365 [ #  # ][ #  # ]:          0 :         if ( pGrid && GRID_LINES_CHARS == pGrid->GetGridType() && pGrid->IsSnapToChars() )
         [ #  # ][ #  # ]
    2366                 :            :         {
    2367                 :          0 :             const SwDoc* pDoc = rInf.GetShell()->GetDoc();
    2368         [ #  # ]:          0 :             const sal_uInt16 nGridWidth = GETGRIDWIDTH(pGrid, pDoc);
    2369                 :            : 
    2370                 :          0 :             sal_Int32* pKernArray = new sal_Int32[rInf.GetLen()];
    2371                 :          0 :             rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray,
    2372                 :          0 :                                         rInf.GetIdx(), rInf.GetLen() );
    2373                 :            : 
    2374                 :          0 :             long nWidthPerChar = pKernArray[ rInf.GetLen() - 1 ] / rInf.GetLen();
    2375                 :            : 
    2376                 :            :             const sal_uLong i = nWidthPerChar ?
    2377                 :            :                             ( nWidthPerChar - 1 ) / nGridWidth + 1:
    2378         [ #  # ]:          0 :                             1;
    2379                 :            : 
    2380                 :          0 :             nWidthPerChar = i * nGridWidth;
    2381                 :          0 :             long nCurrPos = nWidthPerChar;
    2382                 :            : 
    2383 [ #  # ][ #  # ]:          0 :             while( nTxtBreak < rInf.GetLen() && nTextWidth >= nCurrPos )
                 [ #  # ]
    2384                 :            :             {
    2385                 :          0 :                 nCurrPos += nWidthPerChar;
    2386                 :          0 :                 ++nTxtBreak;
    2387                 :            :             }
    2388                 :            : 
    2389         [ #  # ]:          0 :             delete[] pKernArray;
    2390                 :          0 :             return nTxtBreak + rInf.GetIdx();
    2391                 :            :         }
    2392                 :            :     }
    2393                 :            : 
    2394                 :            :     //for text grid enhancement
    2395 [ +  - ][ +  - ]:      81539 :     if ( rInf.GetFrm() && nLn && rInf.SnapToGrid() && rInf.GetFont() &&
                 [ +  + ]
           [ +  -  -  + ]
                 [ -  + ]
    2396                 :      39048 :          SW_CJK == rInf.GetFont()->GetActual() )
    2397                 :            :     {
    2398 [ #  # ][ #  # ]:          0 :         GETGRID( rInf.GetFrm()->FindPageFrm() )
         [ #  # ][ #  # ]
    2399 [ #  # ][ #  # ]:          0 :         if ( pGrid && GRID_LINES_CHARS == pGrid->GetGridType() && !pGrid->IsSnapToChars() )
         [ #  # ][ #  # ]
    2400                 :            :         {
    2401                 :          0 :             const sal_uInt16 nDefaultFontHeight = GetDefaultFontHeight( rInf );
    2402                 :            : 
    2403                 :          0 :             const SwDoc* pDoc = rInf.GetShell()->GetDoc();
    2404         [ #  # ]:          0 :             long nGridWidthAdd = GETGRIDWIDTH(pGrid, pDoc);
    2405         [ #  # ]:          0 :             if( SW_LATIN == rInf.GetFont()->GetActual() )
    2406                 :          0 :                 nGridWidthAdd = ( nGridWidthAdd - nDefaultFontHeight ) / 2 ;
    2407                 :            :             else
    2408                 :          0 :                 nGridWidthAdd = nGridWidthAdd - nDefaultFontHeight;
    2409                 :            : 
    2410                 :          0 :             sal_Int32* pKernArray = new sal_Int32[rInf.GetLen()];
    2411                 :          0 :             rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray,
    2412                 :          0 :                                             rInf.GetIdx(), rInf.GetLen() );
    2413                 :          0 :             long nCurrPos = pKernArray[nTxtBreak] + nGridWidthAdd;
    2414 [ #  # ][ #  # ]:          0 :             while( nTxtBreak < rInf.GetLen() && nTextWidth >= nCurrPos)
                 [ #  # ]
    2415                 :            :             {
    2416                 :          0 :                 nTxtBreak++;
    2417                 :          0 :                 nCurrPos = pKernArray[nTxtBreak] + nGridWidthAdd * ( nTxtBreak + 1 );
    2418                 :            :             }
    2419         [ #  # ]:          0 :             delete[] pKernArray;
    2420                 :          0 :             return nTxtBreak + rInf.GetIdx();
    2421                 :            :         }
    2422                 :            :     }
    2423                 :            : 
    2424 [ -  + ][ #  # ]:      42491 :     if( aSub[nActual].IsCapital() && nLn )
                 [ -  + ]
    2425                 :          0 :         nTxtBreak = GetCapitalBreak( rInf.GetShell(), rInf.GetpOut(),
    2426                 :          0 :         rInf.GetScriptInfo(), rInf.GetText(), nTextWidth,0, rInf.GetIdx(),nLn );
    2427                 :            :     else
    2428                 :            :     {
    2429         [ +  - ]:      42491 :         nKern = CheckKerning();
    2430                 :            : 
    2431                 :            :         const XubString* pTmpText;
    2432         [ +  - ]:      42491 :         XubString aTmpText;
    2433                 :            :         xub_StrLen nTmpIdx;
    2434                 :            :         xub_StrLen nTmpLen;
    2435                 :      42491 :         bool bTextReplaced = false;
    2436                 :            : 
    2437         [ +  + ]:      42491 :         if ( !aSub[nActual].IsCaseMap() )
    2438                 :            :         {
    2439                 :      42251 :             pTmpText = &rInf.GetText();
    2440                 :      42251 :             nTmpIdx = rInf.GetIdx();
    2441                 :      42251 :             nTmpLen = nLn;
    2442                 :            :         }
    2443                 :            :         else
    2444                 :            :         {
    2445         [ +  - ]:        240 :             const XubString aSnippet( rInf.GetText(), rInf.GetIdx(), nLn );
    2446 [ +  - ][ +  - ]:        240 :             aTmpText = aSub[nActual].CalcCaseMap( aSnippet );
                 [ +  - ]
    2447                 :        240 :             const bool bTitle = SVX_CASEMAP_TITEL == aSub[nActual].GetCaseMap() &&
    2448 [ #  # ][ #  # ]:        240 :                                 pBreakIt->GetBreakIter().is();
         [ -  + ][ #  # ]
                 [ -  + ]
    2449                 :            : 
    2450                 :            :             // Uaaaaahhhh!!! In title case mode, we would get wrong results
    2451 [ -  + ][ #  # ]:        240 :             if ( bTitle && nLn )
    2452                 :            :             {
    2453                 :            :                 // check if rInf.GetIdx() is begin of word
    2454         [ #  # ]:          0 :                 if ( !pBreakIt->GetBreakIter()->isBeginWord(
           [ #  #  #  # ]
    2455                 :          0 :                      rInf.GetText(), rInf.GetIdx(),
    2456         [ #  # ]:          0 :                      pBreakIt->GetLocale( aSub[nActual].GetLanguage() ),
    2457 [ #  # ][ #  # ]:          0 :                      i18n::WordType::ANYWORD_IGNOREWHITESPACES ) )
    2458                 :            :                 {
    2459                 :            :                     // In this case, the beginning of aTmpText is wrong.
    2460         [ #  # ]:          0 :                     XubString aSnippetTmp( aSnippet, 0, 1 );
    2461 [ #  # ][ #  # ]:          0 :                     aSnippetTmp = aSub[nActual].CalcCaseMap( aSnippetTmp );
                 [ #  # ]
    2462         [ #  # ]:          0 :                     aTmpText.Erase( 0, aSnippetTmp.Len() );
    2463 [ #  # ][ #  # ]:          0 :                     aTmpText.Insert( aSnippet.GetChar( 0 ), 0 );
    2464                 :            :                 }
    2465                 :            :             }
    2466                 :            : 
    2467                 :        240 :             pTmpText = &aTmpText;
    2468                 :        240 :             nTmpIdx = 0;
    2469                 :        240 :             nTmpLen = aTmpText.Len();
    2470         [ +  - ]:        240 :             bTextReplaced = true;
    2471                 :            :         }
    2472                 :            : 
    2473         [ -  + ]:      42491 :            if( rInf.GetHyphPos() )
    2474                 :          0 :             nTxtBreak = rInf.GetOut().GetTextBreak( *pTmpText, nTextWidth,
    2475                 :          0 :                                                     '-', *rInf.GetHyphPos(),
    2476         [ #  # ]:          0 :                                                      nTmpIdx, nTmpLen, nKern );
    2477                 :            :         else
    2478                 :      42491 :             nTxtBreak = rInf.GetOut().GetTextBreak( *pTmpText, nTextWidth,
    2479         [ +  - ]:      42491 :                                                     nTmpIdx, nTmpLen, nKern );
    2480                 :            : 
    2481 [ +  + ][ +  + ]:      42491 :         if ( bTextReplaced && STRING_LEN != nTxtBreak )
    2482                 :            :         {
    2483         [ -  + ]:        160 :             if ( nTmpLen != nLn )
    2484                 :          0 :                 nTxtBreak = lcl_CalcCaseMap( *this, rInf.GetText(),
    2485         [ #  # ]:          0 :                                              rInf.GetIdx(), nLn, nTxtBreak );
    2486                 :            :             else
    2487                 :        160 :                 nTxtBreak = nTxtBreak + rInf.GetIdx();
    2488         [ +  - ]:      42491 :         }
    2489                 :            :     }
    2490                 :            : 
    2491         [ +  - ]:      42491 :     if ( ! bCompress )
    2492                 :      42491 :         return nTxtBreak;
    2493                 :            : 
    2494                 :          0 :     nTxtBreak = nTxtBreak - rInf.GetIdx();
    2495                 :            : 
    2496         [ #  # ]:          0 :     if( nTxtBreak < nLn )
    2497                 :            :     {
    2498 [ #  # ][ #  # ]:          0 :         if( !nTxtBreak && nLn )
    2499                 :          0 :             nLn = 1;
    2500         [ #  # ]:          0 :         else if( nLn > 2 * nTxtBreak )
    2501                 :          0 :             nLn = 2 * nTxtBreak;
    2502                 :          0 :         sal_Int32 *pKernArray = new sal_Int32[ nLn ];
    2503                 :          0 :         rInf.GetOut().GetTextArray( rInf.GetText(), pKernArray,
    2504                 :          0 :                                     rInf.GetIdx(), nLn );
    2505         [ #  # ]:          0 :         if( rInf.GetScriptInfo()->Compress( pKernArray, rInf.GetIdx(), nLn,
    2506                 :          0 :                             rInf.GetKanaComp(), (sal_uInt16)GetHeight( nActual ) ) )
    2507                 :            :         {
    2508                 :          0 :             long nKernAdd = nKern;
    2509                 :          0 :             xub_StrLen nTmpBreak = nTxtBreak;
    2510 [ #  # ][ #  # ]:          0 :             if( nKern && nTxtBreak )
    2511                 :          0 :                 nKern *= nTxtBreak - 1;
    2512 [ #  # ][ #  # ]:          0 :             while( nTxtBreak<nLn && nTextWidth >= pKernArray[nTxtBreak] +nKern )
                 [ #  # ]
    2513                 :            :             {
    2514                 :          0 :                 nKern += nKernAdd;
    2515                 :          0 :                 ++nTxtBreak;
    2516                 :            :             }
    2517         [ #  # ]:          0 :             if( rInf.GetHyphPos() )
    2518                 :          0 :                 *rInf.GetHyphPos() += nTxtBreak - nTmpBreak; // It's not perfect
    2519                 :            :         }
    2520         [ #  # ]:          0 :         delete[] pKernArray;
    2521                 :            :     }
    2522                 :          0 :     nTxtBreak = nTxtBreak + rInf.GetIdx();
    2523                 :            : 
    2524                 :      42491 :     return nTxtBreak;
    2525                 :            : }
    2526                 :            : 
    2527                 :            : extern Color aGlobalRetoucheColor;
    2528                 :            : 
    2529                 :      26568 : sal_Bool SwDrawTextInfo::ApplyAutoColor( Font* pFont )
    2530                 :            : {
    2531         [ +  + ]:      26568 :     const Font& rFnt = pFont ? *pFont : GetOut().GetFont();
    2532 [ +  - ][ +  + ]:      26568 :     sal_Bool bPrt = GetShell() && ! GetShell()->GetWin();
    2533                 :      26568 :     ColorData nNewColor = COL_BLACK;
    2534                 :      26568 :     sal_Bool bChgFntColor = sal_False;
    2535                 :      26568 :     sal_Bool bChgLineColor = sal_False;
    2536                 :            : 
    2537 [ +  + ][ +  - ]:      26568 :     if( bPrt && GetShell() && GetShell()->GetViewOptions()->IsBlackFont() )
         [ -  + ][ -  + ]
    2538                 :            :     {
    2539         [ #  # ]:          0 :         if ( COL_BLACK != rFnt.GetColor().GetColor() )
    2540                 :          0 :             bChgFntColor = sal_True;
    2541                 :            : 
    2542   [ #  #  #  # ]:          0 :         if ( (COL_BLACK != GetOut().GetLineColor().GetColor()) ||
                 [ #  # ]
    2543                 :          0 :              (COL_BLACK != GetOut().GetOverlineColor().GetColor()) )
    2544                 :          0 :             bChgLineColor = sal_True;
    2545                 :            :     }
    2546                 :            :     else
    2547                 :            :     {
    2548                 :            :         // FontColor has to be changed if:
    2549                 :            :         // 1. FontColor = AUTO or 2. IsAlwaysAutoColor is set
    2550                 :            :         // LineColor has to be changed if:
    2551                 :            :         // 1. IsAlwaysAutoColor is set
    2552                 :            : 
    2553                 :      26323 :         bChgLineColor = ! bPrt && GetShell() &&
    2554   [ +  +  +  - ]:      52891 :                 GetShell()->GetAccessibilityOptions()->IsAlwaysAutoColor();
                 [ -  + ]
    2555                 :            : 
    2556 [ +  + ][ -  + ]:      26568 :         bChgFntColor = COL_AUTO == rFnt.GetColor().GetColor() || bChgLineColor;
    2557                 :            : 
    2558         [ +  + ]:      26568 :         if ( bChgFntColor )
    2559                 :            :         {
    2560                 :            :             // check if current background has a user defined setting
    2561         [ +  - ]:      25912 :             const Color* pCol = GetFont() ? GetFont()->GetBackColor() : NULL;
    2562 [ -  + ][ #  # ]:      25912 :             if( ! pCol || COL_TRANSPARENT == pCol->GetColor() )
                 [ +  - ]
    2563                 :            :             {
    2564                 :            :                 const SvxBrushItem* pItem;
    2565                 :      25912 :                 SwRect aOrigBackRect;
    2566                 :            : 
    2567                 :            :                 /// OD 21.08.2002
    2568                 :            :                 ///     consider, that [GetBackgroundBrush(...)] can set <pCol>
    2569                 :            :                 ///     - see implementation in /core/layout/paintfrm.cxx
    2570                 :            :                 /// OD 21.08.2002 #99657#
    2571                 :            :                 ///     There is a user defined setting for the background, if there
    2572                 :            :                 ///     is a background brush and its color is *not* "no fill"/"auto fill".
    2573 [ +  + ][ +  - ]:      25912 :                 if( GetFrm()->GetBackgroundBrush( pItem, pCol, aOrigBackRect, sal_False ) )
    2574                 :            :                 {
    2575         [ +  + ]:         38 :                     if ( !pCol )
    2576                 :            :                     {
    2577                 :         24 :                         pCol = &pItem->GetColor();
    2578                 :            :                     }
    2579                 :            : 
    2580                 :            :                     /// OD 30.08.2002 #99657#
    2581                 :            :                     /// determined color <pCol> can be <COL_TRANSPARENT>. Thus, check it.
    2582         [ -  + ]:         38 :                     if ( pCol->GetColor() == COL_TRANSPARENT)
    2583                 :          0 :                         pCol = NULL;
    2584                 :            :                 }
    2585                 :            :                 else
    2586                 :      25912 :                     pCol = NULL;
    2587                 :            :             }
    2588                 :            : 
    2589                 :            :             // no user defined color at paragraph or font background
    2590         [ +  + ]:      25912 :             if ( ! pCol )
    2591                 :      25874 :                 pCol = &aGlobalRetoucheColor;
    2592                 :            : 
    2593 [ +  - ][ +  + ]:      25912 :             if( GetShell() && GetShell()->GetWin() )
                 [ +  + ]
    2594                 :            :             {
    2595                 :            :                 // here we determine the prefered window text color for painting
    2596                 :      25667 :                 const SwViewOption* pViewOption = GetShell()->GetViewOptions();
    2597 [ #  # ][ -  + ]:      25667 :                 if(pViewOption->IsPagePreview() &&
                 [ -  + ]
    2598 [ #  # ][ #  # ]:          0 :                         !SW_MOD()->GetAccessibilityOptions().GetIsForPagePreviews())
                 [ #  # ]
    2599                 :          0 :                     nNewColor = COL_BLACK;
    2600                 :            :                 else
    2601                 :            :                     // we take the font color from the appearence page
    2602         [ +  - ]:      25667 :                     nNewColor = SwViewOption::GetFontColor().GetColor();
    2603                 :            :             }
    2604                 :            : 
    2605                 :            :             // change painting color depending of dark/bright background
    2606                 :      25912 :             Color aTmpColor( nNewColor );
    2607 [ +  + ][ +  - ]:      25912 :             if ( pCol->IsDark() && aTmpColor.IsDark() )
         [ +  - ][ +  + ]
                 [ +  - ]
    2608                 :         16 :                 nNewColor = COL_WHITE;
    2609 [ +  - ][ +  + ]:      25896 :             else if ( pCol->IsBright() && aTmpColor.IsBright() )
         [ +  - ][ -  + ]
                 [ -  + ]
    2610                 :      25912 :                 nNewColor = COL_BLACK;
    2611                 :            :         }
    2612                 :            :     }
    2613                 :            : 
    2614 [ +  + ][ -  + ]:      26568 :     if ( bChgFntColor || bChgLineColor )
    2615                 :            :     {
    2616                 :      25912 :         Color aNewColor( nNewColor );
    2617                 :            : 
    2618         [ +  - ]:      25912 :         if ( bChgFntColor )
    2619                 :            :         {
    2620 [ +  + ][ +  - ]:      25912 :             if ( pFont && aNewColor != pFont->GetColor() )
         [ +  - ][ +  + ]
    2621                 :            :             {
    2622                 :            :                 // only set the new color at the font passed as argument
    2623         [ +  - ]:      25908 :                 pFont->SetColor( aNewColor );
    2624                 :            :             }
    2625 [ +  - ][ +  - ]:          4 :             else if ( aNewColor != GetOut().GetFont().GetColor() )
    2626                 :            :             {
    2627                 :            :                 // set new font with new color at output device
    2628         [ +  - ]:          4 :                 Font aFont( rFnt );
    2629         [ +  - ]:          4 :                 aFont.SetColor( aNewColor );
    2630 [ +  - ][ +  - ]:          4 :                 GetOut().SetFont( aFont );
    2631                 :            :             }
    2632                 :            :         }
    2633                 :            : 
    2634                 :            :         // the underline and overline colors have to be set separately
    2635         [ -  + ]:      25912 :         if ( bChgLineColor )
    2636                 :            :         {
    2637                 :            :             // get current font color or color set at output device
    2638 [ #  # ][ #  # ]:          0 :             aNewColor = pFont ? pFont->GetColor() : GetOut().GetFont().GetColor();
                 [ #  # ]
    2639         [ #  # ]:          0 :             if ( aNewColor != GetOut().GetLineColor() )
    2640         [ #  # ]:          0 :                 GetOut().SetLineColor( aNewColor );
    2641         [ #  # ]:          0 :             if ( aNewColor != GetOut().GetOverlineColor() )
    2642         [ #  # ]:          0 :                 GetOut().SetOverlineColor( aNewColor );
    2643                 :            :         }
    2644                 :            : 
    2645                 :      25912 :         return sal_True;
    2646                 :            :     }
    2647                 :            : 
    2648                 :      26568 :     return sal_False;
    2649                 :            : }
    2650                 :            : 
    2651                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10