LCOV - code coverage report
Current view: top level - sc/source/ui/view - output2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1459 2659 54.9 %
Date: 2012-08-25 Functions: 72 83 86.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1366 4082 33.5 %

           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 "scitems.hxx"
      30                 :            : #include <editeng/eeitem.hxx>
      31                 :            : 
      32                 :            : 
      33                 :            : #include <editeng/adjitem.hxx>
      34                 :            : #include <svx/algitem.hxx>
      35                 :            : #include <editeng/brshitem.hxx>
      36                 :            : #include <svtools/colorcfg.hxx>
      37                 :            : #include <editeng/colritem.hxx>
      38                 :            : #include <editeng/editobj.hxx>
      39                 :            : #include <editeng/editstat.hxx>
      40                 :            : #include <editeng/fhgtitem.hxx>
      41                 :            : #include <editeng/forbiddencharacterstable.hxx>
      42                 :            : #include <editeng/frmdiritem.hxx>
      43                 :            : #include <editeng/langitem.hxx>
      44                 :            : #include <editeng/justifyitem.hxx>
      45                 :            : #include <svx/rotmodit.hxx>
      46                 :            : #include <editeng/scripttypeitem.hxx>
      47                 :            : #include <editeng/udlnitem.hxx>
      48                 :            : #include <editeng/unolingu.hxx>
      49                 :            : #include <svl/zforlist.hxx>
      50                 :            : #include <svl/zformat.hxx>
      51                 :            : #include <vcl/svapp.hxx>
      52                 :            : #include <vcl/metric.hxx>
      53                 :            : #include <vcl/outdev.hxx>
      54                 :            : #include <vcl/pdfextoutdevdata.hxx>
      55                 :            : 
      56                 :            : #include "output.hxx"
      57                 :            : #include "document.hxx"
      58                 :            : #include "cell.hxx"
      59                 :            : #include "attrib.hxx"
      60                 :            : #include "patattr.hxx"
      61                 :            : #include "cellform.hxx"
      62                 :            : #include "editutil.hxx"
      63                 :            : #include "progress.hxx"
      64                 :            : #include "scmod.hxx"
      65                 :            : #include "fillinfo.hxx"
      66                 :            : 
      67                 :            : #include <com/sun/star/i18n/DirectionProperty.hpp>
      68                 :            : 
      69                 :            : #include <boost/ptr_container/ptr_vector.hpp>
      70                 :            : 
      71                 :            : #include <math.h>
      72                 :            : 
      73                 :            : using namespace com::sun::star;
      74                 :            : 
      75                 :            : //! Autofilter-Breite mit column.cxx zusammenfassen
      76                 :            : #define DROPDOWN_BITMAP_SIZE        18
      77                 :            : 
      78                 :            : #define DRAWTEXT_MAX    32767
      79                 :            : 
      80                 :            : const sal_uInt16 SC_SHRINKAGAIN_MAX = 7;
      81                 :            : 
      82                 :            : // STATIC DATA -----------------------------------------------------------
      83                 :            : 
      84                 :            : 
      85                 :            : // -----------------------------------------------------------------------
      86                 :            : 
      87                 :            : class ScDrawStringsVars
      88                 :            : {
      89                 :            :     ScOutputData*       pOutput;                // Verbindung
      90                 :            : 
      91                 :            :     const ScPatternAttr* pPattern;              // Attribute
      92                 :            :     const SfxItemSet*   pCondSet;               // aus bedingter Formatierung
      93                 :            : 
      94                 :            :     Font                aFont;                  // aus Attributen erzeugt
      95                 :            :     FontMetric          aMetric;
      96                 :            :     long                nAscentPixel;           // always pixels
      97                 :            :     SvxCellOrientation  eAttrOrient;
      98                 :            :     SvxCellHorJustify   eAttrHorJust;
      99                 :            :     SvxCellVerJustify   eAttrVerJust;
     100                 :            :     SvxCellJustifyMethod eAttrHorJustMethod;
     101                 :            :     SvxCellJustifyMethod eAttrVerJustMethod;
     102                 :            :     const SvxMarginItem* pMargin;
     103                 :            :     sal_uInt16              nIndent;
     104                 :            :     sal_Bool                bRotated;
     105                 :            : 
     106                 :            :     String              aString;                // Inhalte
     107                 :            :     Size                aTextSize;
     108                 :            :     long                nOriginalWidth;
     109                 :            :     long                nMaxDigitWidth;
     110                 :            :     long                nSignWidth;
     111                 :            :     long                nDotWidth;
     112                 :            :     long                nExpWidth;
     113                 :            : 
     114                 :            :     ScBaseCell*         pLastCell;
     115                 :            :     sal_uLong               nValueFormat;
     116                 :            :     sal_Bool                bLineBreak;
     117                 :            :     sal_Bool                bRepeat;
     118                 :            :     sal_Bool                bShrink;
     119                 :            : 
     120                 :            :     sal_Bool                bPixelToLogic;
     121                 :            :     sal_Bool                bCellContrast;
     122                 :            : 
     123                 :            :     Color               aBackConfigColor;       // used for ScPatternAttr::GetFont calls
     124                 :            :     Color               aTextConfigColor;
     125                 :            :     sal_Int32           nPos;
     126                 :            :     sal_Unicode         nChar;
     127                 :            : 
     128                 :            : public:
     129                 :            :                 ScDrawStringsVars(ScOutputData* pData, sal_Bool bPTL);
     130                 :            :                 ~ScDrawStringsVars();
     131                 :            : 
     132                 :            :                 //  SetPattern = ex-SetVars
     133                 :            :                 //  SetPatternSimple: ohne Font
     134                 :            : 
     135                 :            :     void        SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet, ScBaseCell* pCell, sal_uInt8 nScript );
     136                 :            :     void        SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet );
     137                 :            : 
     138                 :            :     sal_Bool        SetText( ScBaseCell* pCell );   // TRUE -> pOldPattern vergessen
     139                 :            :     void        SetHashText();
     140                 :            :     void        SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth );
     141                 :            :     void        SetAutoText( const String& rAutoText );
     142                 :            : 
     143                 :            :     const ScPatternAttr*    GetPattern() const      { return pPattern; }
     144                 :      33418 :     SvxCellOrientation      GetOrient() const       { return eAttrOrient; }
     145                 :      33543 :     SvxCellHorJustify       GetHorJust() const      { return eAttrHorJust; }
     146                 :      10660 :     SvxCellVerJustify       GetVerJust() const      { return eAttrVerJust; }
     147                 :         48 :     SvxCellJustifyMethod    GetHorJustMethod() const { return eAttrHorJustMethod; }
     148                 :            :     SvxCellJustifyMethod    GetVerJustMethod() const { return eAttrVerJustMethod; }
     149                 :      27911 :     const SvxMarginItem*    GetMargin() const       { return pMargin; }
     150                 :            : 
     151                 :      16245 :     sal_uInt16  GetLeftTotal() const        { return pMargin->GetLeftMargin() + nIndent; }
     152                 :            : 
     153                 :      20558 :     const String&           GetString() const       { return aString; }
     154                 :      39454 :     const Size&             GetTextSize() const     { return aTextSize; }
     155                 :        916 :     long                    GetOriginalWidth() const { return nOriginalWidth; }
     156                 :            : 
     157                 :      11050 :     sal_uLong   GetValueFormat() const                  { return nValueFormat; }
     158                 :      10909 :     sal_Bool    GetLineBreak() const                    { return bLineBreak; }
     159                 :      10909 :     sal_Bool    IsRepeat() const                        { return bRepeat; }
     160                 :      10909 :     sal_Bool    IsShrink() const                        { return bShrink; }
     161                 :            :     void        RepeatToFill( long colWidth );
     162                 :            : 
     163                 :      10660 :     long    GetAscent() const   { return nAscentPixel; }
     164                 :      11486 :     sal_Bool    IsRotated() const   { return bRotated; }
     165                 :            : 
     166                 :            :     void    SetShrinkScale( long nScale, sal_uInt8 nScript );
     167                 :            : 
     168                 :          0 :     sal_Bool    HasCondHeight() const   { return pCondSet && SFX_ITEM_SET ==
     169 [ #  # ][ #  # ]:          0 :                                         pCondSet->GetItemState( ATTR_FONT_HEIGHT, sal_True ); }
     170                 :            : 
     171                 :            :     sal_Bool    HasEditCharacters() const;
     172                 :            : 
     173                 :            : private:
     174                 :            :     long        GetMaxDigitWidth();     // in logic units
     175                 :            :     long        GetSignWidth();
     176                 :            :     long        GetDotWidth();
     177                 :            :     long        GetExpWidth();
     178                 :            :     void        TextChanged();
     179                 :            : };
     180                 :            : 
     181                 :            : //==================================================================
     182                 :            : 
     183                 :       1345 : ScDrawStringsVars::ScDrawStringsVars(ScOutputData* pData, sal_Bool bPTL) :
     184                 :            :     pOutput     ( pData ),
     185                 :            :     pPattern    ( NULL ),
     186                 :            :     pCondSet    ( NULL ),
     187                 :            :     nAscentPixel(0),
     188                 :            :     eAttrOrient ( SVX_ORIENTATION_STANDARD ),
     189                 :            :     eAttrHorJust( SVX_HOR_JUSTIFY_STANDARD ),
     190                 :            :     eAttrVerJust( SVX_VER_JUSTIFY_BOTTOM ),
     191                 :            :     eAttrHorJustMethod( SVX_JUSTIFY_METHOD_AUTO ),
     192                 :            :     eAttrVerJustMethod( SVX_JUSTIFY_METHOD_AUTO ),
     193                 :            :     pMargin     ( NULL ),
     194                 :            :     nIndent     ( 0 ),
     195                 :            :     bRotated    ( false ),
     196                 :            :     nOriginalWidth( 0 ),
     197                 :            :     nMaxDigitWidth( 0 ),
     198                 :            :     nSignWidth( 0 ),
     199                 :            :     nDotWidth( 0 ),
     200                 :            :     nExpWidth( 0 ),
     201                 :            :     pLastCell   ( NULL ),
     202                 :            :     nValueFormat( 0 ),
     203                 :            :     bLineBreak  ( false ),
     204                 :            :     bRepeat     ( false ),
     205                 :            :     bShrink     ( false ),
     206                 :            :     bPixelToLogic( bPTL ),
     207                 :            :     nPos( STRING_NOTFOUND ),
     208 [ +  - ][ +  - ]:       1345 :     nChar( 0x0 )
     209                 :            : {
     210         [ +  - ]:       1345 :     ScModule* pScMod = SC_MOD();
     211                 :            :     bCellContrast = pOutput->mbUseStyleColor &&
     212 [ +  + ][ +  - ]:       1345 :             Application::GetSettings().GetStyleSettings().GetHighContrastMode();
                 [ -  + ]
     213                 :            : 
     214         [ +  - ]:       1345 :     const svtools::ColorConfig& rColorConfig = pScMod->GetColorConfig();
     215         [ +  - ]:       1345 :     aBackConfigColor.SetColor( rColorConfig.GetColorValue(svtools::DOCCOLOR).nColor );
     216         [ +  - ]:       1345 :     aTextConfigColor.SetColor( rColorConfig.GetColorValue(svtools::FONTCOLOR).nColor );
     217                 :       1345 : }
     218                 :            : 
     219 [ +  - ][ +  - ]:       1345 : ScDrawStringsVars::~ScDrawStringsVars()
     220                 :            : {
     221                 :       1345 : }
     222                 :            : 
     223                 :          0 : void ScDrawStringsVars::SetShrinkScale( long nScale, sal_uInt8 nScript )
     224                 :            : {
     225                 :            :     // text remains valid, size is updated
     226                 :            : 
     227                 :          0 :     OutputDevice* pDev = pOutput->mpDev;
     228                 :          0 :     OutputDevice* pRefDevice = pOutput->mpRefDevice;
     229                 :          0 :     OutputDevice* pFmtDevice = pOutput->pFmtDevice;
     230                 :            : 
     231                 :            :     // call GetFont with a modified fraction, use only the height
     232                 :            : 
     233         [ #  # ]:          0 :     Fraction aFraction( nScale, 100 );
     234         [ #  # ]:          0 :     if ( !bPixelToLogic )
     235         [ #  # ]:          0 :         aFraction *= pOutput->aZoomY;
     236         [ #  # ]:          0 :     Font aTmpFont;
     237         [ #  # ]:          0 :     pPattern->GetFont( aTmpFont, SC_AUTOCOL_RAW, pFmtDevice, &aFraction, pCondSet, nScript );
     238         [ #  # ]:          0 :     long nNewHeight = aTmpFont.GetHeight();
     239         [ #  # ]:          0 :     if ( nNewHeight > 0 )
     240         [ #  # ]:          0 :         aFont.SetHeight( nNewHeight );
     241                 :            : 
     242                 :            :     // set font and dependent variables as in SetPattern
     243                 :            : 
     244         [ #  # ]:          0 :     pDev->SetFont( aFont );
     245         [ #  # ]:          0 :     if ( pFmtDevice != pDev )
     246         [ #  # ]:          0 :         pFmtDevice->SetFont( aFont );
     247                 :            : 
     248 [ #  # ][ #  # ]:          0 :     aMetric = pFmtDevice->GetFontMetric();
                 [ #  # ]
     249 [ #  # ][ #  # ]:          0 :     if ( pFmtDevice->GetOutDevType() == OUTDEV_PRINTER && aMetric.GetIntLeading() == 0 )
         [ #  # ][ #  # ]
     250                 :            :     {
     251         [ #  # ]:          0 :         OutputDevice* pDefaultDev = Application::GetDefaultDevice();
     252         [ #  # ]:          0 :         MapMode aOld = pDefaultDev->GetMapMode();
     253         [ #  # ]:          0 :         pDefaultDev->SetMapMode( pFmtDevice->GetMapMode() );
     254 [ #  # ][ #  # ]:          0 :         aMetric = pDefaultDev->GetFontMetric( aFont );
                 [ #  # ]
     255 [ #  # ][ #  # ]:          0 :         pDefaultDev->SetMapMode( aOld );
     256                 :            :     }
     257                 :            : 
     258         [ #  # ]:          0 :     nAscentPixel = aMetric.GetAscent();
     259         [ #  # ]:          0 :     if ( bPixelToLogic )
     260         [ #  # ]:          0 :         nAscentPixel = pRefDevice->LogicToPixel( Size( 0, nAscentPixel ) ).Height();
     261                 :            : 
     262 [ #  # ][ #  # ]:          0 :     SetAutoText( aString );     // same text again, to get text size
     263                 :          0 : }
     264                 :            : 
     265                 :            : namespace {
     266                 :            : 
     267                 :            : template<typename _ItemType, typename _EnumType>
     268                 :       9115 : _EnumType lcl_GetValue(const ScPatternAttr& rPattern, sal_uInt16 nWhich, const SfxItemSet* pCondSet)
     269                 :            : {
     270                 :       9115 :     const _ItemType& rItem = static_cast<const _ItemType&>(rPattern.GetItem(nWhich, pCondSet));
     271                 :       9115 :     return static_cast<_EnumType>(rItem.GetValue());
     272                 :            : }
     273                 :            : 
     274                 :        964 : bool lcl_GetBoolValue(const ScPatternAttr& rPattern, sal_uInt16 nWhich, const SfxItemSet* pCondSet)
     275                 :            : {
     276                 :        964 :     return lcl_GetValue<SfxBoolItem, bool>(rPattern, nWhich, pCondSet);
     277                 :            : }
     278                 :            : 
     279                 :            : }
     280                 :            : 
     281                 :       1583 : void ScDrawStringsVars::SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet,
     282                 :            :                                     ScBaseCell* pCell, sal_uInt8 nScript )
     283                 :            : {
     284                 :       1583 :     nMaxDigitWidth = 0;
     285                 :       1583 :     nSignWidth     = 0;
     286                 :       1583 :     nDotWidth      = 0;
     287                 :       1583 :     nExpWidth      = 0;
     288                 :            : 
     289                 :       1583 :     pPattern = pNew;
     290                 :       1583 :     pCondSet = pSet;
     291                 :            : 
     292                 :            :     //  pPattern auswerten
     293                 :            : 
     294                 :       1583 :     OutputDevice* pDev = pOutput->mpDev;
     295                 :       1583 :     OutputDevice* pRefDevice = pOutput->mpRefDevice;
     296                 :       1583 :     OutputDevice* pFmtDevice = pOutput->pFmtDevice;
     297                 :            : 
     298                 :            :     //  Font
     299                 :            : 
     300                 :            :     ScAutoFontColorMode eColorMode;
     301         [ +  - ]:       1583 :     if ( pOutput->mbUseStyleColor )
     302                 :            :     {
     303         [ -  + ]:       1583 :         if ( pOutput->mbForceAutoColor )
     304         [ #  # ]:          0 :             eColorMode = bCellContrast ? SC_AUTOCOL_IGNOREALL : SC_AUTOCOL_IGNOREFONT;
     305                 :            :         else
     306         [ -  + ]:       1583 :             eColorMode = bCellContrast ? SC_AUTOCOL_IGNOREBACK : SC_AUTOCOL_DISPLAY;
     307                 :            :     }
     308                 :            :     else
     309                 :          0 :         eColorMode = SC_AUTOCOL_PRINT;
     310                 :            : 
     311         [ +  + ]:       1583 :     if ( bPixelToLogic )
     312                 :            :         pPattern->GetFont( aFont, eColorMode, pFmtDevice, NULL, pCondSet, nScript,
     313         [ +  - ]:         29 :                             &aBackConfigColor, &aTextConfigColor );
     314                 :            :     else
     315                 :            :         pPattern->GetFont( aFont, eColorMode, pFmtDevice, &pOutput->aZoomY, pCondSet, nScript,
     316         [ +  - ]:       1554 :                             &aBackConfigColor, &aTextConfigColor );
     317         [ +  - ]:       1583 :     aFont.SetAlign(ALIGN_BASELINE);
     318                 :            : 
     319                 :            :     //  Orientierung
     320                 :            : 
     321         [ +  - ]:       1583 :     eAttrOrient = pPattern->GetCellOrientation( pCondSet );
     322                 :            : 
     323                 :            :     //  alignment
     324                 :            : 
     325         [ +  - ]:       1583 :     eAttrHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
     326                 :            : 
     327         [ +  - ]:       1583 :     eAttrVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)pPattern->GetItem( ATTR_VER_JUSTIFY, pCondSet )).GetValue();
     328         [ +  - ]:       1583 :     if ( eAttrVerJust == SVX_VER_JUSTIFY_STANDARD )
     329                 :       1583 :         eAttrVerJust = SVX_VER_JUSTIFY_BOTTOM;
     330                 :            : 
     331                 :            :     // justification method
     332                 :            : 
     333         [ +  - ]:       1583 :     eAttrHorJustMethod = lcl_GetValue<SvxJustifyMethodItem, SvxCellJustifyMethod>(*pPattern, ATTR_HOR_JUSTIFY_METHOD, pCondSet);
     334         [ +  - ]:       1583 :     eAttrVerJustMethod = lcl_GetValue<SvxJustifyMethodItem, SvxCellJustifyMethod>(*pPattern, ATTR_VER_JUSTIFY_METHOD, pCondSet);
     335                 :            : 
     336                 :            :     //  line break
     337                 :            : 
     338         [ +  - ]:       1583 :     bLineBreak = ((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK, pCondSet )).GetValue();
     339                 :            : 
     340                 :            :     //  handle "repeat" alignment
     341                 :            : 
     342                 :       1583 :     bRepeat = ( eAttrHorJust == SVX_HOR_JUSTIFY_REPEAT );
     343         [ -  + ]:       1583 :     if ( bRepeat )
     344                 :            :     {
     345                 :            :         // "repeat" disables rotation (before constructing the font)
     346                 :          0 :         eAttrOrient = SVX_ORIENTATION_STANDARD;
     347                 :            : 
     348                 :            :         // #i31843# "repeat" with "line breaks" is treated as default alignment (but rotation is still disabled)
     349         [ #  # ]:          0 :         if ( bLineBreak )
     350                 :          0 :             eAttrHorJust = SVX_HOR_JUSTIFY_STANDARD;
     351                 :            :     }
     352                 :            : 
     353                 :            :     short nRot;
     354   [ +  -  +  -  :       1583 :     switch (eAttrOrient)
                      - ]
     355                 :            :     {
     356                 :            :         case SVX_ORIENTATION_STANDARD:
     357                 :       1511 :             nRot = 0;
     358         [ +  - ]:       1511 :             bRotated = (((const SfxInt32Item&)pPattern->GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue() != 0) &&
     359 [ +  - ][ +  + ]:       1511 :                        !bRepeat;
     360                 :       1511 :             break;
     361                 :            :         case SVX_ORIENTATION_STACKED:
     362                 :          0 :             nRot = 0;
     363                 :          0 :             bRotated = false;
     364                 :          0 :             break;
     365                 :            :         case SVX_ORIENTATION_TOPBOTTOM:
     366                 :         72 :             nRot = 2700;
     367                 :         72 :             bRotated = false;
     368                 :         72 :             break;
     369                 :            :         case SVX_ORIENTATION_BOTTOMTOP:
     370                 :          0 :             nRot = 900;
     371                 :          0 :             bRotated = false;
     372                 :          0 :             break;
     373                 :            :         default:
     374                 :            :             OSL_FAIL("Falscher SvxCellOrientation Wert");
     375                 :          0 :             nRot = 0;
     376                 :          0 :             bRotated = false;
     377                 :          0 :             break;
     378                 :            :     }
     379         [ +  - ]:       1583 :     aFont.SetOrientation( nRot );
     380                 :            : 
     381                 :            :     //  Syntax-Modus
     382                 :            : 
     383         [ -  + ]:       1583 :     if (pOutput->mbSyntaxMode)
     384         [ #  # ]:          0 :         pOutput->SetSyntaxColor( &aFont, pCell );
     385                 :            : 
     386         [ +  - ]:       1583 :     pDev->SetFont( aFont );
     387         [ +  + ]:       1583 :     if ( pFmtDevice != pDev )
     388         [ +  - ]:         75 :         pFmtDevice->SetFont( aFont );
     389                 :            : 
     390 [ +  - ][ +  - ]:       1583 :     aMetric = pFmtDevice->GetFontMetric();
                 [ +  - ]
     391                 :            : 
     392                 :            :     //
     393                 :            :     //  Wenn auf dem Drucker das Leading 0 ist, gibt es Probleme
     394                 :            :     //  -> Metric vom Bildschirm nehmen (wie EditEngine!)
     395                 :            :     //
     396                 :            : 
     397 [ +  + ][ +  - ]:       1583 :     if ( pFmtDevice->GetOutDevType() == OUTDEV_PRINTER && aMetric.GetIntLeading() == 0 )
         [ -  + ][ -  + ]
     398                 :            :     {
     399         [ #  # ]:          0 :         OutputDevice* pDefaultDev = Application::GetDefaultDevice();
     400         [ #  # ]:          0 :         MapMode aOld = pDefaultDev->GetMapMode();
     401         [ #  # ]:          0 :         pDefaultDev->SetMapMode( pFmtDevice->GetMapMode() );
     402 [ #  # ][ #  # ]:          0 :         aMetric = pDefaultDev->GetFontMetric( aFont );
                 [ #  # ]
     403 [ #  # ][ #  # ]:          0 :         pDefaultDev->SetMapMode( aOld );
     404                 :            :     }
     405                 :            : 
     406         [ +  - ]:       1583 :     nAscentPixel = aMetric.GetAscent();
     407         [ +  + ]:       1583 :     if ( bPixelToLogic )
     408         [ +  - ]:         29 :         nAscentPixel = pRefDevice->LogicToPixel( Size( 0, nAscentPixel ) ).Height();
     409                 :            : 
     410         [ +  - ]:       1583 :     Color aULineColor( ((const SvxUnderlineItem&)pPattern->GetItem( ATTR_FONT_UNDERLINE, pCondSet )).GetColor() );
     411         [ +  - ]:       1583 :     pDev->SetTextLineColor( aULineColor );
     412                 :            : 
     413         [ +  - ]:       1583 :     Color aOLineColor( ((const SvxOverlineItem&)pPattern->GetItem( ATTR_FONT_OVERLINE, pCondSet )).GetColor() );
     414         [ +  - ]:       1583 :     pDev->SetOverlineColor( aOLineColor );
     415                 :            : 
     416                 :            :     //  Zahlenformat
     417                 :            : 
     418 [ +  - ][ +  - ]:       1583 :     nValueFormat = pPattern->GetNumberFormat( pOutput->mpDoc->GetFormatTable(), pCondSet );
     419                 :            : 
     420                 :            :     //  Raender
     421                 :            : 
     422         [ +  - ]:       1583 :     pMargin = (const SvxMarginItem*)&pPattern->GetItem( ATTR_MARGIN, pCondSet );
     423         [ +  + ]:       1583 :     if ( eAttrHorJust == SVX_HOR_JUSTIFY_LEFT )
     424         [ +  - ]:        215 :         nIndent = ((const SfxUInt16Item&)pPattern->GetItem( ATTR_INDENT, pCondSet )).GetValue();
     425                 :            :     else
     426                 :       1368 :         nIndent = 0;
     427                 :            : 
     428                 :            :     //  "Shrink to fit"
     429                 :            : 
     430         [ +  - ]:       1583 :     bShrink = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
     431                 :            : 
     432                 :            :     //  zumindest die Text-Groesse muss neu geholt werden
     433                 :            :     //! unterscheiden, und den Text nicht neu vom Numberformatter holen?
     434                 :            : 
     435                 :       1583 :     pLastCell = NULL;
     436                 :       1583 : }
     437                 :            : 
     438                 :        480 : void ScDrawStringsVars::SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet )
     439                 :            : {
     440                 :        480 :     nMaxDigitWidth = 0;
     441                 :        480 :     nSignWidth     = 0;
     442                 :        480 :     nDotWidth      = 0;
     443                 :        480 :     nExpWidth      = 0;
     444                 :            :     //  wird gerufen, wenn sich die Font-Variablen nicht aendern (!StringDiffer)
     445                 :            : 
     446                 :        480 :     pPattern = pNew;
     447                 :        480 :     pCondSet = pSet;        //! noetig ???
     448                 :            : 
     449                 :            :     //  Zahlenformat
     450                 :            : 
     451                 :        480 :     sal_uLong nOld = nValueFormat;
     452                 :            :     const SfxPoolItem* pFormItem;
     453 [ -  + ][ #  # ]:        480 :     if ( !pCondSet || pCondSet->GetItemState(ATTR_VALUE_FORMAT,sal_True,&pFormItem) != SFX_ITEM_SET )
         [ #  # ][ +  - ]
     454         [ +  - ]:        480 :         pFormItem = &pPattern->GetItem(ATTR_VALUE_FORMAT);
     455                 :            :     const SfxPoolItem* pLangItem;
     456 [ -  + ][ #  # ]:        480 :     if ( !pCondSet || pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT,sal_True,&pLangItem) != SFX_ITEM_SET )
         [ #  # ][ +  - ]
     457         [ +  - ]:        480 :         pLangItem = &pPattern->GetItem(ATTR_LANGUAGE_FORMAT);
     458                 :            :     nValueFormat = pOutput->mpDoc->GetFormatTable()->GetFormatForLanguageIfBuiltIn(
     459                 :            :                     ((SfxUInt32Item*)pFormItem)->GetValue(),
     460 [ +  - ][ +  - ]:        480 :                     ((SvxLanguageItem*)pLangItem)->GetLanguage() );
     461                 :            : 
     462         [ -  + ]:        480 :     if (nValueFormat != nOld)
     463                 :          0 :         pLastCell = NULL;           // immer neu formatieren
     464                 :            : 
     465                 :            :     //  Raender
     466                 :            : 
     467         [ +  - ]:        480 :     pMargin = (const SvxMarginItem*)&pPattern->GetItem( ATTR_MARGIN, pCondSet );
     468                 :            : 
     469         [ +  + ]:        480 :     if ( eAttrHorJust == SVX_HOR_JUSTIFY_LEFT )
     470         [ +  - ]:        104 :         nIndent = ((const SfxUInt16Item&)pPattern->GetItem( ATTR_INDENT, pCondSet )).GetValue();
     471                 :            :     else
     472                 :        376 :         nIndent = 0;
     473                 :            : 
     474                 :            :     //  "Shrink to fit"
     475                 :            : 
     476         [ +  - ]:        480 :     bShrink = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
     477                 :        480 : }
     478                 :            : 
     479                 :      10909 : inline sal_Bool SameValue( ScBaseCell* pCell, ScBaseCell* pOldCell )    // pCell ist != 0
     480                 :            : {
     481                 :       9192 :     return pOldCell && pOldCell->GetCellType() == CELLTYPE_VALUE &&
     482                 :       4904 :             pCell->GetCellType() == CELLTYPE_VALUE &&
     483   [ +  +  +  +  :      25005 :             ((ScValueCell*)pCell)->GetValue() == ((ScValueCell*)pOldCell)->GetValue();
           +  + ][ +  + ]
     484                 :            : }
     485                 :            : 
     486                 :      10909 : sal_Bool ScDrawStringsVars::SetText( ScBaseCell* pCell )
     487                 :            : {
     488                 :      10909 :     sal_Bool bChanged = false;
     489                 :            : 
     490         [ +  - ]:      10909 :     if (pCell)
     491                 :            :     {
     492         [ +  + ]:      10909 :         if ( !SameValue( pCell, pLastCell ) )
     493                 :            :         {
     494                 :      10727 :             pLastCell = pCell;          //  Zelle merken
     495                 :            : 
     496                 :            :             Color* pColor;
     497                 :      10727 :             sal_uLong nFormat = GetValueFormat();
     498         [ +  - ]:      10727 :             rtl::OUString aOUString = aString;
     499                 :            :             ScCellFormat::GetString( pCell,
     500                 :            :                                      nFormat, aOUString, &pColor,
     501         [ +  - ]:      10727 :                                      *pOutput->mpDoc->GetFormatTable(),
     502                 :            :                                      pOutput->mbShowNullValues,
     503                 :            :                                      pOutput->mbShowFormulas,
     504         [ +  - ]:      10727 :                                      ftCheck, true );
     505         [ +  - ]:      10727 :             aString = aOUString;
     506         [ +  + ]:      10727 :             if ( nFormat )
     507                 :            :             {
     508         [ +  - ]:        308 :                 nPos = aString.Search( 0x1B );
     509         [ -  + ]:        308 :                 if ( nPos != STRING_NOTFOUND )
     510                 :            :                 {
     511                 :          0 :                     nPos = nPos - 1;
     512                 :          0 :                     nChar = aString.GetChar( nPos );
     513                 :            :                     // delete placeholder and char to repeat
     514         [ #  # ]:          0 :                     aString.Erase( nPos, 2 );
     515                 :            :                 }
     516                 :            :             }
     517                 :            :             else
     518                 :            :             {
     519                 :      10419 :                 nPos = STRING_NOTFOUND;
     520                 :      10419 :                 nChar = 0x0;
     521                 :            :             }
     522         [ -  + ]:      10727 :             if (aString.Len() > DRAWTEXT_MAX)
     523         [ #  # ]:          0 :                 aString.Erase(DRAWTEXT_MAX);
     524                 :            : 
     525 [ -  + ][ #  # ]:      10727 :             if ( pColor && !pOutput->mbSyntaxMode && !( pOutput->mbUseStyleColor && pOutput->mbForceAutoColor ) )
         [ #  # ][ #  # ]
     526                 :            :             {
     527                 :          0 :                 OutputDevice* pDev = pOutput->mpDev;
     528         [ #  # ]:          0 :                 aFont.SetColor(*pColor);
     529         [ #  # ]:          0 :                 pDev->SetFont( aFont ); // nur fuer Ausgabe
     530                 :          0 :                 bChanged = sal_True;
     531                 :          0 :                 pLastCell = NULL;       // naechstes Mal wieder hierherkommen
     532                 :            :             }
     533                 :            : 
     534         [ +  - ]:      10727 :             TextChanged();
     535                 :            :         }
     536                 :            :         //  sonst String/Groesse behalten
     537                 :            :     }
     538                 :            :     else
     539                 :            :     {
     540                 :          0 :         aString.Erase();
     541                 :          0 :         pLastCell = NULL;
     542                 :          0 :         aTextSize = Size(0,0);
     543                 :          0 :         nOriginalWidth = 0;
     544                 :            :     }
     545                 :            : 
     546                 :      10909 :     return bChanged;
     547                 :            : }
     548                 :            : 
     549                 :         48 : void ScDrawStringsVars::SetHashText()
     550                 :            : {
     551 [ +  - ][ +  - ]:         48 :     SetAutoText(rtl::OUString("###"));
                 [ +  - ]
     552                 :         48 : }
     553                 :            : 
     554                 :      10909 : void ScDrawStringsVars::RepeatToFill( long colWidth )
     555                 :            : {
     556 [ -  + ][ #  # ]:      10909 :     if ( nPos ==  STRING_NOTFOUND || nPos >= aString.Len() )
                 [ -  + ]
     557                 :            :         return;
     558                 :            : 
     559 [ #  # ][ #  # ]:          0 :     long charWidth = pOutput->pFmtDevice->GetTextWidth(rtl::OUString(nChar));
                 [ #  # ]
     560         [ #  # ]:          0 :     if (bPixelToLogic)
     561         [ #  # ]:          0 :         colWidth = pOutput->mpRefDevice->PixelToLogic(Size(colWidth,0)).Width();
     562                 :            :     // Are there restrictions on the cell type we should filter out here ?
     563                 :          0 :     long aSpaceToFill = ( colWidth - aTextSize.Width() );
     564                 :            : 
     565         [ #  # ]:          0 :     if ( aSpaceToFill <= charWidth )
     566                 :            :         return;
     567                 :            : 
     568                 :          0 :     long nCharsToInsert = aSpaceToFill / charWidth;
     569         [ #  # ]:          0 :     String aFill;
     570         [ #  # ]:          0 :     aFill.Expand( nCharsToInsert, nChar);
     571         [ #  # ]:          0 :     aString.Insert( aFill, nPos);
     572 [ #  # ][ #  # ]:      10909 :     TextChanged();
     573                 :            : }
     574                 :            : 
     575                 :        323 : void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth )
     576                 :            : {
     577                 :            :     // #i113045# do the single-character width calculations in logic units
     578         [ -  + ]:        323 :     if (bPixelToLogic)
     579         [ #  # ]:          0 :         nWidth = pOutput->mpRefDevice->PixelToLogic(Size(nWidth,0)).Width();
     580                 :            : 
     581         [ -  + ]:        323 :     if (!pCell)
     582                 :          0 :         return;
     583                 :            : 
     584                 :        323 :     CellType eType = pCell->GetCellType();
     585 [ #  # ][ -  + ]:        323 :     if (eType != CELLTYPE_VALUE && eType != CELLTYPE_FORMULA)
     586                 :            :         // must be a value or formula cell.
     587                 :          0 :         return;
     588                 :            : 
     589         [ -  + ]:        323 :     if (eType == CELLTYPE_FORMULA)
     590                 :            :     {
     591         [ #  # ]:          0 :         ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
     592 [ #  # ][ #  # ]:          0 :         if (pFCell->GetErrCode() != 0 || pOutput->mbShowFormulas)
                 [ #  # ]
     593                 :            :         {
     594                 :          0 :             SetHashText();      // If the error string doesn't fit, always use "###". Also for "display formulas" (#i116691#)
     595                 :          0 :             return;
     596                 :            :         }
     597                 :            :         // If it's formula, the result must be a value.
     598         [ #  # ]:          0 :         if (!pFCell->IsValue())
     599                 :          0 :             return;
     600                 :            : 
     601         [ #  # ]:          0 :         if (pFCell->GetFormatType() != NUMBERFORMAT_NUMBER)
     602                 :            :         {
     603                 :            :             // Make sure the format type implicitly set by the interpreter is
     604                 :            :             // of pure numeric type.  We don't want to adjust date and time
     605                 :            :             // values here.
     606                 :          0 :             SetHashText();
     607                 :          0 :             return;
     608                 :            :         }
     609                 :            :     }
     610                 :            : 
     611                 :        323 :     sal_uLong nFormat = GetValueFormat();
     612         [ +  + ]:        323 :     if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
     613                 :            :     {
     614                 :            :         // Not 'General' number format.  Set hash text and bail out.
     615                 :         48 :         SetHashText();
     616                 :         48 :         return;
     617                 :            :     }
     618                 :            : 
     619                 :            :     double fVal = (eType == CELLTYPE_VALUE) ?
     620 [ +  - ][ #  # ]:        275 :         static_cast<ScValueCell*>(pCell)->GetValue() : static_cast<ScFormulaCell*>(pCell)->GetValue();
     621                 :            : 
     622                 :        275 :     const SvNumberformat* pNumFormat = pOutput->mpDoc->GetFormatTable()->GetEntry(nFormat);
     623         [ -  + ]:        275 :     if (!pNumFormat)
     624                 :          0 :         return;
     625                 :            : 
     626                 :        275 :     long nMaxDigit = GetMaxDigitWidth();
     627                 :        275 :     sal_uInt16 nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit);
     628                 :            : 
     629         [ -  + ]:        275 :     if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString))
     630                 :            :         // Failed to get output string.  Bail out.
     631                 :          0 :         return;
     632                 :            : 
     633                 :        275 :     sal_uInt8 nSignCount = 0, nDecimalCount = 0, nExpCount = 0;
     634                 :        275 :     xub_StrLen nLen = aString.Len();
     635                 :        275 :     sal_Unicode cDecSep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator.getStr()[0];
     636         [ +  + ]:       3306 :     for (xub_StrLen i = 0; i < nLen; ++i)
     637                 :            :     {
     638                 :       3031 :         sal_Unicode c = aString.GetChar(i);
     639         [ +  + ]:       3031 :         if (c == sal_Unicode('-'))
     640                 :         62 :             ++nSignCount;
     641         [ +  + ]:       2969 :         else if (c == cDecSep)
     642                 :        275 :             ++nDecimalCount;
     643         [ +  + ]:       2694 :         else if (c == sal_Unicode('E'))
     644                 :          2 :             ++nExpCount;
     645                 :            :     }
     646                 :            : 
     647                 :            :     // #i112250# A small value might be formatted as "0" when only counting the digits,
     648                 :            :     // but fit into the column when considering the smaller width of the decimal separator.
     649 [ -  + ][ #  # ]:        275 :     if (aString.EqualsAscii("0") && fVal != 0.0)
                 [ -  + ]
     650                 :          0 :         nDecimalCount = 1;
     651                 :            : 
     652         [ +  - ]:        275 :     if (nDecimalCount)
     653                 :        275 :         nWidth += (nMaxDigit - GetDotWidth()) * nDecimalCount;
     654         [ +  + ]:        275 :     if (nSignCount)
     655                 :         62 :         nWidth += (nMaxDigit - GetSignWidth()) * nSignCount;
     656         [ +  + ]:        275 :     if (nExpCount)
     657                 :          2 :         nWidth += (nMaxDigit - GetExpWidth()) * nExpCount;
     658                 :            : 
     659 [ -  + ][ #  # ]:        275 :     if (nDecimalCount || nSignCount || nExpCount)
                 [ #  # ]
     660                 :            :     {
     661                 :            :         // Re-calculate.
     662                 :        275 :         nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit);
     663         [ -  + ]:        275 :         if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString))
     664                 :            :             // Failed to get output string.  Bail out.
     665                 :          0 :             return;
     666                 :            :     }
     667                 :            : 
     668                 :        275 :     long nActualTextWidth = pOutput->pFmtDevice->GetTextWidth(aString);
     669         [ -  + ]:        275 :     if (nActualTextWidth > nWidth)
     670                 :            :     {
     671                 :            :         // Even after the decimal adjustment the text doesn't fit.  Give up.
     672                 :          0 :         SetHashText();
     673                 :          0 :         return;
     674                 :            :     }
     675                 :            : 
     676                 :        275 :     TextChanged();
     677                 :        323 :     pLastCell = NULL;   // #i113022# equal cell and format in another column may give different string
     678                 :            : }
     679                 :            : 
     680                 :         48 : void ScDrawStringsVars::SetAutoText( const String& rAutoText )
     681                 :            : {
     682                 :         48 :     aString = rAutoText;
     683                 :            : 
     684                 :         48 :     OutputDevice* pRefDevice = pOutput->mpRefDevice;
     685                 :         48 :     OutputDevice* pFmtDevice = pOutput->pFmtDevice;
     686                 :         48 :     aTextSize.Width() = pFmtDevice->GetTextWidth( aString );
     687                 :         48 :     aTextSize.Height() = pFmtDevice->GetTextHeight();
     688                 :            : 
     689 [ #  # ][ +  - ]:         48 :     if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
                 [ -  + ]
     690                 :            :     {
     691                 :         48 :         double fMul = pOutput->GetStretch();
     692                 :         48 :         aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5);
     693                 :            :     }
     694                 :            : 
     695                 :         48 :     aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent();
     696         [ +  - ]:         48 :     if ( GetOrient() != SVX_ORIENTATION_STANDARD )
     697                 :            :     {
     698                 :         48 :         long nTemp = aTextSize.Height();
     699                 :         48 :         aTextSize.Height() = aTextSize.Width();
     700                 :         48 :         aTextSize.Width() = nTemp;
     701                 :            :     }
     702                 :            : 
     703                 :         48 :     nOriginalWidth = aTextSize.Width();
     704         [ -  + ]:         48 :     if ( bPixelToLogic )
     705                 :          0 :         aTextSize = pRefDevice->LogicToPixel( aTextSize );
     706                 :            : 
     707                 :         48 :     pLastCell = NULL;       // derselbe Text kann in der naechsten Zelle wieder passen
     708                 :         48 : }
     709                 :            : 
     710                 :        275 : long ScDrawStringsVars::GetMaxDigitWidth()
     711                 :            : {
     712         [ +  + ]:        275 :     if (nMaxDigitWidth > 0)
     713                 :        223 :         return nMaxDigitWidth;
     714                 :            : 
     715                 :         52 :     sal_Char cZero = '0';
     716         [ +  + ]:        572 :     for (sal_Char i = 0; i < 10; ++i)
     717                 :            :     {
     718                 :        520 :         sal_Char cDigit = cZero + i;
     719 [ +  - ][ +  - ]:        520 :         long n = pOutput->pFmtDevice->GetTextWidth(rtl::OUString(cDigit));
                 [ +  - ]
     720         [ +  - ]:        520 :         nMaxDigitWidth = ::std::max(nMaxDigitWidth, n);
     721                 :            :     }
     722                 :        275 :     return nMaxDigitWidth;
     723                 :            : }
     724                 :            : 
     725                 :         62 : long ScDrawStringsVars::GetSignWidth()
     726                 :            : {
     727         [ +  + ]:         62 :     if (nSignWidth > 0)
     728                 :         20 :         return nSignWidth;
     729                 :            : 
     730 [ +  - ][ +  - ]:         42 :     nSignWidth = pOutput->pFmtDevice->GetTextWidth(rtl::OUString('-'));
                 [ +  - ]
     731                 :         62 :     return nSignWidth;
     732                 :            : }
     733                 :            : 
     734                 :        275 : long ScDrawStringsVars::GetDotWidth()
     735                 :            : {
     736         [ +  + ]:        275 :     if (nDotWidth > 0)
     737                 :        223 :         return nDotWidth;
     738                 :            : 
     739                 :         52 :     const ::rtl::OUString& sep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator;
     740 [ +  - ][ +  - ]:         52 :     nDotWidth = pOutput->pFmtDevice->GetTextWidth(sep);
                 [ +  - ]
     741                 :        275 :     return nDotWidth;
     742                 :            : }
     743                 :            : 
     744                 :          2 : long ScDrawStringsVars::GetExpWidth()
     745                 :            : {
     746         [ -  + ]:          2 :     if (nExpWidth > 0)
     747                 :          0 :         return nExpWidth;
     748                 :            : 
     749 [ +  - ][ +  - ]:          2 :     nExpWidth = pOutput->pFmtDevice->GetTextWidth(rtl::OUString('E'));
                 [ +  - ]
     750                 :          2 :     return nExpWidth;
     751                 :            : }
     752                 :            : 
     753                 :      11002 : void ScDrawStringsVars::TextChanged()
     754                 :            : {
     755                 :      11002 :     OutputDevice* pRefDevice = pOutput->mpRefDevice;
     756                 :      11002 :     OutputDevice* pFmtDevice = pOutput->pFmtDevice;
     757                 :      11002 :     aTextSize.Width() = pFmtDevice->GetTextWidth( aString );
     758                 :      11002 :     aTextSize.Height() = pFmtDevice->GetTextHeight();
     759                 :            : 
     760 [ #  # ][ +  - ]:      11002 :     if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
                 [ -  + ]
     761                 :            :     {
     762                 :      11002 :         double fMul = pOutput->GetStretch();
     763                 :      11002 :         aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5);
     764                 :            :     }
     765                 :            : 
     766                 :      11002 :     aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent();
     767         [ +  + ]:      11002 :     if ( GetOrient() != SVX_ORIENTATION_STANDARD )
     768                 :            :     {
     769                 :        306 :         long nTemp = aTextSize.Height();
     770                 :        306 :         aTextSize.Height() = aTextSize.Width();
     771                 :        306 :         aTextSize.Width() = nTemp;
     772                 :            :     }
     773                 :            : 
     774                 :      11002 :     nOriginalWidth = aTextSize.Width();
     775         [ +  + ]:      11002 :     if ( bPixelToLogic )
     776                 :        960 :         aTextSize = pRefDevice->LogicToPixel( aTextSize );
     777                 :      11002 : }
     778                 :            : 
     779                 :      10909 : sal_Bool ScDrawStringsVars::HasEditCharacters() const
     780                 :            : {
     781                 :            :     static const sal_Unicode pChars[] =
     782                 :            :     {
     783                 :            :         CHAR_NBSP, CHAR_SHY, CHAR_ZWSP, CHAR_LRM, CHAR_RLM, CHAR_NBHY, CHAR_ZWNBSP, 0
     784                 :            :     };
     785                 :      10909 :     return aString.SearchChar( pChars ) != STRING_NOTFOUND;
     786                 :            : }
     787                 :            : 
     788                 :            : //==================================================================
     789                 :            : 
     790                 :      12052 : double ScOutputData::GetStretch()
     791                 :            : {
     792         [ +  + ]:      12052 :     if ( mpRefDevice->IsMapMode() )
     793                 :            :     {
     794                 :            :         //  If a non-trivial MapMode is set, its scale is now already
     795                 :            :         //  taken into account in the OutputDevice's font handling
     796                 :            :         //  (OutputDevice::ImplNewFont, see #95414#).
     797                 :            :         //  The old handling below is only needed for pixel output.
     798                 :       2008 :         return 1.0;
     799                 :            :     }
     800                 :            : 
     801                 :            :     // calculation in double is faster than Fraction multiplication
     802                 :            :     // and doesn't overflow
     803                 :            : 
     804         [ +  - ]:      10044 :     if ( mpRefDevice == pFmtDevice )
     805                 :            :     {
     806         [ +  - ]:      10044 :         MapMode aOld = mpRefDevice->GetMapMode();
     807 [ +  - ][ +  - ]:      10044 :         return ((double)aOld.GetScaleY()) / ((double)aOld.GetScaleX()) * ((double)aZoomY) / ((double)aZoomX);
         [ +  - ][ +  - ]
                 [ +  - ]
     808                 :            :     }
     809                 :            :     else
     810                 :            :     {
     811                 :            :         // when formatting for printer, device map mode has already been taken care of
     812                 :      12052 :         return ((double)aZoomY) / ((double)aZoomX);
     813                 :            :     }
     814                 :            : }
     815                 :            : 
     816                 :            : //==================================================================
     817                 :            : 
     818                 :            : //
     819                 :            : //  output strings
     820                 :            : //
     821                 :            : 
     822                 :          0 : void lcl_DoHyperlinkResult( OutputDevice* pDev, const Rectangle& rRect, ScBaseCell* pCell )
     823                 :            : {
     824 [ #  # ][ #  # ]:          0 :     vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
         [ #  # ][ #  # ]
     825                 :            : 
     826                 :          0 :     rtl::OUString aCellText;
     827                 :          0 :     rtl::OUString aURL;
     828 [ #  # ][ #  # ]:          0 :     if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
                 [ #  # ]
     829                 :            :     {
     830         [ #  # ]:          0 :         ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
     831         [ #  # ]:          0 :         if ( pFCell->IsHyperLinkCell() )
     832         [ #  # ]:          0 :             pFCell->GetURLResult( aURL, aCellText );
     833                 :            :     }
     834                 :            : 
     835 [ #  # ][ #  # ]:          0 :     if ( !aURL.isEmpty() && pPDFData )
                 [ #  # ]
     836                 :            :     {
     837                 :          0 :         vcl::PDFExtOutDevBookmarkEntry aBookmark;
     838         [ #  # ]:          0 :         aBookmark.nLinkId = pPDFData->CreateLink( rRect );
     839                 :          0 :         aBookmark.aBookmark = aURL;
     840         [ #  # ]:          0 :         std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFData->GetBookmarks();
     841         [ #  # ]:          0 :         rBookmarks.push_back( aBookmark );
     842                 :          0 :     }
     843                 :          0 : }
     844                 :            : 
     845                 :          0 : void ScOutputData::SetSyntaxColor( Font* pFont, ScBaseCell* pCell )
     846                 :            : {
     847         [ #  # ]:          0 :     if (pCell)
     848                 :            :     {
     849   [ #  #  #  # ]:          0 :         switch (pCell->GetCellType())
     850                 :            :         {
     851                 :            :             case CELLTYPE_VALUE:
     852                 :          0 :                 pFont->SetColor( *pValueColor );
     853                 :          0 :                 break;
     854                 :            :             case CELLTYPE_STRING:
     855                 :          0 :                 pFont->SetColor( *pTextColor );
     856                 :          0 :                 break;
     857                 :            :             case CELLTYPE_FORMULA:
     858                 :          0 :                 pFont->SetColor( *pFormulaColor );
     859                 :          0 :                 break;
     860                 :            :             default:
     861                 :            :             {
     862                 :            :                 // added to avoid warnings
     863                 :            :             }
     864                 :            :         }
     865                 :            :     }
     866                 :          0 : }
     867                 :            : 
     868                 :          0 : void lcl_SetEditColor( EditEngine& rEngine, const Color& rColor )
     869                 :            : {
     870         [ #  # ]:          0 :     ESelection aSel( 0, 0, rEngine.GetParagraphCount(), 0 );
     871 [ #  # ][ #  # ]:          0 :     SfxItemSet aSet( rEngine.GetEmptyItemSet() );
     872 [ #  # ][ #  # ]:          0 :     aSet.Put( SvxColorItem( rColor, EE_CHAR_COLOR ) );
                 [ #  # ]
     873 [ #  # ][ #  # ]:          0 :     rEngine.QuickSetAttribs( aSet, aSel );
     874                 :            :     // function is called with update mode set to FALSE
     875                 :          0 : }
     876                 :            : 
     877                 :          0 : void ScOutputData::SetEditSyntaxColor( EditEngine& rEngine, ScBaseCell* pCell )
     878                 :            : {
     879         [ #  # ]:          0 :     if (pCell)
     880                 :            :     {
     881                 :          0 :         Color aColor;
     882   [ #  #  #  # ]:          0 :         switch (pCell->GetCellType())
     883                 :            :         {
     884                 :            :             case CELLTYPE_VALUE:
     885                 :          0 :                 aColor = *pValueColor;
     886                 :          0 :                 break;
     887                 :            :             case CELLTYPE_STRING:
     888                 :          0 :                 aColor = *pTextColor;
     889                 :          0 :                 break;
     890                 :            :             case CELLTYPE_FORMULA:
     891                 :          0 :                 aColor = *pFormulaColor;
     892                 :          0 :                 break;
     893                 :            :             default:
     894                 :            :             {
     895                 :            :                 // added to avoid warnings
     896                 :            :             }
     897                 :            :         }
     898         [ #  # ]:          0 :         lcl_SetEditColor( rEngine, aColor );
     899                 :            :     }
     900                 :          0 : }
     901                 :            : 
     902                 :         34 : sal_Bool ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY,
     903                 :            :                                     SCCOL& rOverX, SCROW& rOverY,
     904                 :            :                                     sal_Bool bVisRowChanged )
     905                 :            : {
     906                 :         34 :     sal_Bool bDoMerge = false;
     907                 :         34 :     sal_Bool bIsLeft = ( nX == nVisX1 );
     908 [ +  + ][ -  + ]:         34 :     sal_Bool bIsTop  = ( nY == nVisY1 ) || bVisRowChanged;
     909                 :            : 
     910                 :         34 :     CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
     911 [ +  + ][ +  + ]:         34 :     if ( pInfo->bHOverlapped && pInfo->bVOverlapped )
     912 [ -  + ][ #  # ]:         21 :         bDoMerge = bIsLeft && bIsTop;
     913         [ +  + ]:         13 :     else if ( pInfo->bHOverlapped )
     914                 :          6 :         bDoMerge = bIsLeft;
     915         [ +  - ]:          7 :     else if ( pInfo->bVOverlapped )
     916                 :          7 :         bDoMerge = bIsTop;
     917                 :            : 
     918                 :         34 :     rOverX = nX;
     919                 :         34 :     rOverY = nY;
     920                 :         34 :     sal_Bool bHOver = pInfo->bHOverlapped;
     921                 :         34 :     sal_Bool bVOver = pInfo->bVOverlapped;
     922                 :            :     sal_Bool bHidden;
     923                 :            : 
     924         [ +  + ]:         34 :     while (bHOver)              // nY konstant
     925                 :            :     {
     926                 :         27 :         --rOverX;
     927                 :         27 :         bHidden = mpDoc->ColHidden(rOverX, nTab);
     928 [ +  - ][ +  - ]:         27 :         if ( !bDoMerge && !bHidden )
     929                 :         27 :             return false;
     930                 :            : 
     931 [ #  # ][ #  # ]:          0 :         if (rOverX >= nX1 && !bHidden)
     932                 :            :         {
     933                 :          0 :             bHOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bHOverlapped;
     934                 :          0 :             bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
     935                 :            :         }
     936                 :            :         else
     937                 :            :         {
     938                 :            :             sal_uInt16 nOverlap = ((ScMergeFlagAttr*)mpDoc->GetAttr(
     939                 :          0 :                                 rOverX, rOverY, nTab, ATTR_MERGE_FLAG ))->GetValue();
     940                 :          0 :             bHOver = ((nOverlap & SC_MF_HOR) != 0);
     941                 :          0 :             bVOver = ((nOverlap & SC_MF_VER) != 0);
     942                 :            :         }
     943                 :            :     }
     944                 :            : 
     945         [ +  - ]:          7 :     while (bVOver)
     946                 :            :     {
     947                 :          7 :         --rOverY;
     948                 :          7 :         bHidden = mpDoc->RowHidden(rOverY, nTab);
     949 [ +  - ][ +  - ]:          7 :         if ( !bDoMerge && !bHidden )
     950                 :          7 :             return false;
     951                 :            : 
     952         [ #  # ]:          0 :         if (nArrY>0)
     953                 :          0 :             --nArrY;                        // lokale Kopie !
     954                 :            : 
     955 [ #  # ][ #  #  :          0 :         if (rOverX >= nX1 && rOverY >= nY1 &&
             #  #  #  # ]
         [ #  # ][ #  # ]
     956                 :          0 :             !mpDoc->ColHidden(rOverX, nTab) &&
     957                 :          0 :             !mpDoc->RowHidden(rOverY, nTab) &&
     958                 :          0 :             pRowInfo[nArrY].nRowNo == rOverY)
     959                 :            :         {
     960                 :          0 :             bHOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bHOverlapped;
     961                 :          0 :             bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
     962                 :            :         }
     963                 :            :         else
     964                 :            :         {
     965                 :            :             sal_uInt16 nOverlap = ((ScMergeFlagAttr*)mpDoc->GetAttr(
     966                 :          0 :                                 rOverX, rOverY, nTab, ATTR_MERGE_FLAG ))->GetValue();
     967                 :          0 :             bHOver = ((nOverlap & SC_MF_HOR) != 0);
     968                 :          0 :             bVOver = ((nOverlap & SC_MF_VER) != 0);
     969                 :            :         }
     970                 :            :     }
     971                 :            : 
     972                 :         34 :     return sal_True;
     973                 :            : }
     974                 :            : 
     975                 :       2063 : inline sal_Bool StringDiffer( const ScPatternAttr*& rpOldPattern, const ScPatternAttr*& rpNewPattern )
     976                 :            : {
     977                 :            :     OSL_ENSURE( rpNewPattern, "pNewPattern" );
     978                 :            : 
     979         [ +  + ]:       2063 :     if ( rpNewPattern == rpOldPattern )
     980                 :          4 :         return false;
     981         [ +  + ]:       2059 :     else if ( !rpOldPattern )
     982                 :        907 :         return sal_True;
     983         [ +  + ]:       1152 :     else if ( &rpNewPattern->GetItem( ATTR_FONT ) != &rpOldPattern->GetItem( ATTR_FONT ) )
     984                 :        146 :         return sal_True;
     985         [ +  + ]:       1006 :     else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT ) )
     986                 :         58 :         return sal_True;
     987         [ +  + ]:        948 :     else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT ) )
     988                 :         20 :         return sal_True;
     989         [ -  + ]:        928 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_HEIGHT ) )
     990                 :          0 :         return sal_True;
     991         [ +  + ]:        928 :     else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) )
     992                 :         14 :         return sal_True;
     993         [ +  + ]:        914 :     else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) )
     994                 :         10 :         return sal_True;
     995         [ +  + ]:        904 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_WEIGHT ) )
     996                 :        152 :         return sal_True;
     997         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) )
     998                 :          0 :         return sal_True;
     999         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) )
    1000                 :          0 :         return sal_True;
    1001         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_FONT_POSTURE ) )
    1002                 :          0 :         return sal_True;
    1003         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_POSTURE ) )
    1004                 :          0 :         return sal_True;
    1005         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_POSTURE ) )
    1006                 :          0 :         return sal_True;
    1007         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_UNDERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_UNDERLINE ) )
    1008                 :          0 :         return sal_True;
    1009         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_OVERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_OVERLINE ) )
    1010                 :          0 :         return sal_True;
    1011         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_WORDLINE ) != &rpOldPattern->GetItem( ATTR_FONT_WORDLINE ) )
    1012                 :          0 :         return sal_True;
    1013         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_CROSSEDOUT ) != &rpOldPattern->GetItem( ATTR_FONT_CROSSEDOUT ) )
    1014                 :          0 :         return sal_True;
    1015         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_CONTOUR ) != &rpOldPattern->GetItem( ATTR_FONT_CONTOUR ) )
    1016                 :          0 :         return sal_True;
    1017         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_SHADOWED ) != &rpOldPattern->GetItem( ATTR_FONT_SHADOWED ) )
    1018                 :          0 :         return sal_True;
    1019         [ -  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_COLOR ) != &rpOldPattern->GetItem( ATTR_FONT_COLOR ) )
    1020                 :          0 :         return sal_True;
    1021         [ +  + ]:        752 :     else if ( &rpNewPattern->GetItem( ATTR_HOR_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_HOR_JUSTIFY ) )
    1022                 :        192 :         return true;
    1023         [ -  + ]:        560 :     else if ( &rpNewPattern->GetItem( ATTR_HOR_JUSTIFY_METHOD ) != &rpOldPattern->GetItem( ATTR_HOR_JUSTIFY_METHOD ) )
    1024                 :          0 :         return true;
    1025         [ -  + ]:        560 :     else if ( &rpNewPattern->GetItem( ATTR_VER_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_VER_JUSTIFY ) )
    1026                 :          0 :         return true;
    1027         [ -  + ]:        560 :     else if ( &rpNewPattern->GetItem( ATTR_VER_JUSTIFY_METHOD ) != &rpOldPattern->GetItem( ATTR_VER_JUSTIFY_METHOD ) )
    1028                 :          0 :         return true;
    1029         [ -  + ]:        560 :     else if ( &rpNewPattern->GetItem( ATTR_STACKED ) != &rpOldPattern->GetItem( ATTR_STACKED ) )
    1030                 :          0 :         return sal_True;
    1031         [ +  + ]:        560 :     else if ( &rpNewPattern->GetItem( ATTR_LINEBREAK ) != &rpOldPattern->GetItem( ATTR_LINEBREAK ) )
    1032                 :         80 :         return sal_True;
    1033         [ -  + ]:        480 :     else if ( &rpNewPattern->GetItem( ATTR_MARGIN ) != &rpOldPattern->GetItem( ATTR_MARGIN ) )
    1034                 :          0 :         return sal_True;
    1035         [ -  + ]:        480 :     else if ( &rpNewPattern->GetItem( ATTR_ROTATE_VALUE ) != &rpOldPattern->GetItem( ATTR_ROTATE_VALUE ) )
    1036                 :          0 :         return sal_True;
    1037         [ -  + ]:        480 :     else if ( &rpNewPattern->GetItem( ATTR_FORBIDDEN_RULES ) != &rpOldPattern->GetItem( ATTR_FORBIDDEN_RULES ) )
    1038                 :          0 :         return sal_True;
    1039         [ -  + ]:        480 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_EMPHASISMARK ) != &rpOldPattern->GetItem( ATTR_FONT_EMPHASISMARK ) )
    1040                 :          0 :         return sal_True;
    1041         [ -  + ]:        480 :     else if ( &rpNewPattern->GetItem( ATTR_FONT_RELIEF ) != &rpOldPattern->GetItem( ATTR_FONT_RELIEF ) )
    1042                 :          0 :         return sal_True;
    1043         [ -  + ]:        480 :     else if ( &rpNewPattern->GetItem( ATTR_BACKGROUND ) != &rpOldPattern->GetItem( ATTR_BACKGROUND ) )
    1044                 :          0 :         return sal_True;    // needed with automatic text color
    1045                 :            :     else
    1046                 :            :     {
    1047                 :        480 :         rpOldPattern = rpNewPattern;
    1048                 :       2063 :         return false;
    1049                 :            :     }
    1050                 :            : }
    1051                 :            : 
    1052                 :        270 : inline void lcl_CreateInterpretProgress( sal_Bool& bProgress, ScDocument* pDoc,
    1053                 :            :         ScFormulaCell* pFCell )
    1054                 :            : {
    1055 [ +  - ][ -  + ]:        270 :     if ( !bProgress && pFCell->GetDirty() )
                 [ -  + ]
    1056                 :            :     {
    1057                 :          0 :         ScProgress::CreateInterpretProgress( pDoc, sal_True );
    1058                 :          0 :         bProgress = sal_True;
    1059                 :            :     }
    1060                 :        270 : }
    1061                 :            : 
    1062                 :      11486 : inline sal_uInt8 GetScriptType( ScDocument* pDoc, ScBaseCell* pCell,
    1063                 :            :                             const ScPatternAttr* pPattern,
    1064                 :            :                             const SfxItemSet* pCondSet )
    1065                 :            : {
    1066                 :      11486 :     return pDoc->GetCellScriptType( pCell, pPattern->GetNumberFormat( pDoc->GetFormatTable(), pCondSet ) );
    1067                 :            : }
    1068                 :            : 
    1069                 :          0 : inline sal_Bool IsAmbiguousScript( sal_uInt8 nScript )
    1070                 :            : {
    1071                 :            :     return ( nScript != SCRIPTTYPE_LATIN &&
    1072                 :            :              nScript != SCRIPTTYPE_ASIAN &&
    1073 [ #  # ][ #  # ]:          0 :              nScript != SCRIPTTYPE_COMPLEX );
                 [ #  # ]
    1074                 :            : }
    1075                 :            : 
    1076                 :       5017 : sal_Bool ScOutputData::IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW nY )
    1077                 :            : {
    1078                 :            :     // pThisRowInfo may be NULL
    1079                 :            : 
    1080                 :            :     sal_Bool bEmpty;
    1081 [ +  + ][ +  + ]:       5017 :     if ( pThisRowInfo && nX <= nX2 )
    1082                 :       2647 :         bEmpty = pThisRowInfo->pCellInfo[nX+1].bEmptyCellText;
    1083                 :            :     else
    1084         [ +  - ]:       2370 :         bEmpty = ( mpDoc->GetCell( ScAddress( nX, nY, nTab ) ) == NULL );
    1085                 :            : 
    1086 [ +  + ][ +  + ]:       5017 :     if ( !bEmpty && ( nX < nX1 || nX > nX2 || !pThisRowInfo ) )
         [ +  + ][ +  + ]
    1087                 :            :     {
    1088                 :            :         //  for the range nX1..nX2 in RowInfo, cell protection attribute is already evaluated
    1089                 :            :         //  into bEmptyCellText in ScDocument::FillInfo / lcl_HidePrint (printfun)
    1090                 :            : 
    1091                 :        318 :         sal_Bool bIsPrint = ( eType == OUTTYPE_PRINTER );
    1092                 :            : 
    1093 [ +  - ][ -  + ]:        318 :         if ( bIsPrint || bTabProtected )
    1094                 :            :         {
    1095                 :            :             const ScProtectionAttr* pAttr = (const ScProtectionAttr*)
    1096                 :          0 :                     mpDoc->GetEffItem( nX, nY, nTab, ATTR_PROTECTION );
    1097 [ #  # ][ #  # ]:          0 :             if ( bIsPrint && pAttr->GetHidePrint() )
                 [ #  # ]
    1098                 :          0 :                 bEmpty = sal_True;
    1099         [ #  # ]:          0 :             else if ( bTabProtected )
    1100                 :            :             {
    1101         [ #  # ]:          0 :                 if ( pAttr->GetHideCell() )
    1102                 :          0 :                     bEmpty = sal_True;
    1103 [ #  # ][ #  # ]:          0 :                 else if ( mbShowFormulas && pAttr->GetHideFormula() )
                 [ #  # ]
    1104                 :            :                 {
    1105         [ #  # ]:          0 :                     ScBaseCell* pCell = mpDoc->GetCell( ScAddress( nX, nY, nTab ) );
    1106 [ #  # ][ #  # ]:          0 :                     if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
                 [ #  # ]
    1107                 :          0 :                         bEmpty = sal_True;
    1108                 :            :                 }
    1109                 :            :             }
    1110                 :            :         }
    1111                 :            :     }
    1112                 :       5017 :     return bEmpty;
    1113                 :            : }
    1114                 :            : 
    1115                 :         98 : void ScOutputData::GetVisibleCell( SCCOL nCol, SCROW nRow, SCTAB nTabP, ScBaseCell*& rpCell )
    1116                 :            : {
    1117                 :         98 :     mpDoc->GetCell( nCol, nRow, nTabP, rpCell );
    1118 [ -  + ][ -  + ]:         98 :     if ( rpCell && IsEmptyCellText( NULL, nCol, nRow ) )
                 [ +  - ]
    1119                 :          0 :         rpCell = NULL;
    1120                 :         98 : }
    1121                 :            : 
    1122                 :        343 : sal_Bool ScOutputData::IsAvailable( SCCOL nX, SCROW nY )
    1123                 :            : {
    1124                 :            :     //  apply the same logic here as in DrawStrings/DrawEdit:
    1125                 :            :     //  Stop at non-empty or merged or overlapped cell,
    1126                 :            :     //  where a note is empty as well as a cell that's hidden by protection settings
    1127                 :            : 
    1128         [ +  - ]:        343 :     const ScBaseCell* pCell = mpDoc->GetCell( ScAddress( nX, nY, nTab ) );
    1129 [ +  + ][ +  - ]:        343 :     if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE && !IsEmptyCellText( NULL, nX, nY ) )
         [ +  - ][ +  + ]
    1130                 :            :     {
    1131                 :         28 :         return false;
    1132                 :            :     }
    1133                 :            : 
    1134                 :        315 :     const ScPatternAttr* pPattern = mpDoc->GetPattern( nX, nY, nTab );
    1135         [ -  + ]:        630 :     if ( ((const ScMergeAttr&)pPattern->GetItem(ATTR_MERGE)).IsMerged() ||
           [ +  -  -  + ]
    1136                 :        315 :          ((const ScMergeFlagAttr&)pPattern->GetItem(ATTR_MERGE_FLAG)).IsOverlapped() )
    1137                 :            :     {
    1138                 :          0 :         return false;
    1139                 :            :     }
    1140                 :            : 
    1141                 :        343 :     return sal_True;
    1142                 :            : }
    1143                 :            : 
    1144                 :            : // nX, nArrY:       loop variables from DrawStrings / DrawEdit
    1145                 :            : // nPosX, nPosY:    corresponding positions for nX, nArrY
    1146                 :            : // nCellX, nCellY:  position of the cell that contains the text
    1147                 :            : // nNeeded:         Text width, including margin
    1148                 :            : // rPattern:        cell format at nCellX, nCellY
    1149                 :            : // nHorJustify:     horizontal alignment (visual) to determine which cells to use for long strings
    1150                 :            : // bCellIsValue:    if set, don't extend into empty cells
    1151                 :            : // bBreak:          if set, don't extend, and don't set clip marks (but rLeftClip/rRightClip is set)
    1152                 :            : // bOverwrite:      if set, also extend into non-empty cells (for rotated text)
    1153                 :            : // rParam           output: various area parameters.
    1154                 :            : 
    1155                 :      11942 : void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY,
    1156                 :            :                                   SCCOL nCellX, SCROW nCellY, long nNeeded,
    1157                 :            :                                   const ScPatternAttr& rPattern,
    1158                 :            :                                   sal_uInt16 nHorJustify, bool bCellIsValue,
    1159                 :            :                                   bool bBreak, bool bOverwrite,
    1160                 :            :                                   OutputAreaParam& rParam )
    1161                 :            : {
    1162                 :            :     //  rThisRowInfo may be for a different row than nCellY, is still used for clip marks
    1163                 :      11942 :     RowInfo& rThisRowInfo = pRowInfo[nArrY];
    1164                 :            : 
    1165         [ -  + ]:      11942 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
    1166                 :            : 
    1167                 :      11942 :     long nCellPosX = nPosX;         // find nCellX position, starting at nX/nPosX
    1168                 :      11942 :     SCCOL nCompCol = nX;
    1169         [ +  + ]:      12522 :     while ( nCellX > nCompCol )
    1170                 :            :     {
    1171                 :            :         //! extra member function for width?
    1172                 :            :         long nColWidth = ( nCompCol <= nX2 ) ?
    1173                 :         80 :                 pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
    1174         [ +  + ]:        580 :                 (long) ( mpDoc->GetColWidth( nCompCol, nTab ) * mnPPTX );
    1175                 :        580 :         nCellPosX += nColWidth * nLayoutSign;
    1176                 :        580 :         ++nCompCol;
    1177                 :            :     }
    1178         [ +  + ]:      11955 :     while ( nCellX < nCompCol )
    1179                 :            :     {
    1180                 :         13 :         --nCompCol;
    1181                 :            :         long nColWidth = ( nCompCol <= nX2 ) ?
    1182                 :         13 :                 pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
    1183         [ +  - ]:         13 :                 (long) ( mpDoc->GetColWidth( nCompCol, nTab ) * mnPPTX );
    1184                 :         13 :         nCellPosX -= nColWidth * nLayoutSign;
    1185                 :            :     }
    1186                 :            : 
    1187                 :      11942 :     long nCellPosY = nPosY;         // find nCellY position, starting at nArrY/nPosY
    1188                 :      11942 :     SCSIZE nCompArr = nArrY;
    1189                 :      11942 :     SCROW nCompRow = pRowInfo[nCompArr].nRowNo;
    1190         [ -  + ]:      11942 :     while ( nCellY > nCompRow )
    1191                 :            :     {
    1192         [ #  # ]:          0 :         if ( nCompArr + 1 < nArrCount )
    1193                 :            :         {
    1194                 :          0 :             nCellPosY += pRowInfo[nCompArr].nHeight;
    1195                 :          0 :             ++nCompArr;
    1196                 :          0 :             nCompRow = pRowInfo[nCompArr].nRowNo;
    1197                 :            :         }
    1198                 :            :         else
    1199                 :            :         {
    1200                 :          0 :             sal_uInt16 nDocHeight = mpDoc->GetRowHeight( nCompRow, nTab );
    1201         [ #  # ]:          0 :             if ( nDocHeight )
    1202                 :          0 :                 nCellPosY += (long) ( nDocHeight * mnPPTY );
    1203                 :          0 :             ++nCompRow;
    1204                 :            :         }
    1205                 :            :     }
    1206                 :      11942 :     nCellPosY -= (long) mpDoc->GetScaledRowHeight( nCellY, nCompRow-1, nTab, mnPPTY );
    1207                 :            : 
    1208                 :      11942 :     const ScMergeAttr* pMerge = (const ScMergeAttr*)&rPattern.GetItem( ATTR_MERGE );
    1209                 :      11942 :     sal_Bool bMerged = pMerge->IsMerged();
    1210                 :      11942 :     long nMergeCols = pMerge->GetColMerge();
    1211         [ +  - ]:      11942 :     if ( nMergeCols == 0 )
    1212                 :      11942 :         nMergeCols = 1;
    1213                 :      11942 :     long nMergeRows = pMerge->GetRowMerge();
    1214         [ +  - ]:      11942 :     if ( nMergeRows == 0 )
    1215                 :      11942 :         nMergeRows = 1;
    1216                 :            : 
    1217                 :            :     long i;
    1218                 :      11942 :     long nMergeSizeX = 0;
    1219         [ +  + ]:      23884 :     for ( i=0; i<nMergeCols; i++ )
    1220                 :            :     {
    1221                 :            :         long nColWidth = ( nCellX+i <= nX2 ) ?
    1222                 :      11862 :                 pRowInfo[0].pCellInfo[nCellX+i+1].nWidth :
    1223         [ +  + ]:      11942 :                 (long) ( mpDoc->GetColWidth( sal::static_int_cast<SCCOL>(nCellX+i), nTab ) * mnPPTX );
    1224                 :      11942 :         nMergeSizeX += nColWidth;
    1225                 :            :     }
    1226                 :      11942 :     long nMergeSizeY = 0;
    1227                 :      11942 :     short nDirect = 0;
    1228         [ +  - ]:      11942 :     if ( rThisRowInfo.nRowNo == nCellY )
    1229                 :            :     {
    1230                 :            :         // take first row's height from row info
    1231                 :      11942 :         nMergeSizeY += rThisRowInfo.nHeight;
    1232                 :      11942 :         nDirect = 1;        // skip in loop
    1233                 :            :     }
    1234                 :            :     // following rows always from document
    1235                 :      11942 :     nMergeSizeY += (long) mpDoc->GetScaledRowHeight( nCellY+nDirect, nCellY+nMergeRows-1, nTab, mnPPTY);
    1236                 :            : 
    1237                 :      11942 :     --nMergeSizeX;      // leave out the grid horizontally, also for alignment (align between grid lines)
    1238                 :            : 
    1239                 :      11942 :     rParam.mnColWidth = nMergeSizeX; // store the actual column width.
    1240                 :            : 
    1241                 :            :     //
    1242                 :            :     // construct the rectangles using logical left/right values (justify is called at the end)
    1243                 :            :     //
    1244                 :            : 
    1245                 :            :     //  rAlignRect is the single cell or merged area, used for alignment.
    1246                 :            : 
    1247                 :      11942 :     rParam.maAlignRect.Left() = nCellPosX;
    1248                 :      11942 :     rParam.maAlignRect.Right() = nCellPosX + ( nMergeSizeX - 1 ) * nLayoutSign;
    1249                 :      11942 :     rParam.maAlignRect.Top() = nCellPosY;
    1250                 :      11942 :     rParam.maAlignRect.Bottom() = nCellPosY + nMergeSizeY - 1;
    1251                 :            : 
    1252                 :            :     //  rClipRect is all cells that are used for output.
    1253                 :            :     //  For merged cells this is the same as rAlignRect, otherwise neighboring cells can also be used.
    1254                 :            : 
    1255                 :      11942 :     rParam.maClipRect = rParam.maAlignRect;
    1256         [ +  + ]:      11942 :     if ( nNeeded > nMergeSizeX )
    1257                 :            :     {
    1258                 :       1273 :         SvxCellHorJustify eHorJust = (SvxCellHorJustify)nHorJustify;
    1259                 :            : 
    1260                 :       1273 :         long nMissing = nNeeded - nMergeSizeX;
    1261                 :       1273 :         long nLeftMissing = 0;
    1262                 :       1273 :         long nRightMissing = 0;
    1263   [ +  +  +  + ]:       1273 :         switch ( eHorJust )
    1264                 :            :         {
    1265                 :            :             case SVX_HOR_JUSTIFY_LEFT:
    1266                 :        359 :                 nRightMissing = nMissing;
    1267                 :        359 :                 break;
    1268                 :            :             case SVX_HOR_JUSTIFY_RIGHT:
    1269                 :        457 :                 nLeftMissing = nMissing;
    1270                 :        457 :                 break;
    1271                 :            :             case SVX_HOR_JUSTIFY_CENTER:
    1272                 :        244 :                 nLeftMissing = nMissing / 2;
    1273                 :        244 :                 nRightMissing = nMissing - nLeftMissing;
    1274                 :        244 :                 break;
    1275                 :            :             default:
    1276                 :            :             {
    1277                 :            :                 // added to avoid warnings
    1278                 :            :             }
    1279                 :            :         }
    1280                 :            : 
    1281                 :            :         // nLeftMissing, nRightMissing are logical, eHorJust values are visual
    1282         [ -  + ]:       1273 :         if ( bLayoutRTL )
    1283                 :          0 :             ::std::swap( nLeftMissing, nRightMissing );
    1284                 :            : 
    1285                 :       1273 :         SCCOL nRightX = nCellX;
    1286                 :       1273 :         SCCOL nLeftX = nCellX;
    1287 [ +  - ][ +  + ]:       1273 :         if ( !bMerged && !bCellIsValue && !bBreak )
                 [ +  + ]
    1288                 :            :         {
    1289                 :            :             //  look for empty cells into which the text can be extended
    1290                 :            : 
    1291 [ +  + ][ +  - ]:       1316 :             while ( nRightMissing > 0 && nRightX < MAXCOL && ( bOverwrite || IsAvailable( nRightX+1, nCellY ) ) )
         [ +  + ][ +  - ]
         [ +  + ][ +  + ]
    1292                 :            :             {
    1293                 :        537 :                 ++nRightX;
    1294         [ +  - ]:        537 :                 long nAdd = (long) ( mpDoc->GetColWidth( nRightX, nTab ) * mnPPTX );
    1295                 :        537 :                 nRightMissing -= nAdd;
    1296                 :        537 :                 rParam.maClipRect.Right() += nAdd * nLayoutSign;
    1297                 :            : 
    1298 [ +  + ][ +  + ]:        537 :                 if ( rThisRowInfo.nRowNo == nCellY && nRightX >= nX1 && nRightX <= nX2 )
                 [ +  - ]
    1299                 :        524 :                     rThisRowInfo.pCellInfo[nRightX].bHideGrid = sal_True;
    1300                 :            :             }
    1301                 :            : 
    1302 [ +  + ][ +  + ]:       1063 :             while ( nLeftMissing > 0 && nLeftX > 0 && ( bOverwrite || IsAvailable( nLeftX-1, nCellY ) ) )
         [ -  + ][ #  # ]
         [ #  # ][ +  + ]
    1303                 :            :             {
    1304 [ +  - ][ +  - ]:        284 :                 if ( rThisRowInfo.nRowNo == nCellY && nLeftX >= nX1 && nLeftX <= nX2 )
                 [ +  - ]
    1305                 :        284 :                     rThisRowInfo.pCellInfo[nLeftX].bHideGrid = sal_True;
    1306                 :            : 
    1307                 :        284 :                 --nLeftX;
    1308         [ +  - ]:        284 :                 long nAdd = (long) ( mpDoc->GetColWidth( nLeftX, nTab ) * mnPPTX );
    1309                 :        284 :                 nLeftMissing -= nAdd;
    1310                 :        284 :                 rParam.maClipRect.Left() -= nAdd * nLayoutSign;
    1311                 :            :             }
    1312                 :            :         }
    1313                 :            : 
    1314                 :            :         //  Set flag and reserve space for clipping mark triangle,
    1315                 :            :         //  even if rThisRowInfo isn't for nCellY (merged cells).
    1316 [ +  + ][ +  - ]:       1273 :         if ( nRightMissing > 0 && bMarkClipped && nRightX >= nX1 && nRightX <= nX2 && !bBreak && !bCellIsValue )
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
    1317                 :            :         {
    1318                 :         28 :             rThisRowInfo.pCellInfo[nRightX+1].nClipMark |= SC_CLIPMARK_RIGHT;
    1319                 :         28 :             bAnyClipped = sal_True;
    1320                 :         28 :             long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
    1321                 :         28 :             rParam.maClipRect.Right() -= nMarkPixel * nLayoutSign;
    1322                 :            :         }
    1323 [ +  + ][ +  - ]:       1273 :         if ( nLeftMissing > 0 && bMarkClipped && nLeftX >= nX1 && nLeftX <= nX2 && !bBreak && !bCellIsValue )
         [ +  + ][ +  - ]
         [ +  - ][ +  + ]
    1324                 :            :         {
    1325                 :        134 :             rThisRowInfo.pCellInfo[nLeftX+1].nClipMark |= SC_CLIPMARK_LEFT;
    1326                 :        134 :             bAnyClipped = sal_True;
    1327                 :        134 :             long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
    1328                 :        134 :             rParam.maClipRect.Left() += nMarkPixel * nLayoutSign;
    1329                 :            :         }
    1330                 :            : 
    1331                 :       1273 :         rParam.mbLeftClip = ( nLeftMissing > 0 );
    1332                 :       1273 :         rParam.mbRightClip = ( nRightMissing > 0 );
    1333                 :            :     }
    1334                 :            :     else
    1335                 :            :     {
    1336                 :      10669 :         rParam.mbLeftClip = rParam.mbRightClip = false;
    1337                 :            : 
    1338                 :            :         // leave space for AutoFilter on screen
    1339                 :            :         // (for automatic line break: only if not formatting for printer, as in ScColumn::GetNeededSize)
    1340                 :            : 
    1341   [ +  +  +  + ]:      21288 :         if ( eType==OUTTYPE_WINDOW &&
         [ -  + ][ #  # ]
                 [ +  + ]
    1342                 :      10619 :              ( static_cast<const ScMergeFlagAttr&>(rPattern.GetItem(ATTR_MERGE_FLAG)).GetValue() & SC_MF_AUTO ) &&
    1343                 :          2 :              ( !bBreak || mpRefDevice == pFmtDevice ) )
    1344                 :            :         {
    1345                 :            :             // filter drop-down width is now independent from row height
    1346                 :          2 :             const long nFilter = DROPDOWN_BITMAP_SIZE;
    1347                 :          2 :             sal_Bool bFit = ( nNeeded + nFilter <= nMergeSizeX );
    1348 [ -  + ][ #  # ]:          2 :             if ( bFit || bCellIsValue )
    1349                 :            :             {
    1350                 :            :                 // content fits even in the remaining area without the filter button
    1351                 :            :                 // -> align within that remaining area
    1352                 :            : 
    1353                 :          2 :                 rParam.maAlignRect.Right() -= nFilter * nLayoutSign;
    1354                 :          2 :                 rParam.maClipRect.Right() -= nFilter * nLayoutSign;
    1355                 :            : 
    1356                 :            :                 // if a number doesn't fit, don't hide part of the number behind the button
    1357                 :            :                 // -> set clip flags, so "###" replacement is used (but also within the smaller area)
    1358                 :            : 
    1359         [ -  + ]:          2 :                 if ( !bFit )
    1360                 :          0 :                     rParam.mbLeftClip = rParam.mbRightClip = sal_True;
    1361                 :            :             }
    1362                 :            :         }
    1363                 :            :     }
    1364                 :            : 
    1365                 :            :     //  justify both rectangles for alignment calculation, use with DrawText etc.
    1366                 :            : 
    1367                 :      11942 :     rParam.maAlignRect.Justify();
    1368                 :      11942 :     rParam.maClipRect.Justify();
    1369                 :      11942 : }
    1370                 :            : 
    1371                 :            : namespace {
    1372                 :            : 
    1373                 :      10931 : bool beginsWithRTLCharacter(const rtl::OUString& rStr)
    1374                 :            : {
    1375         [ -  + ]:      10931 :     if (rStr.isEmpty())
    1376                 :          0 :         return false;
    1377                 :            : 
    1378 [ +  - ][ -  + ]:      10931 :     switch (ScGlobal::pCharClass->getCharacterDirection(rStr, 0))
    1379                 :            :     {
    1380                 :            :         case i18n::DirectionProperty_RIGHT_TO_LEFT:
    1381                 :            :         case i18n::DirectionProperty_RIGHT_TO_LEFT_ARABIC:
    1382                 :            :         case i18n::DirectionProperty_RIGHT_TO_LEFT_EMBEDDING:
    1383                 :            :         case i18n::DirectionProperty_RIGHT_TO_LEFT_OVERRIDE:
    1384                 :          0 :             return true;
    1385                 :            :         default:
    1386                 :            :             ;
    1387                 :            :     }
    1388                 :            : 
    1389                 :      10931 :     return false;
    1390                 :            : }
    1391                 :            : 
    1392                 :            : }
    1393                 :            : 
    1394                 :       1345 : void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
    1395                 :            : {
    1396                 :            :     OSL_ENSURE( mpDev == mpRefDevice ||
    1397                 :            :                 mpDev->GetMapMode().GetMapUnit() == mpRefDevice->GetMapMode().GetMapUnit(),
    1398                 :            :                 "DrawStrings: unterschiedliche MapUnits ?!?!" );
    1399                 :            : 
    1400 [ -  + ][ #  # ]:       1345 :     vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, mpDev->GetExtOutDevData() );
         [ #  # ][ #  # ]
    1401                 :            : 
    1402                 :       1345 :     sal_Bool bWasIdleDisabled = mpDoc->IsIdleDisabled();
    1403                 :       1345 :     mpDoc->DisableIdle( true );
    1404                 :            : 
    1405         [ +  - ]:       1345 :     ScDrawStringsVars aVars( this, bPixelToLogic );
    1406                 :            : 
    1407                 :       1345 :     sal_Bool bProgress = false;
    1408                 :            : 
    1409                 :       1345 :     long nInitPosX = nScrX;
    1410         [ +  + ]:       1345 :     if ( bLayoutRTL )
    1411                 :          2 :         nInitPosX += nMirrorW - 1;              // pixels
    1412         [ +  + ]:       1345 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
    1413                 :            : 
    1414                 :       1345 :     SCCOL nLastContentCol = MAXCOL;
    1415         [ +  - ]:       1345 :     if ( nX2 < MAXCOL )
    1416                 :            :         nLastContentCol = sal::static_int_cast<SCCOL>(
    1417         [ +  - ]:       1345 :             nLastContentCol - mpDoc->GetEmptyLinesInBlock( nX2+1, nY1, nTab, MAXCOL, nY2, nTab, DIR_RIGHT ) );
    1418                 :       1345 :     SCCOL nLoopStartX = nX1;
    1419         [ +  + ]:       1345 :     if ( nX1 > 0 )
    1420                 :        294 :         --nLoopStartX;          // start before nX1 for rest of long text to the left
    1421                 :            : 
    1422                 :            :     // variables for GetOutputArea
    1423         [ +  - ]:       1345 :     OutputAreaParam aAreaParam;
    1424                 :       1345 :     sal_Bool bCellIsValue = false;
    1425                 :       1345 :     long nNeededWidth = 0;
    1426                 :       1345 :     SvxCellHorJustify eOutHorJust = SVX_HOR_JUSTIFY_STANDARD;
    1427                 :       1345 :     const ScPatternAttr* pPattern = NULL;
    1428                 :       1345 :     const SfxItemSet* pCondSet = NULL;
    1429                 :       1345 :     const ScPatternAttr* pOldPattern = NULL;
    1430                 :       1345 :     const SfxItemSet* pOldCondSet = NULL;
    1431                 :       1345 :     sal_uInt8 nOldScript = 0;
    1432                 :            : 
    1433                 :            :     // alternative pattern instances in case we need to modify the pattern
    1434                 :            :     // before processing the cell value.
    1435         [ +  - ]:       1345 :     ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
    1436                 :            : 
    1437                 :       1345 :     long nPosY = nScrY;
    1438         [ +  + ]:      17212 :     for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
    1439                 :            :     {
    1440                 :      15867 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
    1441         [ +  - ]:      15867 :         if ( pThisRowInfo->bChanged )
    1442                 :            :         {
    1443                 :      15867 :             SCROW nY = pThisRowInfo->nRowNo;
    1444                 :      15867 :             long nPosX = nInitPosX;
    1445         [ +  + ]:      15867 :             if ( nLoopStartX < nX1 )
    1446                 :       1340 :                 nPosX -= pRowInfo[0].pCellInfo[nLoopStartX+1].nWidth * nLayoutSign;
    1447         [ +  + ]:     168304 :             for (SCCOL nX=nLoopStartX; nX<=nX2; nX++)
    1448                 :            :             {
    1449                 :     152437 :                 sal_Bool bMergeEmpty = false;
    1450                 :     152437 :                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
    1451 [ +  + ][ +  + ]:     152437 :                 sal_Bool bEmpty = nX < nX1 || pInfo->bEmptyCellText;
    1452                 :            : 
    1453                 :     152437 :                 SCCOL nCellX = nX;                  // position where the cell really starts
    1454                 :     152437 :                 SCROW nCellY = nY;
    1455                 :     152437 :                 sal_Bool bDoCell = false;
    1456                 :     152437 :                 sal_Bool bNeedEdit = false;
    1457                 :            : 
    1458                 :            :                 //
    1459                 :            :                 //  Part of a merged cell?
    1460                 :            :                 //
    1461                 :            : 
    1462 [ +  + ][ +  + ]:     152437 :                 sal_Bool bOverlapped = ( pInfo->bHOverlapped || pInfo->bVOverlapped );
    1463         [ +  + ]:     152437 :                 if ( bOverlapped )
    1464                 :            :                 {
    1465                 :         34 :                     bEmpty = sal_True;
    1466                 :            : 
    1467                 :            :                     SCCOL nOverX;                   // start of the merged cells
    1468                 :            :                     SCROW nOverY;
    1469                 :         34 :                     sal_Bool bVisChanged = !pRowInfo[nArrY-1].bChanged;
    1470 [ +  - ][ -  + ]:         34 :                     if (GetMergeOrigin( nX,nY, nArrY, nOverX,nOverY, bVisChanged ))
    1471                 :            :                     {
    1472                 :          0 :                         nCellX = nOverX;
    1473                 :          0 :                         nCellY = nOverY;
    1474                 :          0 :                         bDoCell = sal_True;
    1475                 :            :                     }
    1476                 :            :                     else
    1477                 :         34 :                         bMergeEmpty = sal_True;
    1478                 :            :                 }
    1479                 :            : 
    1480                 :            :                 //
    1481                 :            :                 //  Rest of a long text further to the left?
    1482                 :            :                 //
    1483                 :            : 
    1484 [ +  + ][ +  + ]:     152437 :                 if ( bEmpty && !bMergeEmpty && nX < nX1 && !bOverlapped )
         [ +  + ][ +  - ]
    1485                 :            :                 {
    1486                 :       1340 :                     SCCOL nTempX=nX1;
    1487 [ +  + ][ +  - ]:       1794 :                     while (nTempX > 0 && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
         [ +  + ][ +  + ]
    1488                 :        454 :                         --nTempX;
    1489                 :            : 
    1490 [ +  + ][ +  + ]:       1598 :                     if ( nTempX < nX1 &&
         [ +  - ][ +  + ]
    1491         [ +  - ]:        241 :                          !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
    1492         [ +  - ]:         17 :                          !mpDoc->HasAttrib( nTempX,nY,nTab, nX1,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
    1493                 :            :                     {
    1494                 :         17 :                         nCellX = nTempX;
    1495                 :         17 :                         bDoCell = sal_True;
    1496                 :            :                     }
    1497                 :            :                 }
    1498                 :            : 
    1499                 :            :                 //
    1500                 :            :                 //  Rest of a long text further to the right?
    1501                 :            :                 //
    1502                 :            : 
    1503 [ +  + ][ +  + ]:     152437 :                 if ( bEmpty && !bMergeEmpty && nX == nX2 && !bOverlapped )
         [ +  + ][ +  - ]
    1504                 :            :                 {
    1505                 :            :                     //  don't have to look further than nLastContentCol
    1506                 :            : 
    1507                 :      15241 :                     SCCOL nTempX=nX;
    1508 [ +  + ][ +  - ]:      17405 :                     while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
         [ +  + ][ +  + ]
    1509                 :       2164 :                         ++nTempX;
    1510                 :            : 
    1511 [ +  + ][ +  + ]:      15498 :                     if ( nTempX > nX &&
         [ +  - ][ +  + ]
    1512         [ +  - ]:        177 :                          !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
    1513         [ +  - ]:         80 :                          !mpDoc->HasAttrib( nTempX,nY,nTab, nX,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
    1514                 :            :                     {
    1515                 :         80 :                         nCellX = nTempX;
    1516                 :         80 :                         bDoCell = sal_True;
    1517                 :            :                     }
    1518                 :            :                 }
    1519                 :            : 
    1520                 :            :                 //
    1521                 :            :                 //  normal visible cell
    1522                 :            :                 //
    1523                 :            : 
    1524         [ +  + ]:     152437 :                 if (!bEmpty)
    1525                 :      11692 :                     bDoCell = sal_True;
    1526                 :            : 
    1527                 :            :                 //
    1528                 :            :                 //  don't output the cell that's being edited
    1529                 :            :                 //
    1530                 :            : 
    1531 [ +  + ][ -  + ]:     152437 :                 if ( bDoCell && bEditMode && nCellX == nEditCol && nCellY == nEditRow )
         [ #  # ][ #  # ]
    1532                 :          0 :                     bDoCell = false;
    1533                 :            : 
    1534                 :            :                 // skip text in cell if data bar is set and only value selected
    1535         [ +  + ]:     152437 :                 if ( bDoCell )
    1536                 :            :                 {
    1537 [ -  + ][ #  # ]:      11789 :                     if(pInfo->pDataBar && !pInfo->pDataBar->mbShowValue)
    1538                 :          0 :                         bDoCell = false;
    1539                 :            :                 }
    1540                 :            : 
    1541                 :            :                 //
    1542                 :            :                 //  output the cell text
    1543                 :            :                 //
    1544                 :            : 
    1545                 :     152437 :                 ScBaseCell* pCell = NULL;
    1546         [ +  + ]:     152437 :                 if (bDoCell)
    1547                 :            :                 {
    1548 [ +  - ][ +  + ]:      11789 :                     if ( nCellY == nY && nCellX == nX && nCellX >= nX1 && nCellX <= nX2 )
         [ +  + ][ +  - ]
    1549                 :      11692 :                         pCell = pThisRowInfo->pCellInfo[nCellX+1].pCell;
    1550                 :            :                     else
    1551         [ +  - ]:         97 :                         GetVisibleCell( nCellX, nCellY, nTab, pCell );      // get from document
    1552         [ -  + ]:      11789 :                     if ( !pCell )
    1553                 :          0 :                         bDoCell = false;
    1554         [ +  + ]:      11789 :                     else if ( pCell->GetCellType() == CELLTYPE_EDIT )
    1555                 :        303 :                         bNeedEdit = sal_True;
    1556                 :            :                 }
    1557 [ +  + ][ +  + ]:     152437 :                 if (bDoCell && !bNeedEdit)
    1558                 :            :                 {
    1559 [ +  - ][ +  + ]:      11486 :                     if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 )
                 [ +  + ]
    1560                 :            :                     {
    1561                 :      11390 :                         CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1];
    1562                 :      11390 :                         pPattern = rCellInfo.pPatternAttr;
    1563                 :      11390 :                         pCondSet = rCellInfo.pConditionSet;
    1564                 :            : 
    1565         [ -  + ]:      11390 :                         if ( !pPattern )
    1566                 :            :                         {
    1567                 :            :                             // #i68085# pattern from cell info for hidden columns is null,
    1568                 :            :                             // test for null is quicker than using column flags
    1569         [ #  # ]:          0 :                             pPattern = mpDoc->GetPattern( nCellX, nCellY, nTab );
    1570         [ #  # ]:          0 :                             pCondSet = mpDoc->GetCondResult( nCellX, nCellY, nTab );
    1571                 :      11390 :                         }
    1572                 :            :                     }
    1573                 :            :                     else        // get from document
    1574                 :            :                     {
    1575         [ +  - ]:         96 :                         pPattern = mpDoc->GetPattern( nCellX, nCellY, nTab );
    1576         [ +  - ]:         96 :                         pCondSet = mpDoc->GetCondResult( nCellX, nCellY, nTab );
    1577                 :            :                     }
    1578                 :            : 
    1579         [ +  - ]:      18068 :                     if (pCell->HasValueData() &&
           [ +  +  +  + ]
                 [ +  + ]
    1580                 :            :                         static_cast<const SfxBoolItem&>(
    1581         [ +  - ]:       6582 :                             pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue())
    1582                 :            :                     {
    1583                 :            :                         // Disable line break when the cell content is numeric.
    1584 [ +  - ][ +  - ]:        320 :                         aAltPatterns.push_back(new ScPatternAttr(*pPattern));
                 [ +  - ]
    1585         [ +  - ]:        320 :                         ScPatternAttr* pAltPattern = &aAltPatterns.back();
    1586         [ +  - ]:        320 :                         SfxBoolItem aLineBreak(ATTR_LINEBREAK, false);
    1587         [ +  - ]:        320 :                         pAltPattern->GetItemSet().Put(aLineBreak);
    1588         [ +  - ]:        320 :                         pPattern = pAltPattern;
    1589                 :            :                     }
    1590                 :            : 
    1591         [ +  - ]:      11486 :                     sal_uInt8 nScript = GetScriptType( mpDoc, pCell, pPattern, pCondSet );
    1592 [ +  + ][ +  - ]:      11486 :                     if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
    1593 [ +  + ][ +  + ]:      11486 :                     if ( pPattern != pOldPattern || pCondSet != pOldCondSet ||
         [ +  - ][ -  + ]
    1594                 :            :                          nScript != nOldScript || mbSyntaxMode )
    1595                 :            :                     {
    1596 [ +  - ][ +  + ]:       2063 :                         if ( StringDiffer(pOldPattern,pPattern) ||
         [ +  + ][ +  - ]
         [ -  + ][ +  + ]
    1597                 :            :                              pCondSet != pOldCondSet || nScript != nOldScript || mbSyntaxMode )
    1598         [ +  - ]:       1583 :                             aVars.SetPattern( pPattern, pCondSet, pCell, nScript );
    1599                 :            :                         else
    1600         [ +  - ]:        480 :                             aVars.SetPatternSimple( pPattern, pCondSet );
    1601                 :       2063 :                         pOldPattern = pPattern;
    1602                 :       2063 :                         pOldCondSet = pCondSet;
    1603                 :       2063 :                         nOldScript = nScript;
    1604                 :            :                     }
    1605                 :            : 
    1606                 :            :                     //  use edit engine for rotated, stacked or mixed-script text
    1607   [ +  -  +  +  :      33881 :                     if ( aVars.GetOrient() == SVX_ORIENTATION_STACKED ||
           -  + ][ +  + ]
    1608                 :      22395 :                          aVars.IsRotated() || IsAmbiguousScript(nScript) )
    1609                 :        577 :                         bNeedEdit = sal_True;
    1610                 :            :                 }
    1611 [ +  + ][ +  + ]:     152437 :                 if (bDoCell && !bNeedEdit)
    1612                 :            :                 {
    1613                 :      10909 :                     sal_Bool bFormulaCell = (pCell->GetCellType() == CELLTYPE_FORMULA );
    1614         [ +  + ]:      10909 :                     if ( bFormulaCell )
    1615 [ +  - ][ +  - ]:        270 :                         lcl_CreateInterpretProgress( bProgress, mpDoc, (ScFormulaCell*)pCell );
    1616 [ +  - ][ -  + ]:      10909 :                     if ( aVars.SetText(pCell) )
    1617                 :          0 :                         pOldPattern = NULL;
    1618         [ +  - ]:      10909 :                     bNeedEdit = aVars.HasEditCharacters() ||
    1619 [ +  - ][ +  + ]:      10909 :                                     (bFormulaCell && ((ScFormulaCell*)pCell)->IsMultilineResult());
         [ +  - ][ +  - ]
                 [ -  + ]
    1620                 :            :                 }
    1621                 :     152437 :                 long nTotalMargin = 0;
    1622 [ +  + ][ +  + ]:     152437 :                 if (bDoCell && !bNeedEdit)
    1623                 :            :                 {
    1624                 :      10909 :                     CellType eCellType = pCell->GetCellType();
    1625                 :      10909 :                     bCellIsValue = ( eCellType == CELLTYPE_VALUE );
    1626         [ +  + ]:      10909 :                     if ( eCellType == CELLTYPE_FORMULA )
    1627                 :            :                     {
    1628         [ +  - ]:        270 :                         ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
    1629 [ +  - ][ +  - ]:        270 :                         bCellIsValue = pFCell->IsRunning() || pFCell->IsValue();
                 [ +  + ]
    1630                 :            :                     }
    1631                 :            : 
    1632         [ +  + ]:      10909 :                     if (aVars.GetHorJust() == SVX_HOR_JUSTIFY_STANDARD)
    1633                 :            :                     {
    1634                 :            :                         // fdo#32530: Default alignment depends on value vs
    1635                 :            :                         // string, and the direction of the 1st letter.
    1636 [ +  - ][ +  - ]:       9898 :                         if (beginsWithRTLCharacter(aVars.GetString()))
                 [ -  + ]
    1637         [ #  # ]:          0 :                             eOutHorJust = bCellIsValue ? SVX_HOR_JUSTIFY_LEFT : SVX_HOR_JUSTIFY_RIGHT;
    1638                 :            :                         else
    1639         [ +  + ]:       9898 :                             eOutHorJust = bCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT;
    1640                 :            :                     }
    1641                 :            :                     else
    1642                 :       1011 :                         eOutHorJust = aVars.GetHorJust();
    1643                 :            : 
    1644 [ +  + ][ -  + ]:      10909 :                     if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
    1645                 :        144 :                         eOutHorJust = SVX_HOR_JUSTIFY_LEFT;     // repeat is not yet implemented
    1646                 :            : 
    1647 [ +  + ][ +  + ]:      10909 :                     sal_Bool bBreak = ( aVars.GetLineBreak() || aVars.GetHorJust() == SVX_HOR_JUSTIFY_BLOCK );
    1648 [ -  + ][ #  # ]:      10909 :                     sal_Bool bRepeat = aVars.IsRepeat() && !bBreak;
    1649 [ +  + ][ +  + ]:      10909 :                     sal_Bool bShrink = aVars.IsShrink() && !bBreak && !bRepeat;
                 [ +  - ]
    1650                 :            : 
    1651                 :            :                     nTotalMargin =
    1652                 :      10909 :                         static_cast<long>(aVars.GetLeftTotal() * mnPPTX) +
    1653                 :      10909 :                         static_cast<long>(aVars.GetMargin()->GetRightMargin() * mnPPTX);
    1654                 :            : 
    1655                 :      10909 :                     nNeededWidth = aVars.GetTextSize().Width() + nTotalMargin;
    1656                 :            : 
    1657                 :            :                     // GetOutputArea gives justfied rectangles
    1658                 :            :                     GetOutputArea( nX, nArrY, nPosX, nPosY, nCellX, nCellY, nNeededWidth,
    1659                 :      10909 :                                    *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    1660                 :            :                                    bCellIsValue || bRepeat || bShrink, bBreak, false,
    1661 [ +  - ][ +  + ]:      21818 :                                    aAreaParam );
         [ +  - ][ +  + ]
    1662                 :            : 
    1663         [ +  - ]:      10909 :                     aVars.RepeatToFill( aAreaParam.mnColWidth - nTotalMargin );
    1664         [ +  + ]:      10909 :                     if ( bShrink )
    1665                 :            :                     {
    1666         [ +  - ]:         36 :                         if ( aVars.GetOrient() != SVX_ORIENTATION_STANDARD )
    1667                 :            :                         {
    1668                 :            :                             // Only horizontal scaling is handled here.
    1669                 :            :                             // DrawEdit is used to vertically scale 90 deg rotated text.
    1670                 :         36 :                             bNeedEdit = sal_True;
    1671                 :            :                         }
    1672 [ #  # ][ #  # ]:          0 :                         else if ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip )     // horizontal
    1673                 :            :                         {
    1674         [ #  # ]:          0 :                             long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin;
    1675                 :          0 :                             long nScaleSize = aVars.GetTextSize().Width();         // without margin
    1676                 :            : 
    1677         [ #  # ]:          0 :                             if ( nScaleSize > 0 )       // 0 if the text is empty (formulas, number formats)
    1678                 :            :                             {
    1679                 :          0 :                                 long nScale = ( nAvailable * 100 ) / nScaleSize;
    1680                 :            : 
    1681         [ #  # ]:          0 :                                 aVars.SetShrinkScale( nScale, nOldScript );
    1682                 :          0 :                                 long nNewSize = aVars.GetTextSize().Width();
    1683                 :            : 
    1684                 :          0 :                                 sal_uInt16 nShrinkAgain = 0;
    1685 [ #  # ][ #  # ]:          0 :                                 while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
                 [ #  # ]
    1686                 :            :                                 {
    1687                 :            :                                     // If the text is still too large, reduce the scale again by 10%, until it fits,
    1688                 :            :                                     // at most 7 times (it's less than 50% of the calculated scale then).
    1689                 :            : 
    1690                 :          0 :                                     nScale = ( nScale * 9 ) / 10;
    1691         [ #  # ]:          0 :                                     aVars.SetShrinkScale( nScale, nOldScript );
    1692                 :          0 :                                     nNewSize = aVars.GetTextSize().Width();
    1693                 :          0 :                                     ++nShrinkAgain;
    1694                 :            :                                 }
    1695                 :            :                                 // If even at half the size the font still isn't rendered smaller,
    1696                 :            :                                 // fall back to normal clipping (showing ### for numbers).
    1697         [ #  # ]:          0 :                                 if ( nNewSize <= nAvailable )
    1698                 :          0 :                                     aAreaParam.mbLeftClip = aAreaParam.mbRightClip = false;
    1699                 :            : 
    1700                 :          0 :                                 pOldPattern = NULL;
    1701                 :            :                             }
    1702                 :            :                         }
    1703                 :            :                     }
    1704                 :            : 
    1705 [ -  + ][ #  # ]:      10909 :                     if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip )
                 [ #  # ]
    1706                 :            :                     {
    1707         [ #  # ]:          0 :                         long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin;
    1708                 :          0 :                         long nRepeatSize = aVars.GetTextSize().Width();         // without margin
    1709                 :            :                         // When formatting for the printer, the text sizes don't always add up.
    1710                 :            :                         // Round down (too few repetitions) rather than exceeding the cell size then:
    1711         [ #  # ]:          0 :                         if ( pFmtDevice != mpRefDevice )
    1712                 :          0 :                             ++nRepeatSize;
    1713         [ #  # ]:          0 :                         if ( nRepeatSize > 0 )
    1714                 :            :                         {
    1715                 :          0 :                             long nRepeatCount = nAvailable / nRepeatSize;
    1716         [ #  # ]:          0 :                             if ( nRepeatCount > 1 )
    1717                 :            :                             {
    1718         [ #  # ]:          0 :                                 String aCellStr = aVars.GetString();
    1719         [ #  # ]:          0 :                                 String aRepeated = aCellStr;
    1720         [ #  # ]:          0 :                                 for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
    1721         [ #  # ]:          0 :                                     aRepeated.Append( aCellStr );
    1722 [ #  # ][ #  # ]:          0 :                                 aVars.SetAutoText( aRepeated );
                 [ #  # ]
    1723                 :            :                             }
    1724                 :            :                         }
    1725                 :            :                     }
    1726                 :            : 
    1727                 :            :                     //  use edit engine if automatic line breaks are needed
    1728         [ +  + ]:      10909 :                     if ( bBreak )
    1729                 :            :                     {
    1730         [ -  + ]:        186 :                         if ( aVars.GetOrient() == SVX_ORIENTATION_STANDARD )
    1731 [ #  # ][ #  # ]:          0 :                             bNeedEdit = ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip );
    1732                 :            :                         else
    1733                 :            :                         {
    1734                 :        186 :                             long nHeight = aVars.GetTextSize().Height() +
    1735                 :        186 :                                             (long)(aVars.GetMargin()->GetTopMargin()*mnPPTY) +
    1736                 :        186 :                                             (long)(aVars.GetMargin()->GetBottomMargin()*mnPPTY);
    1737         [ +  - ]:        186 :                             bNeedEdit = ( nHeight > aAreaParam.maClipRect.GetHeight() );
    1738                 :            :                         }
    1739                 :            :                     }
    1740         [ +  + ]:      10909 :                     if (!bNeedEdit)
    1741                 :            :                     {
    1742                 :            :                         bNeedEdit =
    1743                 :      10756 :                             aVars.GetHorJust() == SVX_HOR_JUSTIFY_BLOCK &&
    1744 [ -  + ][ +  + ]:      10756 :                             aVars.GetHorJustMethod() == SVX_JUSTIFY_METHOD_DISTRIBUTE;
    1745                 :            :                     }
    1746                 :            :                 }
    1747         [ +  + ]:     152437 :                 if (bNeedEdit)
    1748                 :            :                 {
    1749                 :            :                     //  mark the cell in CellInfo to be drawn in DrawEdit:
    1750                 :            :                     //  Cells to the left are marked directly, cells to the
    1751                 :            :                     //  right are handled by the flag for nX2
    1752         [ -  + ]:       1033 :                     SCCOL nMarkX = ( nCellX <= nX2 ) ? nCellX : nX2;
    1753         [ -  + ]:       1033 :                     RowInfo* pMarkRowInfo = ( nCellY == nY ) ? pThisRowInfo : &pRowInfo[0];
    1754                 :       1033 :                     pMarkRowInfo->pCellInfo[nMarkX+1].bEditEngine = sal_True;
    1755                 :       1033 :                     bDoCell = false;    // don't draw here
    1756                 :            :                 }
    1757         [ +  + ]:     152437 :                 if ( bDoCell )
    1758                 :            :                 {
    1759 [ +  + ][ +  + ]:      10756 :                     if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
                 [ +  + ]
    1760                 :            :                     {
    1761         [ -  + ]:        323 :                         if (mbShowFormulas)
    1762         [ #  # ]:          0 :                             aVars.SetHashText();
    1763                 :            :                         else
    1764                 :            :                             // Adjust the decimals to fit the available column width.
    1765         [ +  - ]:        323 :                             aVars.SetTextToWidthOrHash(pCell, aAreaParam.mnColWidth - nTotalMargin);
    1766                 :            : 
    1767                 :        323 :                         nNeededWidth = aVars.GetTextSize().Width() +
    1768                 :        323 :                                     (long) ( aVars.GetLeftTotal() * mnPPTX ) +
    1769                 :        323 :                                     (long) ( aVars.GetMargin()->GetRightMargin() * mnPPTX );
    1770 [ +  + ][ +  - ]:        323 :                         if ( nNeededWidth <= aAreaParam.maClipRect.GetWidth() )
    1771                 :        275 :                             aAreaParam.mbLeftClip = aAreaParam.mbRightClip = false;
    1772                 :            : 
    1773                 :            :                         //  If the "###" replacement doesn't fit into the cells, no clip marks
    1774                 :            :                         //  are shown, as the "###" already denotes too little space.
    1775                 :            :                         //  The rectangles from the first GetOutputArea call remain valid.
    1776                 :            :                     }
    1777                 :            : 
    1778                 :      10756 :                     long nJustPosX = aAreaParam.maAlignRect.Left();     // "justified" - effect of alignment will be added
    1779                 :      10756 :                     long nJustPosY = aAreaParam.maAlignRect.Top();
    1780         [ +  - ]:      10756 :                     long nAvailWidth = aAreaParam.maAlignRect.GetWidth();
    1781         [ +  - ]:      10756 :                     long nOutHeight = aAreaParam.maAlignRect.GetHeight();
    1782                 :            : 
    1783 [ +  + ][ +  + ]:      10756 :                     sal_Bool bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW );
    1784         [ +  + ]:      10756 :                     if ( aAreaParam.maClipRect.Left() < nScrX )
    1785                 :            :                     {
    1786                 :         16 :                         aAreaParam.maClipRect.Left() = nScrX;
    1787                 :         16 :                         aAreaParam.mbLeftClip = sal_True;
    1788                 :            :                     }
    1789         [ +  + ]:      10756 :                     if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
    1790                 :            :                     {
    1791                 :         80 :                         aAreaParam.maClipRect.Right() = nScrX + nScrW;          //! minus one?
    1792                 :         80 :                         aAreaParam.mbRightClip = sal_True;
    1793                 :            :                     }
    1794                 :            : 
    1795 [ +  + ][ +  + ]:      10756 :                     sal_Bool bHClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
    1796                 :      10756 :                     sal_Bool bVClip = false;
    1797                 :            : 
    1798         [ -  + ]:      10756 :                     if ( aAreaParam.maClipRect.Top() < nScrY )
    1799                 :            :                     {
    1800                 :          0 :                         aAreaParam.maClipRect.Top() = nScrY;
    1801                 :          0 :                         bVClip = sal_True;
    1802                 :            :                     }
    1803         [ -  + ]:      10756 :                     if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
    1804                 :            :                     {
    1805                 :          0 :                         aAreaParam.maClipRect.Bottom() = nScrY + nScrH;         //! minus one?
    1806                 :          0 :                         bVClip = sal_True;
    1807                 :            :                     }
    1808                 :            : 
    1809                 :            :                     //
    1810                 :            :                     //      horizontalen Platz testen
    1811                 :            :                     //
    1812                 :            : 
    1813                 :      10756 :                     sal_Bool bRightAdjusted = false;        // to correct text width calculation later
    1814                 :      10756 :                     sal_Bool bNeedEditEngine = false;
    1815 [ +  - ][ +  + ]:      10756 :                     if ( !bNeedEditEngine && !bOutside )
    1816                 :            :                     {
    1817   [ +  +  -  - ]:      10660 :                         switch (eOutHorJust)
    1818                 :            :                         {
    1819                 :            :                             case SVX_HOR_JUSTIFY_LEFT:
    1820                 :       5013 :                                 nJustPosX += (long) ( aVars.GetLeftTotal() * mnPPTX );
    1821                 :       5013 :                                 break;
    1822                 :            :                             case SVX_HOR_JUSTIFY_RIGHT:
    1823                 :       5647 :                                 nJustPosX += nAvailWidth - aVars.GetTextSize().Width() -
    1824                 :       5647 :                                             (long) ( aVars.GetMargin()->GetRightMargin() * mnPPTX );
    1825                 :       5647 :                                 bRightAdjusted = sal_True;
    1826                 :       5647 :                                 break;
    1827                 :            :                             case SVX_HOR_JUSTIFY_CENTER:
    1828                 :          0 :                                 nJustPosX += ( nAvailWidth - aVars.GetTextSize().Width() +
    1829                 :          0 :                                             (long) ( aVars.GetLeftTotal() * mnPPTX ) -
    1830                 :          0 :                                             (long) ( aVars.GetMargin()->GetRightMargin() * mnPPTX ) ) / 2;
    1831                 :          0 :                                 break;
    1832                 :            :                             default:
    1833                 :            :                             {
    1834                 :            :                                 // added to avoid warnings
    1835                 :            :                             }
    1836                 :            :                         }
    1837                 :            : 
    1838                 :      10660 :                         long nTestClipHeight = aVars.GetTextSize().Height();
    1839   [ -  +  -  - ]:      10660 :                         switch (aVars.GetVerJust())
    1840                 :            :                         {
    1841                 :            :                             case SVX_VER_JUSTIFY_TOP:
    1842                 :            :                             case SVX_VER_JUSTIFY_BLOCK:
    1843                 :            :                                 {
    1844                 :          0 :                                     long nTop = (long)( aVars.GetMargin()->GetTopMargin() * mnPPTY );
    1845                 :          0 :                                     nJustPosY += nTop;
    1846                 :          0 :                                     nTestClipHeight += nTop;
    1847                 :            :                                 }
    1848                 :          0 :                                 break;
    1849                 :            :                             case SVX_VER_JUSTIFY_BOTTOM:
    1850                 :            :                                 {
    1851                 :      10660 :                                     long nBot = (long)( aVars.GetMargin()->GetBottomMargin() * mnPPTY );
    1852                 :      10660 :                                     nJustPosY += nOutHeight - aVars.GetTextSize().Height() - nBot;
    1853                 :      10660 :                                     nTestClipHeight += nBot;
    1854                 :            :                                 }
    1855                 :      10660 :                                 break;
    1856                 :            :                             case SVX_VER_JUSTIFY_CENTER:
    1857                 :            :                                 {
    1858                 :          0 :                                     long nTop = (long)( aVars.GetMargin()->GetTopMargin() * mnPPTY );
    1859                 :          0 :                                     long nBot = (long)( aVars.GetMargin()->GetBottomMargin() * mnPPTY );
    1860                 :            :                                     nJustPosY += ( nOutHeight + nTop -
    1861                 :          0 :                                                     aVars.GetTextSize().Height() - nBot ) / 2;
    1862                 :          0 :                                     nTestClipHeight += Abs( nTop - nBot );
    1863                 :            :                                 }
    1864                 :          0 :                                 break;
    1865                 :            :                             default:
    1866                 :            :                             {
    1867                 :            :                                 // added to avoid warnings
    1868                 :            :                             }
    1869                 :            :                         }
    1870                 :            : 
    1871         [ +  + ]:      10660 :                         if ( nTestClipHeight > nOutHeight )
    1872                 :            :                         {
    1873                 :            :                             //  kein vertikales Clipping beim Drucken von Zellen mit
    1874                 :            :                             //  optimaler Hoehe, ausser bei Groesse in bedingter Formatierung
    1875 [ -  + ][ #  # ]:         32 :                             if ( eType != OUTTYPE_PRINTER ||
         [ #  # ][ +  - ]
    1876         [ #  # ]:          0 :                                     ( mpDoc->GetRowFlags( nCellY, nTab ) & CR_MANUALSIZE ) ||
    1877         [ #  # ]:          0 :                                     ( aVars.HasCondHeight() ) )
    1878                 :         32 :                                 bVClip = sal_True;
    1879                 :            :                         }
    1880                 :            : 
    1881 [ +  + ][ +  + ]:      10660 :                         if ( bHClip || bVClip )
    1882                 :            :                         {
    1883                 :            :                             //  nur die betroffene Dimension clippen,
    1884                 :            :                             //  damit bei nicht-proportionalem Resize nicht alle
    1885                 :            :                             //  rechtsbuendigen Zahlen abgeschnitten werden:
    1886                 :            : 
    1887         [ +  + ]:         75 :                             if (!bHClip)
    1888                 :            :                             {
    1889                 :          2 :                                 aAreaParam.maClipRect.Left() = nScrX;
    1890                 :          2 :                                 aAreaParam.maClipRect.Right() = nScrX+nScrW;
    1891                 :            :                             }
    1892         [ +  + ]:         75 :                             if (!bVClip)
    1893                 :            :                             {
    1894                 :         43 :                                 aAreaParam.maClipRect.Top() = nScrY;
    1895                 :         43 :                                 aAreaParam.maClipRect.Bottom() = nScrY+nScrH;
    1896                 :            :                             }
    1897                 :            : 
    1898                 :            :                             //  aClipRect is not used after SetClipRegion/IntersectClipRegion,
    1899                 :            :                             //  so it can be modified here
    1900         [ -  + ]:         75 :                             if (bPixelToLogic)
    1901         [ #  # ]:          0 :                                 aAreaParam.maClipRect = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
    1902                 :            : 
    1903         [ -  + ]:         75 :                             if (bMetaFile)
    1904                 :            :                             {
    1905         [ #  # ]:          0 :                                 mpDev->Push();
    1906         [ #  # ]:          0 :                                 mpDev->IntersectClipRegion( aAreaParam.maClipRect );
    1907                 :            :                             }
    1908                 :            :                             else
    1909 [ +  - ][ +  - ]:         75 :                                 mpDev->SetClipRegion( Region( aAreaParam.maClipRect ) );
                 [ +  - ]
    1910                 :            :                         }
    1911                 :            : 
    1912                 :      10660 :                         Point aURLStart( nJustPosX, nJustPosY );    // copy before modifying for orientation
    1913                 :            : 
    1914   [ +  +  -  - ]:      10660 :                         switch (aVars.GetOrient())
    1915                 :            :                         {
    1916                 :            :                             case SVX_ORIENTATION_STANDARD:
    1917                 :      10507 :                                 nJustPosY += aVars.GetAscent();
    1918                 :      10507 :                                 break;
    1919                 :            :                             case SVX_ORIENTATION_TOPBOTTOM:
    1920                 :        153 :                                 nJustPosX += aVars.GetTextSize().Width() - aVars.GetAscent();
    1921                 :        153 :                                 break;
    1922                 :            :                             case SVX_ORIENTATION_BOTTOMTOP:
    1923                 :          0 :                                 nJustPosY += aVars.GetTextSize().Height();
    1924                 :          0 :                                 nJustPosX += aVars.GetAscent();
    1925                 :          0 :                                 break;
    1926                 :            :                             default:
    1927                 :            :                             {
    1928                 :            :                                 // added to avoid warnings
    1929                 :            :                             }
    1930                 :            :                         }
    1931                 :            : 
    1932                 :            :                         // When clipping, the visible part is now completely defined by the alignment,
    1933                 :            :                         // there's no more special handling to show the right part of RTL text.
    1934                 :            : 
    1935                 :      10660 :                         Point aDrawTextPos( nJustPosX, nJustPosY );
    1936         [ +  + ]:      10660 :                         if ( bPixelToLogic )
    1937                 :            :                         {
    1938                 :            :                             //  undo text width adjustment in pixels
    1939         [ +  + ]:        956 :                             if (bRightAdjusted)
    1940                 :        916 :                                 aDrawTextPos.X() += aVars.GetTextSize().Width();
    1941                 :            : 
    1942         [ +  - ]:        956 :                             aDrawTextPos = mpRefDevice->PixelToLogic( aDrawTextPos );
    1943                 :            : 
    1944                 :            :                             //  redo text width adjustment in logic units
    1945         [ +  + ]:        956 :                             if (bRightAdjusted)
    1946                 :        916 :                                 aDrawTextPos.X() -= aVars.GetOriginalWidth();
    1947                 :            :                         }
    1948                 :            : 
    1949                 :            :                         //  in Metafiles immer DrawTextArray, damit die Positionen mit
    1950                 :            :                         //  aufgezeichnet werden (fuer nicht-proportionales Resize):
    1951                 :            : 
    1952         [ +  - ]:      10660 :                         String aString = aVars.GetString();
    1953 [ +  - ][ +  + ]:      10660 :                         if (bMetaFile || pFmtDevice != mpDev || aZoomX != aZoomY)
         [ +  - ][ -  + ]
                 [ +  + ]
    1954                 :            :                         {
    1955         [ +  - ]:       1002 :                             sal_Int32* pDX = new sal_Int32[aString.Len()];
    1956         [ +  - ]:       1002 :                             pFmtDevice->GetTextArray( aString, pDX );
    1957                 :            : 
    1958   [ -  +  #  # ]:       1002 :                             if ( !mpRefDevice->GetConnectMetaFile() ||
                 [ +  - ]
    1959                 :          0 :                                     mpRefDevice->GetOutDevType() == OUTDEV_PRINTER )
    1960                 :            :                             {
    1961         [ +  - ]:       1002 :                                 double fMul = GetStretch();
    1962                 :       1002 :                                 xub_StrLen nLen = aString.Len();
    1963         [ +  + ]:       3698 :                                 for (xub_StrLen i=0; i<nLen; i++)
    1964                 :       2696 :                                     pDX[i] = (long)(pDX[i] / fMul + 0.5);
    1965                 :            :                             }
    1966                 :            : 
    1967         [ +  - ]:       1002 :                             mpDev->DrawTextArray( aDrawTextPos, aString, pDX );
    1968         [ +  - ]:       1002 :                             delete[] pDX;
    1969                 :            :                         }
    1970                 :            :                         else
    1971         [ +  - ]:       9658 :                             mpDev->DrawText( aDrawTextPos, aString );
    1972                 :            : 
    1973 [ +  + ][ +  + ]:      10660 :                         if ( bHClip || bVClip )
    1974                 :            :                         {
    1975         [ -  + ]:         75 :                             if (bMetaFile)
    1976         [ #  # ]:          0 :                                 mpDev->Pop();
    1977                 :            :                             else
    1978         [ +  - ]:         75 :                                 mpDev->SetClipRegion();
    1979                 :            :                         }
    1980                 :            : 
    1981                 :            :                         // PDF: whole-cell hyperlink from formula?
    1982                 :          0 :                         sal_Bool bHasURL = pPDFData && pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
    1983         [ -  + ]:      10660 :                                         static_cast<ScFormulaCell*>(pCell)->IsHyperLinkCell();
           [ #  #  #  # ]
         [ #  # ][ #  # ]
    1984         [ -  + ]:      10660 :                         if ( bHasURL )
    1985                 :            :                         {
    1986         [ #  # ]:          0 :                             Rectangle aURLRect( aURLStart, aVars.GetTextSize() );
    1987         [ #  # ]:          0 :                             lcl_DoHyperlinkResult( mpDev, aURLRect, pCell );
    1988         [ +  - ]:      10660 :                         }
    1989                 :            :                     }
    1990                 :            :                 }
    1991                 :     152437 :                 nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
    1992                 :            :             }
    1993                 :            :         }
    1994                 :      15867 :         nPosY += pRowInfo[nArrY].nHeight;
    1995                 :            :     }
    1996         [ -  + ]:       1345 :     if ( bProgress )
    1997         [ #  # ]:          0 :         ScProgress::DeleteInterpretProgress();
    1998 [ +  - ][ +  - ]:       1345 :     mpDoc->DisableIdle( bWasIdleDisabled );
    1999                 :       1345 : }
    2000                 :            : 
    2001                 :            : //  -------------------------------------------------------------------------------
    2002                 :            : 
    2003                 :        405 : ScFieldEditEngine* ScOutputData::CreateOutputEditEngine()
    2004                 :            : {
    2005         [ +  - ]:        405 :     ScFieldEditEngine* pEngine = new ScFieldEditEngine(mpDoc, mpDoc->GetEnginePool());
    2006                 :        405 :     pEngine->SetUpdateMode( false );
    2007                 :            :     // a RefDevice always has to be set, otherwise EditEngine would create a VirtualDevice
    2008                 :        405 :     pEngine->SetRefDevice( pFmtDevice );
    2009                 :        405 :     sal_uLong nCtrl = pEngine->GetControlWord();
    2010         [ +  + ]:        405 :     if ( bShowSpellErrors )
    2011                 :        388 :         nCtrl |= EE_CNTRL_ONLINESPELLING;
    2012         [ +  + ]:        405 :     if ( eType == OUTTYPE_PRINTER )
    2013                 :         17 :         nCtrl &= ~EE_CNTRL_MARKFIELDS;
    2014 [ +  + ][ +  - ]:        405 :     if ( eType == OUTTYPE_WINDOW && mpRefDevice == pFmtDevice )
    2015                 :        388 :         nCtrl &= ~EE_CNTRL_FORMAT100;       // use the actual MapMode
    2016                 :        405 :     pEngine->SetControlWord( nCtrl );
    2017                 :        405 :     mpDoc->ApplyAsianEditSettings( *pEngine );
    2018                 :        405 :     pEngine->EnableAutoColor( mbUseStyleColor );
    2019                 :        405 :     pEngine->SetDefaultHorizontalTextDirection( (EEHorizontalTextDirection)mpDoc->GetEditTextDirection( nTab ) );
    2020                 :        405 :     return pEngine;
    2021                 :            : }
    2022                 :            : 
    2023                 :       2083 : void lcl_ClearEdit( EditEngine& rEngine )       // Text und Attribute
    2024                 :            : {
    2025                 :       2083 :     rEngine.SetUpdateMode( false );
    2026                 :            : 
    2027                 :       2083 :     rEngine.SetText(EMPTY_STRING);
    2028                 :            :     //  keine Para-Attribute uebrigbehalten...
    2029                 :       2083 :     const SfxItemSet& rPara = rEngine.GetParaAttribs(0);
    2030         [ +  + ]:       2083 :     if (rPara.Count())
    2031                 :            :         rEngine.SetParaAttribs( 0,
    2032         [ +  - ]:        772 :                     SfxItemSet( *rPara.GetPool(), rPara.GetRanges() ) );
    2033                 :       2083 : }
    2034                 :            : 
    2035                 :       1033 : sal_Bool lcl_SafeIsValue( ScBaseCell* pCell )
    2036                 :            : {
    2037         [ -  + ]:       1033 :     if (!pCell)
    2038                 :          0 :         return false;
    2039                 :            : 
    2040                 :       1033 :     sal_Bool bRet = false;
    2041      [ +  -  + ]:       1033 :     switch ( pCell->GetCellType() )
    2042                 :            :     {
    2043                 :            :         case CELLTYPE_VALUE:
    2044                 :        456 :             bRet = sal_True;
    2045                 :        456 :             break;
    2046                 :            :         case CELLTYPE_FORMULA:
    2047                 :            :             {
    2048         [ #  # ]:          0 :                 ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
    2049 [ #  # ][ #  # ]:          0 :                 if ( pFCell->IsRunning() || pFCell->IsValue() )
                 [ #  # ]
    2050                 :          0 :                     bRet = sal_True;
    2051                 :            :             }
    2052                 :          0 :             break;
    2053                 :            :         default:
    2054                 :            :         {
    2055                 :            :             // added to avoid warnings
    2056                 :            :         }
    2057                 :            :     }
    2058                 :       1033 :     return bRet;
    2059                 :            : }
    2060                 :            : 
    2061                 :         91 : void lcl_ScaleFonts( EditEngine& rEngine, long nPercent )
    2062                 :            : {
    2063                 :         91 :     sal_Bool bUpdateMode = rEngine.GetUpdateMode();
    2064         [ +  - ]:         91 :     if ( bUpdateMode )
    2065                 :         91 :         rEngine.SetUpdateMode( false );
    2066                 :            : 
    2067                 :         91 :     sal_uInt16 nParCount = rEngine.GetParagraphCount();
    2068         [ +  + ]:        182 :     for (sal_uInt16 nPar=0; nPar<nParCount; nPar++)
    2069                 :            :     {
    2070         [ +  - ]:         91 :         std::vector<sal_uInt16> aPortions;
    2071         [ +  - ]:         91 :         rEngine.GetPortions( nPar, aPortions );
    2072                 :            : 
    2073                 :         91 :         sal_uInt16 nStart = 0;
    2074 [ +  - ][ +  - ]:        182 :         for ( std::vector<sal_uInt16>::const_iterator it(aPortions.begin()); it != aPortions.end(); ++it )
         [ +  - ][ +  + ]
    2075                 :            :         {
    2076         [ +  - ]:         91 :             sal_uInt16 nEnd = *it;
    2077                 :         91 :             ESelection aSel( nPar, nStart, nPar, nEnd );
    2078         [ +  - ]:         91 :             SfxItemSet aAttribs = rEngine.GetAttribs( aSel );
    2079                 :            : 
    2080         [ +  - ]:         91 :             long nWestern = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT)).GetHeight();
    2081         [ +  - ]:         91 :             long nCJK = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT_CJK)).GetHeight();
    2082         [ +  - ]:         91 :             long nCTL = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT_CTL)).GetHeight();
    2083                 :            : 
    2084                 :         91 :             nWestern = ( nWestern * nPercent ) / 100;
    2085                 :         91 :             nCJK     = ( nCJK     * nPercent ) / 100;
    2086                 :         91 :             nCTL     = ( nCTL     * nPercent ) / 100;
    2087                 :            : 
    2088 [ +  - ][ +  - ]:         91 :             aAttribs.Put( SvxFontHeightItem( nWestern, 100, EE_CHAR_FONTHEIGHT ) );
                 [ +  - ]
    2089 [ +  - ][ +  - ]:         91 :             aAttribs.Put( SvxFontHeightItem( nCJK, 100, EE_CHAR_FONTHEIGHT_CJK ) );
                 [ +  - ]
    2090 [ +  - ][ +  - ]:         91 :             aAttribs.Put( SvxFontHeightItem( nCTL, 100, EE_CHAR_FONTHEIGHT_CTL ) );
                 [ +  - ]
    2091                 :            : 
    2092         [ +  - ]:         91 :             rEngine.QuickSetAttribs( aAttribs, aSel );      //! remove paragraph attributes from aAttribs?
    2093                 :            : 
    2094                 :         91 :             nStart = nEnd;
    2095         [ +  - ]:         91 :         }
    2096                 :         91 :     }
    2097                 :            : 
    2098         [ +  - ]:         91 :     if ( bUpdateMode )
    2099                 :         91 :         rEngine.SetUpdateMode( sal_True );
    2100                 :         91 : }
    2101                 :            : 
    2102                 :        182 : long lcl_GetEditSize( EditEngine& rEngine, sal_Bool bWidth, sal_Bool bSwap, long nAttrRotate )
    2103                 :            : {
    2104         [ -  + ]:        182 :     if ( bSwap )
    2105                 :          0 :         bWidth = !bWidth;
    2106                 :            : 
    2107         [ +  - ]:        182 :     if ( nAttrRotate )
    2108                 :            :     {
    2109                 :        182 :         long nRealWidth  = (long) rEngine.CalcTextWidth();
    2110                 :        182 :         long nRealHeight = rEngine.GetTextHeight();
    2111                 :            : 
    2112                 :            :         // assuming standard mode, otherwise width isn't used
    2113                 :            : 
    2114                 :        182 :         double nRealOrient = nAttrRotate * F_PI18000;   // 1/100th degrees
    2115                 :        182 :         double nAbsCos = fabs( cos( nRealOrient ) );
    2116                 :        182 :         double nAbsSin = fabs( sin( nRealOrient ) );
    2117         [ +  + ]:        182 :         if ( bWidth )
    2118                 :         91 :             return (long) ( nRealWidth * nAbsCos + nRealHeight * nAbsSin );
    2119                 :            :         else
    2120                 :         91 :             return (long) ( nRealHeight * nAbsCos + nRealWidth * nAbsSin );
    2121                 :            :     }
    2122         [ #  # ]:          0 :     else if ( bWidth )
    2123                 :          0 :         return (long) rEngine.CalcTextWidth();
    2124                 :            :     else
    2125                 :        182 :         return rEngine.GetTextHeight();
    2126                 :            : }
    2127                 :            : 
    2128                 :            : 
    2129                 :        221 : void ScOutputData::ShrinkEditEngine( EditEngine& rEngine, const Rectangle& rAlignRect,
    2130                 :            :             long nLeftM, long nTopM, long nRightM, long nBottomM,
    2131                 :            :             sal_Bool bWidth, sal_uInt16 nOrient, long nAttrRotate, sal_Bool bPixelToLogic,
    2132                 :            :             long& rEngineWidth, long& rEngineHeight, long& rNeededPixel, bool& rLeftClip, bool& rRightClip )
    2133                 :            : {
    2134         [ +  + ]:        221 :     if ( !bWidth )
    2135                 :            :     {
    2136                 :            :         // vertical
    2137                 :            : 
    2138                 :            :         long nScaleSize = bPixelToLogic ?
    2139 [ +  - ][ +  - ]:        130 :             mpRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
         [ +  - ][ +  - ]
           [ #  #  #  # ]
    2140                 :            : 
    2141                 :            :         // Don't scale if it fits already.
    2142                 :            :         // Allowing to extend into the margin, to avoid scaling at optimal height.
    2143         [ +  - ]:        130 :         if ( nScaleSize <= rAlignRect.GetHeight() )
    2144                 :        130 :             return;
    2145                 :            : 
    2146 [ #  # ][ #  # ]:          0 :         sal_Bool bSwap = ( nOrient == SVX_ORIENTATION_TOPBOTTOM || nOrient == SVX_ORIENTATION_BOTTOMTOP );
    2147                 :          0 :         long nAvailable = rAlignRect.GetHeight() - nTopM - nBottomM;
    2148                 :          0 :         long nScale = ( nAvailable * 100 ) / nScaleSize;
    2149                 :            : 
    2150                 :          0 :         lcl_ScaleFonts( rEngine, nScale );
    2151                 :          0 :         rEngineHeight = lcl_GetEditSize( rEngine, false, bSwap, nAttrRotate );
    2152                 :            :         long nNewSize = bPixelToLogic ?
    2153 [ #  # ][ #  # ]:          0 :             mpRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
    2154                 :            : 
    2155                 :          0 :         sal_uInt16 nShrinkAgain = 0;
    2156 [ #  # ][ #  # ]:          0 :         while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
                 [ #  # ]
    2157                 :            :         {
    2158                 :            :             // further reduce, like in DrawStrings
    2159                 :          0 :             lcl_ScaleFonts( rEngine, 90 );     // reduce by 10%
    2160                 :          0 :             rEngineHeight = lcl_GetEditSize( rEngine, false, bSwap, nAttrRotate );
    2161                 :            :             nNewSize = bPixelToLogic ?
    2162 [ #  # ][ #  # ]:          0 :                 mpRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
    2163                 :          0 :             ++nShrinkAgain;
    2164                 :            :         }
    2165                 :            : 
    2166                 :            :         // sizes for further processing (alignment etc):
    2167                 :          0 :         rEngineWidth = lcl_GetEditSize( rEngine, sal_True, bSwap, nAttrRotate );
    2168                 :            :         long nPixelWidth = bPixelToLogic ?
    2169 [ #  # ][ #  # ]:          0 :             mpRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
    2170                 :          0 :         rNeededPixel = nPixelWidth + nLeftM + nRightM;
    2171                 :            :     }
    2172 [ -  + ][ #  # ]:         91 :     else if ( rLeftClip || rRightClip )
    2173                 :            :     {
    2174                 :            :         // horizontal
    2175                 :            : 
    2176                 :         91 :         long nAvailable = rAlignRect.GetWidth() - nLeftM - nRightM;
    2177                 :         91 :         long nScaleSize = rNeededPixel - nLeftM - nRightM;      // without margin
    2178                 :            : 
    2179         [ -  + ]:         91 :         if ( nScaleSize <= nAvailable )
    2180                 :          0 :             return;
    2181                 :            : 
    2182                 :         91 :         long nScale = ( nAvailable * 100 ) / nScaleSize;
    2183                 :            : 
    2184                 :         91 :         lcl_ScaleFonts( rEngine, nScale );
    2185                 :         91 :         rEngineWidth = lcl_GetEditSize( rEngine, sal_True, false, nAttrRotate );
    2186                 :            :         long nNewSize = bPixelToLogic ?
    2187 [ +  - ][ +  - ]:         91 :             mpRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
                 [ +  - ]
           [ #  #  #  # ]
                 [ +  - ]
    2188                 :            : 
    2189                 :         91 :         sal_uInt16 nShrinkAgain = 0;
    2190 [ -  + ][ #  # ]:         91 :         while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
                 [ -  + ]
    2191                 :            :         {
    2192                 :            :             // further reduce, like in DrawStrings
    2193                 :          0 :             lcl_ScaleFonts( rEngine, 90 );     // reduce by 10%
    2194                 :          0 :             rEngineWidth = lcl_GetEditSize( rEngine, sal_True, false, nAttrRotate );
    2195                 :            :             nNewSize = bPixelToLogic ?
    2196 [ #  # ][ #  # ]:          0 :                 mpRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
    2197                 :          0 :             ++nShrinkAgain;
    2198                 :            :         }
    2199         [ +  - ]:         91 :         if ( nNewSize <= nAvailable )
    2200                 :         91 :             rLeftClip = rRightClip = false;
    2201                 :            : 
    2202                 :            :         // sizes for further processing (alignment etc):
    2203                 :         91 :         rNeededPixel = nNewSize + nLeftM + nRightM;
    2204                 :        221 :         rEngineHeight = lcl_GetEditSize( rEngine, false, false, nAttrRotate );
    2205                 :            :     }
    2206                 :            : }
    2207                 :            : 
    2208                 :       1033 : ScOutputData::DrawEditParam::DrawEditParam(const ScPatternAttr* pPattern, const SfxItemSet* pCondSet, bool bCellIsValue) :
    2209                 :       1033 :     meHorJust( lcl_GetValue<SvxHorJustifyItem, SvxCellHorJustify>(*pPattern, ATTR_HOR_JUSTIFY, pCondSet) ),
    2210                 :       1033 :     meVerJust( lcl_GetValue<SvxVerJustifyItem, SvxCellVerJustify>(*pPattern, ATTR_VER_JUSTIFY, pCondSet) ),
    2211                 :       1033 :     meHorJustMethod( lcl_GetValue<SvxJustifyMethodItem, SvxCellJustifyMethod>(*pPattern, ATTR_HOR_JUSTIFY_METHOD, pCondSet) ),
    2212                 :       1033 :     meVerJustMethod( lcl_GetValue<SvxJustifyMethodItem, SvxCellJustifyMethod>(*pPattern, ATTR_VER_JUSTIFY_METHOD, pCondSet) ),
    2213                 :       1033 :     meOrient( pPattern->GetCellOrientation(pCondSet) ),
    2214                 :            :     mnArrY(0),
    2215                 :            :     mnX(0), mnY(0), mnCellX(0), mnCellY(0),
    2216                 :            :     mnPosX(0), mnPosY(0), mnInitPosX(0),
    2217                 :        655 :     mbBreak( (meHorJust == SVX_HOR_JUSTIFY_BLOCK) || lcl_GetBoolValue(*pPattern, ATTR_LINEBREAK, pCondSet) ),
    2218                 :            :     mbCellIsValue(bCellIsValue),
    2219                 :            :     mbAsianVertical(false),
    2220                 :            :     mbPixelToLogic(false),
    2221                 :            :     mbHyphenatorSet(false),
    2222                 :            :     mbRTL(false),
    2223                 :            :     mpEngine(NULL),
    2224                 :            :     mpCell(NULL),
    2225                 :            :     mpPattern(pPattern),
    2226                 :            :     mpCondSet(pCondSet),
    2227                 :            :     mpOldPattern(NULL),
    2228                 :            :     mpOldCondSet(NULL),
    2229   [ +  +  +  + ]:       1688 :     mpThisRowInfo(NULL)
    2230                 :       1033 : {}
    2231                 :            : 
    2232                 :        372 : bool ScOutputData::DrawEditParam::readCellContent(
    2233                 :            :     ScDocument* pDoc, bool bShowNullValues, bool bShowFormulas, bool bSyntaxMode, bool bUseStyleColor, bool bForceAutoColor, bool& rWrapFields)
    2234                 :            : {
    2235         [ -  + ]:        372 :     if (!mpCell)
    2236                 :            :     {
    2237                 :            :         OSL_FAIL("pCell == NULL");
    2238                 :          0 :         return false;
    2239                 :            :     }
    2240                 :            : 
    2241         [ +  + ]:        372 :     if (mpCell->GetCellType() == CELLTYPE_EDIT)
    2242                 :            :     {
    2243                 :            :         const EditTextObject* pData;
    2244         [ +  - ]:        219 :         ((ScEditCell*)mpCell)->GetData(pData);
    2245                 :            : 
    2246         [ +  - ]:        219 :         if (pData)
    2247                 :            :         {
    2248         [ +  - ]:        219 :             mpEngine->SetText(*pData);
    2249                 :            : 
    2250 [ +  + ][ +  - ]:        219 :             if ( mbBreak && !mbAsianVertical && pData->HasField() )
         [ +  - ][ -  + ]
                 [ -  + ]
    2251                 :            :             {
    2252                 :            :                 //  Fields aren't wrapped, so clipping is enabled to prevent
    2253                 :            :                 //  a field from being drawn beyond the cell size
    2254                 :            : 
    2255                 :          0 :                 rWrapFields = true;
    2256                 :            :             }
    2257                 :            :         }
    2258                 :            :         else
    2259                 :            :         {
    2260                 :            :             OSL_FAIL("pData == 0");
    2261                 :        219 :             return false;
    2262                 :            :         }
    2263                 :            :     }
    2264                 :            :     else
    2265                 :            :     {
    2266                 :            :         sal_uLong nFormat = mpPattern->GetNumberFormat(
    2267 [ +  - ][ +  - ]:        153 :                                     pDoc->GetFormatTable(), mpCondSet );
    2268                 :        153 :         rtl::OUString aString;
    2269                 :            :         Color* pColor;
    2270                 :            :         ScCellFormat::GetString( mpCell,
    2271                 :            :                                  nFormat,aString, &pColor,
    2272         [ +  - ]:        153 :                                  *pDoc->GetFormatTable(),
    2273                 :            :                                  bShowNullValues,
    2274                 :            :                                  bShowFormulas,
    2275         [ +  - ]:        153 :                                  ftCheck );
    2276                 :            : 
    2277 [ +  - ][ +  - ]:        153 :         mpEngine->SetText(aString);
                 [ +  - ]
    2278 [ -  + ][ #  # ]:        153 :         if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
         [ #  # ][ #  # ]
    2279         [ #  # ]:        153 :             lcl_SetEditColor( *mpEngine, *pColor );
    2280                 :            :     }
    2281                 :        372 :     return true;
    2282                 :            : }
    2283                 :            : 
    2284                 :        372 : void ScOutputData::DrawEditParam::setPatternToEngine(bool bUseStyleColor)
    2285                 :            : {
    2286                 :            :     // syntax highlighting mode is ignored here
    2287                 :            :     // StringDiffer doesn't look at hyphenate, language items
    2288                 :            : 
    2289 [ +  + ][ -  + ]:        372 :     if (mpPattern == mpOldPattern && mpCondSet == mpOldCondSet)
    2290                 :        372 :         return;
    2291                 :            : 
    2292 [ +  - ][ +  - ]:        207 :     sal_Int32 nConfBackColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
                 [ +  - ]
    2293                 :            :     bool bCellContrast = bUseStyleColor &&
    2294 [ +  - ][ +  - ]:        207 :             Application::GetSettings().GetStyleSettings().GetHighContrastMode();
                 [ -  + ]
    2295                 :            : 
    2296 [ +  - ][ +  - ]:        207 :     SfxItemSet* pSet = new SfxItemSet( mpEngine->GetEmptyItemSet() );
                 [ +  - ]
    2297         [ +  - ]:        207 :     mpPattern->FillEditItemSet( pSet, mpCondSet );
    2298                 :            : 
    2299         [ +  - ]:        207 :     mpEngine->SetDefaults( pSet );
    2300                 :        207 :     mpOldPattern = mpPattern;
    2301                 :        207 :     mpOldCondSet = mpCondSet;
    2302                 :            : 
    2303         [ +  - ]:        207 :     sal_uLong nControl = mpEngine->GetControlWord();
    2304         [ -  + ]:        207 :     if (meOrient == SVX_ORIENTATION_STACKED)
    2305                 :          0 :         nControl |= EE_CNTRL_ONECHARPERLINE;
    2306                 :            :     else
    2307                 :        207 :         nControl &= ~EE_CNTRL_ONECHARPERLINE;
    2308         [ +  - ]:        207 :     mpEngine->SetControlWord( nControl );
    2309                 :            : 
    2310 [ +  - ][ +  - ]:        207 :     if ( !mbHyphenatorSet && ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() )
         [ +  + ][ +  + ]
    2311                 :            :     {
    2312                 :            :         //  set hyphenator the first time it is needed
    2313         [ +  - ]:         30 :         com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
    2314         [ +  - ]:         30 :         mpEngine->SetHyphenator( xXHyphenator );
    2315                 :         30 :         mbHyphenatorSet = true;
    2316                 :            :     }
    2317                 :            : 
    2318         [ +  - ]:        207 :     Color aBackCol = ((const SvxBrushItem&)mpPattern->GetItem( ATTR_BACKGROUND, mpCondSet )).GetColor();
    2319 [ +  + ][ -  + ]:        207 :     if ( bUseStyleColor && ( aBackCol.GetTransparency() > 0 || bCellContrast ) )
         [ +  + ][ +  - ]
    2320                 :        176 :         aBackCol.SetColor( nConfBackColor );
    2321         [ +  - ]:        372 :     mpEngine->SetBackgroundColor( aBackCol );
    2322                 :            : }
    2323                 :            : 
    2324                 :        526 : void ScOutputData::DrawEditParam::calcMargins(long& rTopM, long& rLeftM, long& rBottomM, long& rRightM, double nPPTX, double nPPTY) const
    2325                 :            : {
    2326                 :            :     const SvxMarginItem& rMargin =
    2327                 :        526 :         static_cast<const SvxMarginItem&>(mpPattern->GetItem(ATTR_MARGIN, mpCondSet));
    2328                 :            : 
    2329                 :        526 :     sal_uInt16 nIndent = 0;
    2330         [ +  + ]:        526 :     if (meHorJust == SVX_HOR_JUSTIFY_LEFT)
    2331                 :         13 :         nIndent = lcl_GetValue<SfxUInt16Item, sal_uInt16>(*mpPattern, ATTR_INDENT, mpCondSet);
    2332                 :            : 
    2333                 :        526 :     rLeftM   = static_cast<long>(((rMargin.GetLeftMargin() + nIndent) * nPPTX));
    2334                 :        526 :     rTopM    = static_cast<long>((rMargin.GetTopMargin() * nPPTY));
    2335                 :        526 :     rRightM  = static_cast<long>((rMargin.GetRightMargin() * nPPTX));
    2336                 :        526 :     rBottomM = static_cast<long>((rMargin.GetBottomMargin() * nPPTY));
    2337                 :        526 : }
    2338                 :            : 
    2339                 :        154 : void ScOutputData::DrawEditParam::calcPaperSize(
    2340                 :            :     Size& rPaperSize, const Rectangle& rAlignRect, double nPPTX, double nPPTY) const
    2341                 :            : {
    2342                 :            :     long nTopM, nLeftM, nBottomM, nRightM;
    2343         [ +  - ]:        154 :     calcMargins(nTopM, nLeftM, nBottomM, nRightM, nPPTX, nPPTY);
    2344                 :            : 
    2345         [ +  - ]:        154 :     if (isVerticallyOriented())
    2346                 :            :     {
    2347         [ +  - ]:        154 :         rPaperSize.Width() = rAlignRect.GetHeight() - nTopM - nBottomM;
    2348         [ +  - ]:        154 :         rPaperSize.Height() = rAlignRect.GetWidth() - nLeftM - nRightM;
    2349                 :            :     }
    2350                 :            :     else
    2351                 :            :     {
    2352         [ #  # ]:          0 :         rPaperSize.Width() = rAlignRect.GetWidth() - nLeftM - nRightM;
    2353         [ #  # ]:          0 :         rPaperSize.Height() = rAlignRect.GetHeight() - nTopM - nBottomM;
    2354                 :            :     }
    2355                 :            : 
    2356         [ -  + ]:        154 :     if (mbAsianVertical)
    2357                 :            :     {
    2358         [ #  # ]:          0 :         rPaperSize.Height() = rAlignRect.GetHeight() - nTopM - nBottomM;
    2359                 :            :         // Subtract some extra value from the height or else the text would go
    2360                 :            :         // outside the cell area.  The value of 5 is arbitrary, and is based
    2361                 :            :         // entirely on heuristics.
    2362                 :          0 :         rPaperSize.Height() -= 5;
    2363                 :            :     }
    2364                 :        154 : }
    2365                 :            : 
    2366                 :        372 : void ScOutputData::DrawEditParam::getEngineSize(ScFieldEditEngine* pEngine, long& rWidth, long& rHeight) const
    2367                 :            : {
    2368                 :        372 :     long nEngineWidth = 0;
    2369 [ +  + ][ +  - ]:        372 :     if (!mbBreak || meOrient == SVX_ORIENTATION_STACKED || mbAsianVertical)
                 [ -  + ]
    2370                 :        218 :         nEngineWidth = static_cast<long>(pEngine->CalcTextWidth());
    2371                 :            : 
    2372                 :        372 :     long nEngineHeight = pEngine->GetTextHeight();
    2373                 :            : 
    2374         [ +  + ]:        372 :     if (isVerticallyOriented())
    2375                 :            :     {
    2376                 :        193 :         long nTemp = nEngineWidth;
    2377                 :        193 :         nEngineWidth = nEngineHeight;
    2378                 :        193 :         nEngineHeight = nTemp;
    2379                 :            :     }
    2380                 :            : 
    2381         [ -  + ]:        372 :     if (meOrient == SVX_ORIENTATION_STACKED)
    2382                 :          0 :         nEngineWidth = nEngineWidth * 11 / 10;
    2383                 :            : 
    2384                 :        372 :     rWidth = nEngineWidth;
    2385                 :        372 :     rHeight = nEngineHeight;
    2386                 :        372 : }
    2387                 :            : 
    2388                 :        193 : bool ScOutputData::DrawEditParam::hasLineBreak() const
    2389                 :            : {
    2390 [ +  + ][ +  - ]:        193 :     return (mbBreak || (meOrient == SVX_ORIENTATION_STACKED) || mbAsianVertical);
                 [ -  + ]
    2391                 :            : }
    2392                 :            : 
    2393                 :          0 : bool ScOutputData::DrawEditParam::isHyperlinkCell() const
    2394                 :            : {
    2395         [ #  # ]:          0 :     if (!mpCell)
    2396                 :          0 :         return false;
    2397                 :            : 
    2398         [ #  # ]:          0 :     if (mpCell->GetCellType() != CELLTYPE_FORMULA)
    2399                 :          0 :         return false;
    2400                 :            : 
    2401         [ #  # ]:          0 :     return static_cast<ScFormulaCell*>(mpCell)->IsHyperLinkCell();
    2402                 :            : }
    2403                 :            : 
    2404                 :        898 : bool ScOutputData::DrawEditParam::isVerticallyOriented() const
    2405                 :            : {
    2406 [ +  + ][ -  + ]:        898 :     return (meOrient == SVX_ORIENTATION_TOPBOTTOM || meOrient == SVX_ORIENTATION_BOTTOMTOP);
    2407                 :            : }
    2408                 :            : 
    2409                 :        193 : void ScOutputData::DrawEditParam::calcStartPosForVertical(
    2410                 :            :     Point& rLogicStart, long nCellWidth, long nEngineWidth, long nTopM, OutputDevice* pRefDevice)
    2411                 :            : {
    2412                 :            :     OSL_ENSURE(isVerticallyOriented(), "Use this only for vertically oriented cell!");
    2413                 :            : 
    2414         [ +  - ]:        193 :     if (mbPixelToLogic)
    2415                 :        193 :         rLogicStart = pRefDevice->PixelToLogic(rLogicStart);
    2416                 :            : 
    2417         [ +  + ]:        193 :     if (mbBreak)
    2418                 :            :     {
    2419                 :            :         // vertical adjustment is within the EditEngine
    2420         [ +  - ]:        154 :         if (mbPixelToLogic)
    2421         [ +  - ]:        154 :             rLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
    2422                 :            :         else
    2423                 :          0 :             rLogicStart.Y() += nTopM;
    2424                 :            : 
    2425      [ -  +  + ]:        154 :         switch (meHorJust)
    2426                 :            :         {
    2427                 :            :             case SVX_HOR_JUSTIFY_CENTER:
    2428                 :          0 :                 rLogicStart.X() += (nCellWidth - nEngineWidth) / 2;
    2429                 :          0 :             break;
    2430                 :            :             case SVX_HOR_JUSTIFY_RIGHT:
    2431                 :         28 :                 rLogicStart.X() += nCellWidth - nEngineWidth;
    2432                 :        154 :             break;
    2433                 :            :             default:
    2434                 :            :                 ; // do nothing
    2435                 :            :         }
    2436                 :            :     }
    2437                 :        193 : }
    2438                 :            : 
    2439                 :        372 : void ScOutputData::DrawEditParam::setAlignmentToEngine()
    2440                 :            : {
    2441 [ +  + ][ -  + ]:        372 :     if (isVerticallyOriented() || mbAsianVertical)
                 [ +  + ]
    2442                 :            :     {
    2443                 :        193 :         SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
    2444   [ -  -  +  -  :        193 :         switch (meVerJust)
                      - ]
    2445                 :            :         {
    2446                 :            :             case SVX_VER_JUSTIFY_TOP:
    2447                 :            :                 eSvxAdjust = (meOrient == SVX_ORIENTATION_TOPBOTTOM || mbAsianVertical) ?
    2448 [ #  # ][ #  # ]:          0 :                             SVX_ADJUST_LEFT : SVX_ADJUST_RIGHT;
    2449                 :          0 :                 break;
    2450                 :            :             case SVX_VER_JUSTIFY_CENTER:
    2451                 :          0 :                 eSvxAdjust = SVX_ADJUST_CENTER;
    2452                 :          0 :                 break;
    2453                 :            :             case SVX_VER_JUSTIFY_BOTTOM:
    2454                 :            :             case SVX_VER_JUSTIFY_STANDARD:
    2455                 :            :                 eSvxAdjust = (meOrient == SVX_ORIENTATION_TOPBOTTOM || mbAsianVertical) ?
    2456 [ -  + ][ #  # ]:        193 :                             SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
    2457                 :        193 :                 break;
    2458                 :            :             case SVX_VER_JUSTIFY_BLOCK:
    2459                 :          0 :                 eSvxAdjust = SVX_ADJUST_BLOCK;
    2460                 :          0 :                 break;
    2461                 :            :         }
    2462                 :            : 
    2463         [ +  - ]:        193 :         mpEngine->SetDefaultItem( SvxAdjustItem(eSvxAdjust, EE_PARA_JUST) );
    2464         [ +  - ]:        193 :         mpEngine->SetDefaultItem( SvxJustifyMethodItem(meVerJustMethod, EE_PARA_JUST_METHOD) );
    2465                 :            : 
    2466         [ +  + ]:        193 :         if (meHorJust == SVX_HOR_JUSTIFY_BLOCK)
    2467         [ +  - ]:        117 :             mpEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
    2468                 :            :     }
    2469                 :            :     else
    2470                 :            :     {
    2471                 :            :         //  horizontal alignment now may depend on cell content
    2472                 :            :         //  (for values with number formats with mixed script types)
    2473                 :            :         //  -> always set adjustment
    2474                 :            : 
    2475                 :        179 :         SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
    2476         [ -  + ]:        179 :         if (meOrient == SVX_ORIENTATION_STACKED)
    2477                 :          0 :             eSvxAdjust = SVX_ADJUST_CENTER;
    2478         [ -  + ]:        179 :         else if (mbBreak)
    2479                 :            :         {
    2480         [ #  # ]:          0 :             if (meOrient == SVX_ORIENTATION_STANDARD)
    2481   [ #  #  #  #  :          0 :                 switch (meHorJust)
                   #  # ]
    2482                 :            :                 {
    2483                 :            :                     case SVX_HOR_JUSTIFY_STANDARD:
    2484         [ #  # ]:          0 :                         eSvxAdjust = mbCellIsValue ? SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
    2485                 :          0 :                         break;
    2486                 :            :                     case SVX_HOR_JUSTIFY_LEFT:
    2487                 :            :                     case SVX_HOR_JUSTIFY_REPEAT:            // nicht implementiert
    2488                 :          0 :                         eSvxAdjust = SVX_ADJUST_LEFT;
    2489                 :          0 :                         break;
    2490                 :            :                     case SVX_HOR_JUSTIFY_RIGHT:
    2491                 :          0 :                         eSvxAdjust = SVX_ADJUST_RIGHT;
    2492                 :          0 :                         break;
    2493                 :            :                     case SVX_HOR_JUSTIFY_CENTER:
    2494                 :          0 :                         eSvxAdjust = SVX_ADJUST_CENTER;
    2495                 :          0 :                         break;
    2496                 :            :                     case SVX_HOR_JUSTIFY_BLOCK:
    2497                 :          0 :                         eSvxAdjust = SVX_ADJUST_BLOCK;
    2498                 :          0 :                         break;
    2499                 :            :                 }
    2500                 :            :             else
    2501   [ #  #  #  #  :          0 :                 switch (meVerJust)
                      # ]
    2502                 :            :                 {
    2503                 :            :                     case SVX_VER_JUSTIFY_TOP:
    2504                 :          0 :                         eSvxAdjust = SVX_ADJUST_RIGHT;
    2505                 :          0 :                         break;
    2506                 :            :                     case SVX_VER_JUSTIFY_CENTER:
    2507                 :          0 :                         eSvxAdjust = SVX_ADJUST_CENTER;
    2508                 :          0 :                         break;
    2509                 :            :                     case SVX_VER_JUSTIFY_BOTTOM:
    2510                 :            :                     case SVX_VER_JUSTIFY_STANDARD:
    2511                 :          0 :                         eSvxAdjust = SVX_ADJUST_LEFT;
    2512                 :          0 :                         break;
    2513                 :            :                     case SVX_VER_JUSTIFY_BLOCK:
    2514                 :          0 :                         eSvxAdjust = SVX_ADJUST_BLOCK;
    2515                 :          0 :                         break;
    2516                 :            :                 }
    2517                 :            :         }
    2518                 :            : 
    2519         [ +  - ]:        179 :         mpEngine->SetDefaultItem( SvxAdjustItem(eSvxAdjust, EE_PARA_JUST) );
    2520                 :            : 
    2521         [ -  + ]:        179 :         if (mbAsianVertical)
    2522                 :            :         {
    2523         [ #  # ]:          0 :             mpEngine->SetDefaultItem( SvxJustifyMethodItem(meVerJustMethod, EE_PARA_JUST_METHOD) );
    2524         [ #  # ]:          0 :             if (meHorJust == SVX_HOR_JUSTIFY_BLOCK)
    2525         [ #  # ]:          0 :                 mpEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
    2526                 :            :         }
    2527                 :            :         else
    2528                 :            :         {
    2529         [ +  - ]:        179 :             mpEngine->SetDefaultItem( SvxJustifyMethodItem(meHorJustMethod, EE_PARA_JUST_METHOD) );
    2530         [ -  + ]:        179 :             if (meVerJust == SVX_VER_JUSTIFY_BLOCK)
    2531         [ #  # ]:          0 :                 mpEngine->SetDefaultItem( SvxVerJustifyItem(SVX_VER_JUSTIFY_BLOCK, EE_PARA_VER_JUST) );
    2532                 :            :         }
    2533                 :            :     }
    2534                 :            : 
    2535                 :        372 :     mpEngine->SetVertical(mbAsianVertical);
    2536 [ +  + ][ +  + ]:        372 :     if (mpCell && mpCell->GetCellType() == CELLTYPE_EDIT)
                 [ +  - ]
    2537                 :            :     {
    2538                 :            :         // We need to synchronize the vertical mode in the EditTextObject
    2539                 :            :         // instance too.  No idea why we keep this state in two separate
    2540                 :            :         // instances.
    2541                 :        219 :         ScEditCell* pEditCell = static_cast<ScEditCell*>(mpCell);
    2542                 :        219 :         const EditTextObject* pData = pEditCell->GetData();
    2543         [ +  - ]:        219 :         if (pData)
    2544                 :        219 :             const_cast<EditTextObject*>(pData)->SetVertical(mbAsianVertical);
    2545                 :            :     }
    2546                 :        372 : }
    2547                 :            : 
    2548                 :        178 : bool ScOutputData::DrawEditParam::adjustHorAlignment(ScFieldEditEngine* pEngine)
    2549                 :            : {
    2550 [ +  - ][ +  - ]:        178 :     if (meHorJust == SVX_HOR_JUSTIFY_RIGHT || meHorJust == SVX_HOR_JUSTIFY_CENTER ||
         [ +  + ][ -  + ]
    2551                 :            :         (meHorJust == SVX_HOR_JUSTIFY_STANDARD && mbCellIsValue))
    2552                 :            :     {
    2553                 :            :         SvxAdjust eEditAdjust = (meHorJust == SVX_HOR_JUSTIFY_CENTER) ?
    2554         [ #  # ]:          0 :             SVX_ADJUST_CENTER : SVX_ADJUST_RIGHT;
    2555                 :            : 
    2556                 :          0 :         pEngine->SetUpdateMode(false);
    2557         [ #  # ]:          0 :         pEngine->SetDefaultItem( SvxAdjustItem(eEditAdjust, EE_PARA_JUST) );
    2558                 :          0 :         pEngine->SetUpdateMode(true);
    2559                 :          0 :         return true;
    2560                 :            :     }
    2561                 :        178 :     return false;
    2562                 :            : }
    2563                 :            : 
    2564                 :        371 : void ScOutputData::DrawEditParam::adjustForRTL()
    2565                 :            : {
    2566 [ +  - ][ -  + ]:        371 :     if (!mpEngine->IsRightToLeft(0))
    2567                 :            :         // No RTL mode.
    2568                 :        371 :         return;
    2569                 :            : 
    2570                 :            :     //  For right-to-left, EditEngine always calculates its lines
    2571                 :            :     //  beginning from the right edge, but EditLine::nStartPosX is
    2572                 :            :     //  of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
    2573         [ #  # ]:          0 :     Size aLogicPaper = mpEngine->GetPaperSize();
    2574         [ #  # ]:          0 :     if ( aLogicPaper.Width() > USHRT_MAX )
    2575                 :            :     {
    2576                 :          0 :         aLogicPaper.Width() = USHRT_MAX;
    2577         [ #  # ]:        371 :         mpEngine->SetPaperSize(aLogicPaper);
    2578                 :            :     }
    2579                 :            : }
    2580                 :            : 
    2581                 :        371 : void ScOutputData::DrawEditParam::adjustForHyperlinkInPDF(Point aURLStart, OutputDevice* pDev)
    2582                 :            : {
    2583                 :            :     // PDF: whole-cell hyperlink from formula?
    2584 [ -  + ][ #  # ]:        371 :     vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
         [ #  # ][ #  # ]
    2585 [ -  + ][ #  # ]:        371 :     bool bHasURL = pPDFData && isHyperlinkCell();
    2586         [ -  + ]:        371 :     if (!bHasURL)
    2587                 :        371 :         return;
    2588                 :            : 
    2589         [ #  # ]:          0 :     long nURLWidth = (long) mpEngine->CalcTextWidth();
    2590         [ #  # ]:          0 :     long nURLHeight = mpEngine->GetTextHeight();
    2591         [ #  # ]:          0 :     if (mbBreak)
    2592                 :            :     {
    2593         [ #  # ]:          0 :         Size aPaper = mpEngine->GetPaperSize();
    2594         [ #  # ]:          0 :         if ( mbAsianVertical )
    2595                 :          0 :             nURLHeight = aPaper.Height();
    2596                 :            :         else
    2597                 :          0 :             nURLWidth = aPaper.Width();
    2598                 :            :     }
    2599         [ #  # ]:          0 :     if (isVerticallyOriented())
    2600                 :          0 :         std::swap( nURLWidth, nURLHeight );
    2601         [ #  # ]:          0 :     else if (mbAsianVertical)
    2602                 :          0 :         aURLStart.X() -= nURLWidth;
    2603                 :            : 
    2604         [ #  # ]:          0 :     Rectangle aURLRect( aURLStart, Size( nURLWidth, nURLHeight ) );
    2605         [ #  # ]:        371 :     lcl_DoHyperlinkResult( pDev, aURLRect, mpCell );
    2606                 :            : }
    2607                 :            : 
    2608                 :        840 : void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
    2609                 :            : {
    2610                 :            :     OSL_ASSERT(rParam.meOrient == SVX_ORIENTATION_STANDARD);
    2611                 :            :     OSL_ASSERT(!rParam.mbAsianVertical);
    2612                 :            : 
    2613         [ +  - ]:        840 :     Size aRefOne = mpRefDevice->PixelToLogic(Size(1,1));
    2614                 :            : 
    2615                 :        840 :     bool bHidden = false;
    2616 [ -  + ][ #  # ]:        840 :     bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
    2617 [ +  + ][ +  - ]:        840 :     bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
         [ +  - ][ +  + ]
    2618         [ +  - ]:        840 :     long nAttrRotate = lcl_GetValue<SfxInt32Item, long>(*rParam.mpPattern, ATTR_ROTATE_VALUE, rParam.mpCondSet);
    2619                 :            : 
    2620         [ -  + ]:        840 :     if ( rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT )
    2621                 :            :     {
    2622                 :            :         // ignore orientation/rotation if "repeat" is active
    2623                 :          0 :         rParam.meOrient = SVX_ORIENTATION_STANDARD;
    2624                 :          0 :         nAttrRotate = 0;
    2625                 :            : 
    2626                 :            :         // #i31843# "repeat" with "line breaks" is treated as default alignment
    2627                 :            :         // (but rotation is still disabled)
    2628         [ #  # ]:          0 :         if ( rParam.mbBreak )
    2629                 :          0 :             rParam.meHorJust = SVX_HOR_JUSTIFY_STANDARD;
    2630                 :            :     }
    2631                 :            : 
    2632         [ +  + ]:        840 :     if (nAttrRotate)
    2633                 :            :     {
    2634                 :            :         //! Flag setzen, um die Zelle in DrawRotated wiederzufinden ?
    2635                 :            :         //! (oder Flag schon bei DrawBackground, dann hier keine Abfrage)
    2636                 :        661 :         bHidden = true;     // gedreht wird getrennt ausgegeben
    2637                 :            :     }
    2638                 :            : 
    2639                 :        840 :     SvxCellHorJustify eOutHorJust = rParam.meHorJust;
    2640         [ +  + ]:        840 :     if (eOutHorJust == SVX_HOR_JUSTIFY_STANDARD)
    2641                 :            :     {
    2642                 :            :         // fdo#32530: Default alignment depends on value vs string, and the
    2643                 :            :         // direction of the 1st letter.
    2644         [ -  + ]:        166 :         if (rParam.mbRTL)
    2645         [ #  # ]:          0 :             eOutHorJust = rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_LEFT : SVX_HOR_JUSTIFY_RIGHT;
    2646                 :            :         else
    2647         [ -  + ]:        166 :             eOutHorJust = rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT;
    2648                 :            :     }
    2649                 :            : 
    2650 [ +  + ][ -  + ]:        840 :     if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
    2651                 :        261 :         eOutHorJust = SVX_HOR_JUSTIFY_LEFT;     // repeat is not yet implemented
    2652                 :            : 
    2653         [ +  + ]:        840 :     if (bHidden)
    2654                 :            :         return;
    2655                 :            : 
    2656                 :            :     //! mirror margin values for RTL?
    2657                 :            :     //! move margin down to after final GetOutputArea call
    2658                 :            :     long nTopM, nLeftM, nBottomM, nRightM;
    2659         [ +  - ]:        179 :     rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, mnPPTX, mnPPTY);
    2660                 :            : 
    2661                 :        179 :     SCCOL nXForPos = rParam.mnX;
    2662         [ +  + ]:        179 :     if ( nXForPos < nX1 )
    2663                 :            :     {
    2664                 :          1 :         nXForPos = nX1;
    2665                 :          1 :         rParam.mnPosX = rParam.mnInitPosX;
    2666                 :            :     }
    2667                 :        179 :     SCSIZE nArrYForPos = rParam.mnArrY;
    2668         [ -  + ]:        179 :     if ( nArrYForPos < 1 )
    2669                 :            :     {
    2670                 :          0 :         nArrYForPos = 1;
    2671                 :          0 :         rParam.mnPosY = nScrY;
    2672                 :            :     }
    2673                 :            : 
    2674         [ +  - ]:        179 :     OutputAreaParam aAreaParam;
    2675                 :            : 
    2676                 :            :     //
    2677                 :            :     //  Initial page size - large for normal text, cell size for automatic line breaks
    2678                 :            :     //
    2679                 :            : 
    2680                 :        179 :     Size aPaperSize = Size( 1000000, 1000000 );
    2681         [ -  + ]:        179 :     if (rParam.mbBreak)
    2682                 :            :     {
    2683                 :            :         //  call GetOutputArea with nNeeded=0, to get only the cell width
    2684                 :            : 
    2685                 :            :         //! handle nArrY == 0
    2686                 :            :         GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
    2687                 :          0 :                        *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    2688         [ #  # ]:          0 :                        rParam.mbCellIsValue, true, false, aAreaParam );
    2689                 :            : 
    2690                 :            :         //! special ScEditUtil handling if formatting for printer
    2691         [ #  # ]:          0 :         rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, mnPPTX, mnPPTY);
    2692                 :            :     }
    2693         [ +  + ]:        179 :     if (rParam.mbPixelToLogic)
    2694                 :            :     {
    2695         [ +  - ]:        162 :         Size aLogicSize = mpRefDevice->PixelToLogic(aPaperSize);
    2696 [ -  + ][ #  # ]:        162 :         if ( rParam.mbBreak && !rParam.mbAsianVertical && mpRefDevice != pFmtDevice )
                 [ #  # ]
    2697                 :            :         {
    2698                 :            :             // #i85342# screen display and formatting for printer,
    2699                 :            :             // use same GetEditArea call as in ScViewData::SetEditEngine
    2700                 :            : 
    2701         [ #  # ]:          0 :             Fraction aFract(1,1);
    2702                 :            :             Rectangle aUtilRect = ScEditUtil( mpDoc, rParam.mnCellX, rParam.mnCellY, nTab, Point(0,0), pFmtDevice,
    2703 [ #  # ][ #  # ]:          0 :                 HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( rParam.mpPattern, false );
    2704         [ #  # ]:          0 :             aLogicSize.Width() = aUtilRect.GetWidth();
    2705                 :            :         }
    2706         [ +  - ]:        162 :         rParam.mpEngine->SetPaperSize(aLogicSize);
    2707                 :            :     }
    2708                 :            :     else
    2709         [ +  - ]:         17 :         rParam.mpEngine->SetPaperSize(aPaperSize);
    2710                 :            : 
    2711                 :            :     //
    2712                 :            :     //  Fill the EditEngine (cell attributes and text)
    2713                 :            :     //
    2714                 :            : 
    2715                 :            :     // default alignment for asian vertical mode is top-right
    2716 [ -  + ][ #  # ]:        179 :     if ( rParam.mbAsianVertical && rParam.meVerJust == SVX_VER_JUSTIFY_STANDARD )
    2717                 :          0 :         rParam.meVerJust = SVX_VER_JUSTIFY_TOP;
    2718                 :            : 
    2719         [ +  - ]:        179 :     rParam.setPatternToEngine(mbUseStyleColor);
    2720         [ +  - ]:        179 :     rParam.setAlignmentToEngine();
    2721                 :            : 
    2722                 :            :     //  Read content from cell
    2723                 :            : 
    2724                 :        179 :     bool bWrapFields = false;
    2725 [ +  - ][ +  - ]:        179 :     if (!rParam.readCellContent(mpDoc, mbShowNullValues, mbShowFormulas, mbSyntaxMode, mbUseStyleColor, mbForceAutoColor, bWrapFields))
    2726                 :            :         // Failed to read cell content.  Bail out.
    2727                 :            :         return;
    2728                 :            : 
    2729         [ -  + ]:        179 :     if ( mbSyntaxMode )
    2730         [ #  # ]:          0 :         SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
    2731 [ +  - ][ -  + ]:        179 :     else if ( mbUseStyleColor && mbForceAutoColor )
    2732         [ #  # ]:          0 :         lcl_SetEditColor( *rParam.mpEngine, COL_AUTO );     //! or have a flag at EditEngine
    2733                 :            : 
    2734         [ +  - ]:        179 :     rParam.mpEngine->SetUpdateMode( true );     // after SetText, before CalcTextWidth/GetTextHeight
    2735                 :            : 
    2736                 :            :     //
    2737                 :            :     //  Get final output area using the calculated width
    2738                 :            :     //
    2739                 :            : 
    2740                 :            :     long nEngineWidth, nEngineHeight;
    2741         [ +  - ]:        179 :     rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
    2742                 :            : 
    2743                 :        179 :     long nNeededPixel = nEngineWidth;
    2744         [ +  + ]:        179 :     if (rParam.mbPixelToLogic)
    2745         [ +  - ]:        162 :         nNeededPixel = mpRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
    2746                 :        179 :     nNeededPixel += nLeftM + nRightM;
    2747                 :            : 
    2748 [ -  + ][ #  # ]:        179 :     if (!rParam.mbBreak || bShrink)
    2749                 :            :     {
    2750                 :            :         // for break, the first GetOutputArea call is sufficient
    2751                 :            :         GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
    2752                 :        179 :                        *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    2753 [ +  - ][ +  - ]:        358 :                        rParam.mbCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
         [ -  + ][ +  - ]
    2754                 :            : 
    2755         [ -  + ]:        179 :         if ( bShrink )
    2756                 :            :         {
    2757                 :            :             ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
    2758                 :            :                 nLeftM, nTopM, nRightM, nBottomM, true,
    2759                 :          0 :                 sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
    2760                 :            :                 nEngineWidth, nEngineHeight, nNeededPixel,
    2761         [ #  # ]:          0 :                 aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
    2762                 :            :         }
    2763 [ -  + ][ #  # ]:        179 :         if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
    2764                 :            :         {
    2765                 :            :             // First check if twice the space for the formatted text is available
    2766                 :            :             // (otherwise just keep it unchanged).
    2767                 :            : 
    2768                 :          0 :             long nFormatted = nNeededPixel - nLeftM - nRightM;      // without margin
    2769         [ #  # ]:          0 :             long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
    2770         [ #  # ]:          0 :             if ( nAvailable >= 2 * nFormatted )
    2771                 :            :             {
    2772                 :            :                 // "repeat" is handled with unformatted text (for performance reasons)
    2773         [ #  # ]:          0 :                 String aCellStr = rParam.mpEngine->GetText();
    2774         [ #  # ]:          0 :                 rParam.mpEngine->SetText( aCellStr );
    2775                 :            : 
    2776         [ #  # ]:          0 :                 long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
    2777         [ #  # ]:          0 :                 if (rParam.mbPixelToLogic)
    2778         [ #  # ]:          0 :                     nRepeatSize = mpRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
    2779         [ #  # ]:          0 :                 if ( pFmtDevice != mpRefDevice )
    2780                 :          0 :                     ++nRepeatSize;
    2781         [ #  # ]:          0 :                 if ( nRepeatSize > 0 )
    2782                 :            :                 {
    2783                 :          0 :                     long nRepeatCount = nAvailable / nRepeatSize;
    2784         [ #  # ]:          0 :                     if ( nRepeatCount > 1 )
    2785                 :            :                     {
    2786         [ #  # ]:          0 :                         String aRepeated = aCellStr;
    2787         [ #  # ]:          0 :                         for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
    2788         [ #  # ]:          0 :                             aRepeated.Append( aCellStr );
    2789         [ #  # ]:          0 :                         rParam.mpEngine->SetText( aRepeated );
    2790                 :            : 
    2791         [ #  # ]:          0 :                         nEngineHeight = rParam.mpEngine->GetTextHeight();
    2792         [ #  # ]:          0 :                         nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
    2793         [ #  # ]:          0 :                         if (rParam.mbPixelToLogic)
    2794         [ #  # ]:          0 :                             nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
    2795                 :            :                         else
    2796                 :          0 :                             nNeededPixel = nEngineWidth;
    2797         [ #  # ]:          0 :                         nNeededPixel += nLeftM + nRightM;
    2798                 :            :                     }
    2799         [ #  # ]:          0 :                 }
    2800                 :            :             }
    2801                 :            :         }
    2802                 :            : 
    2803 [ -  + ][ #  # ]:        179 :         if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
                 [ #  # ]
    2804                 :            :         {
    2805 [ #  # ][ #  # ]:          0 :             rParam.mpEngine->SetText(rtl::OUString("###"));
                 [ #  # ]
    2806         [ #  # ]:          0 :             nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
    2807         [ #  # ]:          0 :             if (rParam.mbPixelToLogic)
    2808         [ #  # ]:          0 :                 nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
    2809                 :            :             else
    2810                 :          0 :                 nNeededPixel = nEngineWidth;
    2811                 :          0 :             nNeededPixel += nLeftM + nRightM;
    2812                 :            : 
    2813                 :            :             //  No clip marks if "###" doesn't fit (same as in DrawStrings)
    2814                 :            :         }
    2815                 :            : 
    2816         [ -  + ]:        179 :         if (eOutHorJust != SVX_HOR_JUSTIFY_LEFT)
    2817                 :            :         {
    2818                 :          0 :             aPaperSize.Width() = nNeededPixel + 1;
    2819         [ #  # ]:          0 :             if (rParam.mbPixelToLogic)
    2820 [ #  # ][ #  # ]:          0 :                 rParam.mpEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
    2821                 :            :             else
    2822         [ #  # ]:          0 :                 rParam.mpEngine->SetPaperSize(aPaperSize);
    2823                 :            :         }
    2824                 :            :     }
    2825                 :            : 
    2826                 :        179 :     long nStartX = aAreaParam.maAlignRect.Left();
    2827                 :        179 :     long nStartY = aAreaParam.maAlignRect.Top();
    2828         [ +  - ]:        179 :     long nCellWidth = aAreaParam.maAlignRect.GetWidth();
    2829                 :        179 :     long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
    2830         [ +  - ]:        179 :     long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
    2831                 :            : 
    2832         [ -  + ]:        179 :     if (rParam.mbBreak)
    2833                 :            :     {
    2834                 :            :         //  text with automatic breaks is aligned only within the
    2835                 :            :         //  edit engine's paper size, the output of the whole area
    2836                 :            :         //  is always left-aligned
    2837                 :            : 
    2838                 :          0 :         nStartX += nLeftM;
    2839                 :            :     }
    2840                 :            :     else
    2841                 :            :     {
    2842         [ -  + ]:        179 :         if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
    2843                 :          0 :             nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
    2844         [ -  + ]:        179 :         else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
    2845                 :          0 :             nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
    2846                 :            :         else
    2847                 :        179 :             nStartX += nLeftM;
    2848                 :            :     }
    2849                 :            : 
    2850 [ +  + ][ -  + ]:        179 :     bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
    2851         [ +  + ]:        179 :     if (bOutside)
    2852                 :            :         return;
    2853                 :            : 
    2854         [ -  + ]:        178 :     if ( aAreaParam.maClipRect.Left() < nScrX )
    2855                 :            :     {
    2856                 :          0 :         aAreaParam.maClipRect.Left() = nScrX;
    2857                 :          0 :         aAreaParam.mbLeftClip = true;
    2858                 :            :     }
    2859         [ -  + ]:        178 :     if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
    2860                 :            :     {
    2861                 :          0 :         aAreaParam.maClipRect.Right() = nScrX + nScrW;          //! minus one?
    2862                 :          0 :         aAreaParam.mbRightClip = true;
    2863                 :            :     }
    2864                 :            : 
    2865 [ +  - ][ +  + ]:        178 :     bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
    2866                 :        178 :     bool bSimClip = false;
    2867                 :            : 
    2868         [ -  + ]:        178 :     if ( bWrapFields )
    2869                 :            :     {
    2870                 :            :         //  Fields in a cell with automatic breaks: clip to cell width
    2871                 :          0 :         bClip = true;
    2872                 :            :     }
    2873                 :            : 
    2874         [ -  + ]:        178 :     if ( aAreaParam.maClipRect.Top() < nScrY )
    2875                 :            :     {
    2876                 :          0 :         aAreaParam.maClipRect.Top() = nScrY;
    2877                 :          0 :         bClip = true;
    2878                 :            :     }
    2879         [ -  + ]:        178 :     if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
    2880                 :            :     {
    2881                 :          0 :         aAreaParam.maClipRect.Bottom() = nScrY + nScrH;     //! minus one?
    2882                 :          0 :         bClip = true;
    2883                 :            :     }
    2884                 :            : 
    2885                 :        178 :     Size aCellSize;         // output area, excluding margins, in logical units
    2886         [ +  + ]:        178 :     if (rParam.mbPixelToLogic)
    2887         [ +  - ]:        161 :         aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
    2888                 :            :     else
    2889                 :         17 :         aCellSize = Size( nOutWidth, nOutHeight );
    2890                 :            : 
    2891         [ +  + ]:        178 :     if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
    2892                 :            :     {
    2893                 :            :         const ScMergeAttr* pMerge =
    2894         [ +  - ]:        146 :                 (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
    2895 [ +  - ][ -  + ]:        146 :         bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
    2896                 :            : 
    2897                 :            :         //  Don't clip for text height when printing rows with optimal height,
    2898                 :            :         //  except when font size is from conditional formatting.
    2899                 :            :         //! Allow clipping when vertically merged?
    2900 [ +  + ][ +  - ]:        163 :         if ( eType != OUTTYPE_PRINTER ||
         [ -  + ][ #  # ]
                 [ +  + ]
    2901         [ +  - ]:         17 :             ( mpDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
    2902                 :            :             ( rParam.mpCondSet && SFX_ITEM_SET ==
    2903         [ #  # ]:          0 :                 rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
    2904                 :        129 :             bClip = true;
    2905                 :            :         else
    2906                 :         17 :             bSimClip = true;
    2907                 :            : 
    2908                 :            :         //  Show clip marks if height is at least 5pt too small and
    2909                 :            :         //  there are several lines of text.
    2910                 :            :         //  Not for asian vertical text, because that would interfere
    2911                 :            :         //  with the default right position of the text.
    2912                 :            :         //  Only with automatic line breaks, to avoid having to find
    2913                 :            :         //  the cells with the horizontal end of the text again.
    2914 [ -  + ][ #  # ]:        146 :         if ( nEngineHeight - aCellSize.Height() > 100 &&
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
    2915                 :            :              rParam.mbBreak && bMarkClipped &&
    2916 [ #  # ][ #  # ]:          0 :              ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
    2917                 :            :         {
    2918                 :          0 :             CellInfo* pClipMarkCell = NULL;
    2919         [ #  # ]:          0 :             if ( bMerged )
    2920                 :            :             {
    2921                 :            :                 //  anywhere in the merged area...
    2922         [ #  # ]:          0 :                 SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
    2923         [ #  # ]:          0 :                 pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
    2924                 :            :             }
    2925                 :            :             else
    2926                 :          0 :                 pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
    2927                 :            : 
    2928                 :          0 :             pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT;      //! also allow left?
    2929                 :          0 :             bAnyClipped = true;
    2930                 :            : 
    2931                 :          0 :             long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
    2932         [ #  # ]:          0 :             if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
    2933                 :          0 :                 aAreaParam.maClipRect.Right() -= nMarkPixel;
    2934                 :            :         }
    2935                 :            :     }
    2936                 :            : 
    2937         [ +  - ]:        178 :     Rectangle aLogicClip;
    2938 [ +  + ][ +  + ]:        178 :     if (bClip || bSimClip)
    2939                 :            :     {
    2940                 :            :         // Clip marks are already handled in GetOutputArea
    2941                 :            : 
    2942         [ +  + ]:        146 :         if (rParam.mbPixelToLogic)
    2943         [ +  - ]:        129 :             aLogicClip = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
    2944                 :            :         else
    2945                 :         17 :             aLogicClip = aAreaParam.maClipRect;
    2946                 :            : 
    2947         [ +  + ]:        146 :         if (bClip)  // bei bSimClip nur aClipRect initialisieren
    2948                 :            :         {
    2949         [ -  + ]:        129 :             if (bMetaFile)
    2950                 :            :             {
    2951         [ #  # ]:          0 :                 mpDev->Push();
    2952         [ #  # ]:          0 :                 mpDev->IntersectClipRegion( aLogicClip );
    2953                 :            :             }
    2954                 :            :             else
    2955 [ +  - ][ +  - ]:        129 :                 mpDev->SetClipRegion( Region( aLogicClip ) );
                 [ +  - ]
    2956                 :            :         }
    2957                 :            :     }
    2958                 :            : 
    2959                 :        178 :     Point aLogicStart;
    2960         [ +  + ]:        178 :     if (rParam.mbPixelToLogic)
    2961         [ +  - ]:        161 :         aLogicStart = mpRefDevice->PixelToLogic( Point(nStartX,nStartY) );
    2962                 :            :     else
    2963                 :         17 :         aLogicStart = Point(nStartX, nStartY);
    2964                 :            : 
    2965         [ +  - ]:        178 :     if (!rParam.mbBreak)
    2966                 :            :     {
    2967                 :            :         //  horizontal alignment
    2968 [ +  - ][ -  + ]:        178 :         if (rParam.adjustHorAlignment(rParam.mpEngine))
    2969                 :            :             // reset adjustment for the next cell
    2970                 :          0 :             rParam.mpOldPattern = NULL;
    2971                 :            :     }
    2972                 :            : 
    2973 [ +  - ][ +  - ]:        178 :     if (rParam.meVerJust==SVX_VER_JUSTIFY_BOTTOM ||
    2974                 :            :         rParam.meVerJust==SVX_VER_JUSTIFY_STANDARD)
    2975                 :            :     {
    2976                 :            :         //! if pRefDevice != pFmtDevice, keep heights in logic units,
    2977                 :            :         //! only converting margin?
    2978                 :            : 
    2979         [ +  + ]:        356 :         if (rParam.mbPixelToLogic)
    2980                 :        161 :             aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0, nTopM +
    2981         [ +  - ]:        322 :                             mpRefDevice->LogicToPixel(aCellSize).Height() -
    2982         [ +  - ]:        161 :                             mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
    2983         [ +  - ]:        161 :                             )).Height();
    2984                 :            :         else
    2985                 :         17 :             aLogicStart.Y() += nTopM + aCellSize.Height() - nEngineHeight;
    2986                 :            :     }
    2987         [ #  # ]:          0 :     else if (rParam.meVerJust==SVX_VER_JUSTIFY_CENTER)
    2988                 :            :     {
    2989         [ #  # ]:          0 :         if (rParam.mbPixelToLogic)
    2990                 :          0 :             aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0, nTopM + (
    2991         [ #  # ]:          0 :                             mpRefDevice->LogicToPixel(aCellSize).Height() -
    2992         [ #  # ]:          0 :                             mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height() )
    2993         [ #  # ]:          0 :                             / 2)).Height();
    2994                 :            :         else
    2995                 :          0 :             aLogicStart.Y() += nTopM + (aCellSize.Height() - nEngineHeight) / 2;
    2996                 :            :     }
    2997                 :            :     else        // top
    2998                 :            :     {
    2999         [ #  # ]:          0 :         if (rParam.mbPixelToLogic)
    3000         [ #  # ]:          0 :             aLogicStart.Y() += mpRefDevice->PixelToLogic(Size(0,nTopM)).Height();
    3001                 :            :         else
    3002                 :          0 :             aLogicStart.Y() += nTopM;
    3003                 :            :     }
    3004                 :            : 
    3005                 :        178 :     Point aURLStart = aLogicStart;      // copy before modifying for orientation
    3006                 :            : 
    3007         [ +  - ]:        178 :     rParam.adjustForRTL();
    3008                 :            : 
    3009                 :            :     // bMoveClipped handling has been replaced by complete alignment
    3010                 :            :     // handling (also extending to the left).
    3011                 :            : 
    3012         [ +  + ]:        178 :     if (bSimClip)
    3013                 :            :     {
    3014                 :            :         //  kein hartes Clipping, aber nur die betroffenen
    3015                 :            :         //  Zeilen ausgeben
    3016                 :            : 
    3017                 :         17 :         Point aDocStart = aLogicClip.TopLeft();
    3018                 :         17 :         aDocStart -= aLogicStart;
    3019         [ +  - ]:         17 :         rParam.mpEngine->Draw( mpDev, aLogicClip, aDocStart, false );
    3020                 :            :     }
    3021                 :            :     else
    3022                 :            :     {
    3023         [ +  - ]:        161 :         rParam.mpEngine->Draw(mpDev, aLogicStart, 0);
    3024                 :            :     }
    3025                 :            : 
    3026         [ +  + ]:        178 :     if (bClip)
    3027                 :            :     {
    3028         [ -  + ]:        129 :         if (bMetaFile)
    3029         [ #  # ]:          0 :             mpDev->Pop();
    3030                 :            :         else
    3031         [ +  - ]:        129 :             mpDev->SetClipRegion();
    3032                 :            :     }
    3033                 :            : 
    3034         [ +  - ]:        840 :     rParam.adjustForHyperlinkInPDF(aURLStart, mpDev);
    3035                 :            : }
    3036                 :            : 
    3037                 :          0 : void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
    3038                 :            : {
    3039                 :            :     OSL_ASSERT(rParam.meHorJust != SVX_HOR_JUSTIFY_REPEAT);
    3040         [ #  # ]:          0 :     Size aRefOne = mpRefDevice->PixelToLogic(Size(1,1));
    3041                 :            : 
    3042 [ #  # ][ #  # ]:          0 :     bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
    3043 [ #  # ][ #  # ]:          0 :     bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
         [ #  # ][ #  # ]
    3044                 :            : 
    3045                 :            :     SvxCellHorJustify eOutHorJust =
    3046                 :            :         ( rParam.meHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? rParam.meHorJust :
    3047 [ #  # ][ #  # ]:          0 :         ( rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
    3048                 :            : 
    3049 [ #  # ][ #  # ]:          0 :     if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
    3050                 :          0 :         eOutHorJust = SVX_HOR_JUSTIFY_LEFT;     // repeat is not yet implemented
    3051                 :            : 
    3052                 :            :     //! mirror margin values for RTL?
    3053                 :            :     //! move margin down to after final GetOutputArea call
    3054                 :            :     long nTopM, nLeftM, nBottomM, nRightM;
    3055         [ #  # ]:          0 :     rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, mnPPTX, mnPPTY);
    3056                 :            : 
    3057                 :          0 :     SCCOL nXForPos = rParam.mnX;
    3058         [ #  # ]:          0 :     if ( nXForPos < nX1 )
    3059                 :            :     {
    3060                 :          0 :         nXForPos = nX1;
    3061                 :          0 :         rParam.mnPosX = rParam.mnInitPosX;
    3062                 :            :     }
    3063                 :          0 :     SCSIZE nArrYForPos = rParam.mnArrY;
    3064         [ #  # ]:          0 :     if ( nArrYForPos < 1 )
    3065                 :            :     {
    3066                 :          0 :         nArrYForPos = 1;
    3067                 :          0 :         rParam.mnPosY = nScrY;
    3068                 :            :     }
    3069                 :            : 
    3070         [ #  # ]:          0 :     OutputAreaParam aAreaParam;
    3071                 :            : 
    3072                 :            :     //
    3073                 :            :     //  Initial page size - large for normal text, cell size for automatic line breaks
    3074                 :            :     //
    3075                 :            : 
    3076                 :          0 :     Size aPaperSize = Size( 1000000, 1000000 );
    3077         [ #  # ]:          0 :     if (rParam.mbBreak)
    3078                 :            :     {
    3079                 :            :         //  call GetOutputArea with nNeeded=0, to get only the cell width
    3080                 :            : 
    3081                 :            :         //! handle nArrY == 0
    3082                 :            :         GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
    3083                 :          0 :                        *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    3084         [ #  # ]:          0 :                        rParam.mbCellIsValue, true, false, aAreaParam );
    3085                 :            : 
    3086                 :            :         //! special ScEditUtil handling if formatting for printer
    3087         [ #  # ]:          0 :         rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, mnPPTX, mnPPTY);
    3088                 :            :     }
    3089         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    3090                 :            :     {
    3091         [ #  # ]:          0 :         Size aLogicSize = mpRefDevice->PixelToLogic(aPaperSize);
    3092         [ #  # ]:          0 :         rParam.mpEngine->SetPaperSize(aLogicSize);
    3093                 :            :     }
    3094                 :            :     else
    3095         [ #  # ]:          0 :         rParam.mpEngine->SetPaperSize(aPaperSize);
    3096                 :            : 
    3097                 :            :     //
    3098                 :            :     //  Fill the EditEngine (cell attributes and text)
    3099                 :            :     //
    3100                 :            : 
    3101         [ #  # ]:          0 :     rParam.setPatternToEngine(mbUseStyleColor);
    3102         [ #  # ]:          0 :     rParam.setAlignmentToEngine();
    3103                 :            : 
    3104                 :            :     //  Read content from cell
    3105                 :            : 
    3106                 :          0 :     bool bWrapFields = false;
    3107 [ #  # ][ #  # ]:          0 :     if (!rParam.readCellContent(mpDoc, mbShowNullValues, mbShowFormulas, mbSyntaxMode, mbUseStyleColor, mbForceAutoColor, bWrapFields))
    3108                 :            :         // Failed to read cell content.  Bail out.
    3109                 :            :         return;
    3110                 :            : 
    3111         [ #  # ]:          0 :     if ( mbSyntaxMode )
    3112         [ #  # ]:          0 :         SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
    3113 [ #  # ][ #  # ]:          0 :     else if ( mbUseStyleColor && mbForceAutoColor )
    3114         [ #  # ]:          0 :         lcl_SetEditColor( *rParam.mpEngine, COL_AUTO );     //! or have a flag at EditEngine
    3115                 :            : 
    3116         [ #  # ]:          0 :     rParam.mpEngine->SetUpdateMode( true );     // after SetText, before CalcTextWidth/GetTextHeight
    3117                 :            : 
    3118                 :            :     //
    3119                 :            :     //  Get final output area using the calculated width
    3120                 :            :     //
    3121                 :            : 
    3122                 :            :     long nEngineWidth, nEngineHeight;
    3123         [ #  # ]:          0 :     rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
    3124                 :            : 
    3125                 :          0 :     long nNeededPixel = nEngineWidth;
    3126         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    3127         [ #  # ]:          0 :         nNeededPixel = mpRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
    3128                 :          0 :     nNeededPixel += nLeftM + nRightM;
    3129                 :            : 
    3130 [ #  # ][ #  # ]:          0 :     if (!rParam.mbBreak || bShrink)
    3131                 :            :     {
    3132                 :            :         // for break, the first GetOutputArea call is sufficient
    3133                 :            :         GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
    3134                 :          0 :                        *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    3135 [ #  # ][ #  # ]:          0 :                        rParam.mbCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
         [ #  # ][ #  # ]
    3136                 :            : 
    3137         [ #  # ]:          0 :         if ( bShrink )
    3138                 :            :         {
    3139                 :            :             ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
    3140                 :            :                 nLeftM, nTopM, nRightM, nBottomM, false,
    3141                 :          0 :                 sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
    3142                 :            :                 nEngineWidth, nEngineHeight, nNeededPixel,
    3143         [ #  # ]:          0 :                 aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
    3144                 :            :         }
    3145 [ #  # ][ #  # ]:          0 :         if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3146                 :            :         {
    3147                 :            :             // First check if twice the space for the formatted text is available
    3148                 :            :             // (otherwise just keep it unchanged).
    3149                 :            : 
    3150                 :          0 :             long nFormatted = nNeededPixel - nLeftM - nRightM;      // without margin
    3151         [ #  # ]:          0 :             long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
    3152         [ #  # ]:          0 :             if ( nAvailable >= 2 * nFormatted )
    3153                 :            :             {
    3154                 :            :                 // "repeat" is handled with unformatted text (for performance reasons)
    3155         [ #  # ]:          0 :                 String aCellStr = rParam.mpEngine->GetText();
    3156         [ #  # ]:          0 :                 rParam.mpEngine->SetText( aCellStr );
    3157                 :            : 
    3158         [ #  # ]:          0 :                 long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
    3159         [ #  # ]:          0 :                 if (rParam.mbPixelToLogic)
    3160         [ #  # ]:          0 :                     nRepeatSize = mpRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
    3161         [ #  # ]:          0 :                 if ( pFmtDevice != mpRefDevice )
    3162                 :          0 :                     ++nRepeatSize;
    3163         [ #  # ]:          0 :                 if ( nRepeatSize > 0 )
    3164                 :            :                 {
    3165                 :          0 :                     long nRepeatCount = nAvailable / nRepeatSize;
    3166         [ #  # ]:          0 :                     if ( nRepeatCount > 1 )
    3167                 :            :                     {
    3168         [ #  # ]:          0 :                         String aRepeated = aCellStr;
    3169         [ #  # ]:          0 :                         for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
    3170         [ #  # ]:          0 :                             aRepeated.Append( aCellStr );
    3171         [ #  # ]:          0 :                         rParam.mpEngine->SetText( aRepeated );
    3172                 :            : 
    3173         [ #  # ]:          0 :                         nEngineHeight = rParam.mpEngine->GetTextHeight();
    3174         [ #  # ]:          0 :                         nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
    3175         [ #  # ]:          0 :                         if (rParam.mbPixelToLogic)
    3176         [ #  # ]:          0 :                             nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
    3177                 :            :                         else
    3178                 :          0 :                             nNeededPixel = nEngineWidth;
    3179         [ #  # ]:          0 :                         nNeededPixel += nLeftM + nRightM;
    3180                 :            :                     }
    3181         [ #  # ]:          0 :                 }
    3182                 :            :             }
    3183                 :            :         }
    3184                 :            : 
    3185 [ #  # ][ #  # ]:          0 :         if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
                 [ #  # ]
    3186                 :            :         {
    3187 [ #  # ][ #  # ]:          0 :             rParam.mpEngine->SetText(rtl::OUString("###"));
                 [ #  # ]
    3188         [ #  # ]:          0 :             nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
    3189         [ #  # ]:          0 :             if (rParam.mbPixelToLogic)
    3190         [ #  # ]:          0 :                 nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
    3191                 :            :             else
    3192                 :          0 :                 nNeededPixel = nEngineWidth;
    3193                 :          0 :             nNeededPixel += nLeftM + nRightM;
    3194                 :            : 
    3195                 :            :             //  No clip marks if "###" doesn't fit (same as in DrawStrings)
    3196                 :            :         }
    3197                 :            :     }
    3198                 :            : 
    3199                 :          0 :     long nStartX = aAreaParam.maAlignRect.Left();
    3200                 :          0 :     long nStartY = aAreaParam.maAlignRect.Top();
    3201         [ #  # ]:          0 :     long nCellWidth = aAreaParam.maAlignRect.GetWidth();
    3202                 :          0 :     long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
    3203         [ #  # ]:          0 :     long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
    3204                 :            : 
    3205         [ #  # ]:          0 :     if (rParam.mbBreak)
    3206                 :            :     {
    3207                 :            :         //  text with automatic breaks is aligned only within the
    3208                 :            :         //  edit engine's paper size, the output of the whole area
    3209                 :            :         //  is always left-aligned
    3210                 :            : 
    3211                 :          0 :         nStartX += nLeftM;
    3212                 :            :     }
    3213                 :            :     else
    3214                 :            :     {
    3215         [ #  # ]:          0 :         if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
    3216                 :          0 :             nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
    3217         [ #  # ]:          0 :         else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
    3218                 :          0 :             nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
    3219                 :            :         else
    3220                 :          0 :             nStartX += nLeftM;
    3221                 :            :     }
    3222                 :            : 
    3223 [ #  # ][ #  # ]:          0 :     bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
    3224         [ #  # ]:          0 :     if (bOutside)
    3225                 :            :         return;
    3226                 :            : 
    3227         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Left() < nScrX )
    3228                 :            :     {
    3229                 :          0 :         aAreaParam.maClipRect.Left() = nScrX;
    3230                 :          0 :         aAreaParam.mbLeftClip = true;
    3231                 :            :     }
    3232         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
    3233                 :            :     {
    3234                 :          0 :         aAreaParam.maClipRect.Right() = nScrX + nScrW;          //! minus one?
    3235                 :          0 :         aAreaParam.mbRightClip = true;
    3236                 :            :     }
    3237                 :            : 
    3238 [ #  # ][ #  # ]:          0 :     bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
    3239                 :          0 :     bool bSimClip = false;
    3240                 :            : 
    3241         [ #  # ]:          0 :     if ( bWrapFields )
    3242                 :            :     {
    3243                 :            :         //  Fields in a cell with automatic breaks: clip to cell width
    3244                 :          0 :         bClip = true;
    3245                 :            :     }
    3246                 :            : 
    3247         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Top() < nScrY )
    3248                 :            :     {
    3249                 :          0 :         aAreaParam.maClipRect.Top() = nScrY;
    3250                 :          0 :         bClip = true;
    3251                 :            :     }
    3252         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
    3253                 :            :     {
    3254                 :          0 :         aAreaParam.maClipRect.Bottom() = nScrY + nScrH;     //! minus one?
    3255                 :          0 :         bClip = true;
    3256                 :            :     }
    3257                 :            : 
    3258                 :          0 :     Size aCellSize;         // output area, excluding margins, in logical units
    3259         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    3260         [ #  # ]:          0 :         aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
    3261                 :            :     else
    3262                 :          0 :         aCellSize = Size( nOutWidth, nOutHeight );
    3263                 :            : 
    3264         [ #  # ]:          0 :     if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
    3265                 :            :     {
    3266                 :            :         const ScMergeAttr* pMerge =
    3267         [ #  # ]:          0 :                 (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
    3268 [ #  # ][ #  # ]:          0 :         bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
    3269                 :            : 
    3270                 :            :         //  Don't clip for text height when printing rows with optimal height,
    3271                 :            :         //  except when font size is from conditional formatting.
    3272                 :            :         //! Allow clipping when vertically merged?
    3273 [ #  # ][ #  # ]:          0 :         if ( eType != OUTTYPE_PRINTER ||
         [ #  # ][ #  # ]
                 [ #  # ]
    3274         [ #  # ]:          0 :             ( mpDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
    3275                 :            :             ( rParam.mpCondSet && SFX_ITEM_SET ==
    3276         [ #  # ]:          0 :                 rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
    3277                 :          0 :             bClip = true;
    3278                 :            :         else
    3279                 :          0 :             bSimClip = true;
    3280                 :            : 
    3281                 :            :         //  Show clip marks if height is at least 5pt too small and
    3282                 :            :         //  there are several lines of text.
    3283                 :            :         //  Not for asian vertical text, because that would interfere
    3284                 :            :         //  with the default right position of the text.
    3285                 :            :         //  Only with automatic line breaks, to avoid having to find
    3286                 :            :         //  the cells with the horizontal end of the text again.
    3287 [ #  # ][ #  # ]:          0 :         if ( nEngineHeight - aCellSize.Height() > 100 &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3288                 :            :              rParam.mbBreak && bMarkClipped &&
    3289 [ #  # ][ #  # ]:          0 :              ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
    3290                 :            :         {
    3291                 :          0 :             CellInfo* pClipMarkCell = NULL;
    3292         [ #  # ]:          0 :             if ( bMerged )
    3293                 :            :             {
    3294                 :            :                 //  anywhere in the merged area...
    3295         [ #  # ]:          0 :                 SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
    3296         [ #  # ]:          0 :                 pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
    3297                 :            :             }
    3298                 :            :             else
    3299                 :          0 :                 pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
    3300                 :            : 
    3301                 :          0 :             pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT;      //! also allow left?
    3302                 :          0 :             bAnyClipped = true;
    3303                 :            : 
    3304                 :          0 :             long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
    3305         [ #  # ]:          0 :             if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
    3306                 :          0 :                 aAreaParam.maClipRect.Right() -= nMarkPixel;
    3307                 :            :         }
    3308                 :            :     }
    3309                 :            : 
    3310         [ #  # ]:          0 :     Rectangle aLogicClip;
    3311 [ #  # ][ #  # ]:          0 :     if (bClip || bSimClip)
    3312                 :            :     {
    3313                 :            :         // Clip marks are already handled in GetOutputArea
    3314                 :            : 
    3315         [ #  # ]:          0 :         if (rParam.mbPixelToLogic)
    3316         [ #  # ]:          0 :             aLogicClip = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
    3317                 :            :         else
    3318                 :          0 :             aLogicClip = aAreaParam.maClipRect;
    3319                 :            : 
    3320         [ #  # ]:          0 :         if (bClip)  // bei bSimClip nur aClipRect initialisieren
    3321                 :            :         {
    3322         [ #  # ]:          0 :             if (bMetaFile)
    3323                 :            :             {
    3324         [ #  # ]:          0 :                 mpDev->Push();
    3325         [ #  # ]:          0 :                 mpDev->IntersectClipRegion( aLogicClip );
    3326                 :            :             }
    3327                 :            :             else
    3328 [ #  # ][ #  # ]:          0 :                 mpDev->SetClipRegion( Region( aLogicClip ) );
                 [ #  # ]
    3329                 :            :         }
    3330                 :            :     }
    3331                 :            : 
    3332                 :          0 :     Point aLogicStart(nStartX, nStartY);
    3333         [ #  # ]:          0 :     rParam.calcStartPosForVertical(aLogicStart, aCellSize.Width(), nEngineWidth, nTopM, mpRefDevice);
    3334                 :            : 
    3335                 :          0 :     Point aURLStart = aLogicStart;      // copy before modifying for orientation
    3336                 :            : 
    3337 [ #  # ][ #  # ]:          0 :     if (rParam.meHorJust == SVX_HOR_JUSTIFY_BLOCK || rParam.mbBreak)
    3338                 :            :     {
    3339         [ #  # ]:          0 :         Size aPSize = rParam.mpEngine->GetPaperSize();
    3340                 :          0 :         aPSize.Width() = aCellSize.Height();
    3341         [ #  # ]:          0 :         rParam.mpEngine->SetPaperSize(aPSize);
    3342                 :          0 :         aLogicStart.Y() +=
    3343         [ #  # ]:          0 :             rParam.mbBreak ? aPSize.Width() : nEngineHeight;
    3344                 :            :     }
    3345                 :            :     else
    3346                 :            :     {
    3347                 :            :         // Note that the "paper" is rotated 90 degrees to the left, so
    3348                 :            :         // paper's width is in vertical direction.  Also, the whole text
    3349                 :            :         // is on a single line, as text wrap is not in effect.
    3350                 :            : 
    3351                 :            :         // Set the paper width to be the width of the text.
    3352         [ #  # ]:          0 :         Size aPSize = rParam.mpEngine->GetPaperSize();
    3353         [ #  # ]:          0 :         aPSize.Width() = rParam.mpEngine->CalcTextWidth();
    3354         [ #  # ]:          0 :         rParam.mpEngine->SetPaperSize(aPSize);
    3355                 :            : 
    3356                 :          0 :         long nGap = 0;
    3357                 :          0 :         long nTopOffset = 0;
    3358         [ #  # ]:          0 :         if (rParam.mbPixelToLogic)
    3359                 :            :         {
    3360 [ #  # ][ #  # ]:          0 :             nGap = mpRefDevice->LogicToPixel(aCellSize).Height() - mpRefDevice->LogicToPixel(aPSize).Width();
    3361         [ #  # ]:          0 :             nGap = mpRefDevice->PixelToLogic(Size(0, nGap)).Height();
    3362         [ #  # ]:          0 :             nTopOffset = mpRefDevice->PixelToLogic(Size(0,nTopM)).Height();
    3363                 :            :         }
    3364                 :            :         else
    3365                 :            :         {
    3366                 :          0 :             nGap = aCellSize.Height() - aPSize.Width();
    3367                 :          0 :             nTopOffset = nTopM;
    3368                 :            :         }
    3369                 :            : 
    3370                 :            :         // First, align text to bottom.
    3371                 :          0 :         aLogicStart.Y() += aCellSize.Height();
    3372                 :          0 :         aLogicStart.Y() += nTopOffset;
    3373                 :            : 
    3374   [ #  #  #  # ]:          0 :         switch (rParam.meVerJust)
    3375                 :            :         {
    3376                 :            :             case SVX_VER_JUSTIFY_STANDARD:
    3377                 :            :             case SVX_VER_JUSTIFY_BOTTOM:
    3378                 :            :                 // align to bottom (do nothing).
    3379                 :          0 :             break;
    3380                 :            :             case SVX_VER_JUSTIFY_CENTER:
    3381                 :            :                 // center it.
    3382                 :          0 :                 aLogicStart.Y() -= nGap / 2;
    3383                 :          0 :             break;
    3384                 :            :             case SVX_VER_JUSTIFY_BLOCK:
    3385                 :            :             case SVX_VER_JUSTIFY_TOP:
    3386                 :            :                 // align to top
    3387                 :          0 :                 aLogicStart.Y() -= nGap;
    3388                 :            :             default:
    3389                 :            :                 ;
    3390                 :            :         }
    3391                 :            :     }
    3392                 :            : 
    3393         [ #  # ]:          0 :     rParam.adjustForRTL();
    3394         [ #  # ]:          0 :     rParam.mpEngine->Draw(mpDev, aLogicStart, 900);
    3395                 :            : 
    3396         [ #  # ]:          0 :     if (bClip)
    3397                 :            :     {
    3398         [ #  # ]:          0 :         if (bMetaFile)
    3399         [ #  # ]:          0 :             mpDev->Pop();
    3400                 :            :         else
    3401         [ #  # ]:          0 :             mpDev->SetClipRegion();
    3402                 :            :     }
    3403                 :            : 
    3404         [ #  # ]:          0 :     rParam.adjustForHyperlinkInPDF(aURLStart, mpDev);
    3405                 :            : }
    3406                 :            : 
    3407                 :        193 : void ScOutputData::DrawEditTopBottom(DrawEditParam& rParam)
    3408                 :            : {
    3409                 :            :     OSL_ASSERT(rParam.meHorJust != SVX_HOR_JUSTIFY_REPEAT);
    3410         [ +  - ]:        193 :     Size aRefOne = mpRefDevice->PixelToLogic(Size(1,1));
    3411                 :            : 
    3412 [ -  + ][ #  # ]:        193 :     bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
    3413 [ +  + ][ +  - ]:        193 :     bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
         [ +  - ][ +  - ]
    3414                 :            : 
    3415                 :            :     SvxCellHorJustify eOutHorJust =
    3416                 :            :         ( rParam.meHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? rParam.meHorJust :
    3417 [ +  + ][ -  + ]:        193 :         ( rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
    3418                 :            : 
    3419 [ +  + ][ -  + ]:        193 :     if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
    3420                 :        117 :         eOutHorJust = SVX_HOR_JUSTIFY_LEFT;     // repeat is not yet implemented
    3421                 :            : 
    3422                 :            :     //! mirror margin values for RTL?
    3423                 :            :     //! move margin down to after final GetOutputArea call
    3424                 :            :     long nTopM, nLeftM, nBottomM, nRightM;
    3425         [ +  - ]:        193 :     rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, mnPPTX, mnPPTY);
    3426                 :            : 
    3427                 :        193 :     SCCOL nXForPos = rParam.mnX;
    3428         [ -  + ]:        193 :     if ( nXForPos < nX1 )
    3429                 :            :     {
    3430                 :          0 :         nXForPos = nX1;
    3431                 :          0 :         rParam.mnPosX = rParam.mnInitPosX;
    3432                 :            :     }
    3433                 :        193 :     SCSIZE nArrYForPos = rParam.mnArrY;
    3434         [ -  + ]:        193 :     if ( nArrYForPos < 1 )
    3435                 :            :     {
    3436                 :          0 :         nArrYForPos = 1;
    3437                 :          0 :         rParam.mnPosY = nScrY;
    3438                 :            :     }
    3439                 :            : 
    3440         [ +  - ]:        193 :     OutputAreaParam aAreaParam;
    3441                 :            : 
    3442                 :            :     //
    3443                 :            :     //  Initial page size - large for normal text, cell size for automatic line breaks
    3444                 :            :     //
    3445                 :            : 
    3446                 :        193 :     Size aPaperSize = Size( 1000000, 1000000 );
    3447         [ +  + ]:        193 :     if (rParam.hasLineBreak())
    3448                 :            :     {
    3449                 :            :         //  call GetOutputArea with nNeeded=0, to get only the cell width
    3450                 :            : 
    3451                 :            :         //! handle nArrY == 0
    3452                 :            :         GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
    3453                 :        154 :                        *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    3454         [ +  - ]:        154 :                        rParam.mbCellIsValue, true, false, aAreaParam );
    3455                 :            : 
    3456                 :            :         //! special ScEditUtil handling if formatting for printer
    3457         [ +  - ]:        154 :         rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, mnPPTX, mnPPTY);
    3458                 :            :     }
    3459         [ +  - ]:        193 :     if (rParam.mbPixelToLogic)
    3460                 :            :     {
    3461         [ +  - ]:        193 :         Size aLogicSize = mpRefDevice->PixelToLogic(aPaperSize);
    3462         [ +  - ]:        193 :         rParam.mpEngine->SetPaperSize(aLogicSize);
    3463                 :            :     }
    3464                 :            :     else
    3465         [ #  # ]:          0 :         rParam.mpEngine->SetPaperSize(aPaperSize);
    3466                 :            : 
    3467                 :            :     //
    3468                 :            :     //  Fill the EditEngine (cell attributes and text)
    3469                 :            :     //
    3470                 :            : 
    3471         [ +  - ]:        193 :     rParam.setPatternToEngine(mbUseStyleColor);
    3472         [ +  - ]:        193 :     rParam.setAlignmentToEngine();
    3473                 :            : 
    3474                 :            :     //  Read content from cell
    3475                 :            : 
    3476                 :        193 :     bool bWrapFields = false;
    3477 [ +  - ][ +  - ]:        193 :     if (!rParam.readCellContent(mpDoc, mbShowNullValues, mbShowFormulas, mbSyntaxMode, mbUseStyleColor, mbForceAutoColor, bWrapFields))
    3478                 :            :         // Failed to read cell content.  Bail out.
    3479                 :            :         return;
    3480                 :            : 
    3481         [ -  + ]:        193 :     if ( mbSyntaxMode )
    3482         [ #  # ]:          0 :         SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
    3483 [ +  - ][ -  + ]:        193 :     else if ( mbUseStyleColor && mbForceAutoColor )
    3484         [ #  # ]:          0 :         lcl_SetEditColor( *rParam.mpEngine, COL_AUTO );     //! or have a flag at EditEngine
    3485                 :            : 
    3486         [ +  - ]:        193 :     rParam.mpEngine->SetUpdateMode( true );     // after SetText, before CalcTextWidth/GetTextHeight
    3487                 :            : 
    3488                 :            :     //
    3489                 :            :     //  Get final output area using the calculated width
    3490                 :            :     //
    3491                 :            : 
    3492                 :            :     long nEngineWidth, nEngineHeight;
    3493         [ +  - ]:        193 :     rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
    3494                 :            : 
    3495                 :        193 :     long nNeededPixel = nEngineWidth;
    3496         [ +  - ]:        193 :     if (rParam.mbPixelToLogic)
    3497         [ +  - ]:        193 :         nNeededPixel = mpRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
    3498                 :        193 :     nNeededPixel += nLeftM + nRightM;
    3499                 :            : 
    3500 [ +  + ][ -  + ]:        193 :     if (!rParam.mbBreak || bShrink)
    3501                 :            :     {
    3502                 :            :         // for break, the first GetOutputArea call is sufficient
    3503                 :            :         GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
    3504                 :         39 :                        *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    3505 [ +  + ][ +  - ]:         78 :                        rParam.mbCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
         [ +  - ][ +  - ]
    3506                 :            : 
    3507         [ +  - ]:         39 :         if ( bShrink )
    3508                 :            :         {
    3509                 :            :             ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
    3510                 :            :                 nLeftM, nTopM, nRightM, nBottomM, false,
    3511                 :         39 :                 sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
    3512                 :            :                 nEngineWidth, nEngineHeight, nNeededPixel,
    3513         [ +  - ]:         39 :                 aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
    3514                 :            :         }
    3515 [ -  + ][ #  # ]:         39 :         if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
    3516                 :            :         {
    3517                 :            :             // First check if twice the space for the formatted text is available
    3518                 :            :             // (otherwise just keep it unchanged).
    3519                 :            : 
    3520                 :          0 :             long nFormatted = nNeededPixel - nLeftM - nRightM;      // without margin
    3521         [ #  # ]:          0 :             long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
    3522         [ #  # ]:          0 :             if ( nAvailable >= 2 * nFormatted )
    3523                 :            :             {
    3524                 :            :                 // "repeat" is handled with unformatted text (for performance reasons)
    3525         [ #  # ]:          0 :                 String aCellStr = rParam.mpEngine->GetText();
    3526         [ #  # ]:          0 :                 rParam.mpEngine->SetText( aCellStr );
    3527                 :            : 
    3528         [ #  # ]:          0 :                 long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
    3529         [ #  # ]:          0 :                 if (rParam.mbPixelToLogic)
    3530         [ #  # ]:          0 :                     nRepeatSize = mpRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
    3531         [ #  # ]:          0 :                 if ( pFmtDevice != mpRefDevice )
    3532                 :          0 :                     ++nRepeatSize;
    3533         [ #  # ]:          0 :                 if ( nRepeatSize > 0 )
    3534                 :            :                 {
    3535                 :          0 :                     long nRepeatCount = nAvailable / nRepeatSize;
    3536         [ #  # ]:          0 :                     if ( nRepeatCount > 1 )
    3537                 :            :                     {
    3538         [ #  # ]:          0 :                         String aRepeated = aCellStr;
    3539         [ #  # ]:          0 :                         for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
    3540         [ #  # ]:          0 :                             aRepeated.Append( aCellStr );
    3541         [ #  # ]:          0 :                         rParam.mpEngine->SetText( aRepeated );
    3542                 :            : 
    3543         [ #  # ]:          0 :                         nEngineHeight = rParam.mpEngine->GetTextHeight();
    3544         [ #  # ]:          0 :                         nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
    3545         [ #  # ]:          0 :                         if (rParam.mbPixelToLogic)
    3546         [ #  # ]:          0 :                             nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
    3547                 :            :                         else
    3548                 :          0 :                             nNeededPixel = nEngineWidth;
    3549         [ #  # ]:          0 :                         nNeededPixel += nLeftM + nRightM;
    3550                 :            :                     }
    3551         [ #  # ]:          0 :                 }
    3552                 :            :             }
    3553                 :            :         }
    3554                 :            : 
    3555 [ +  + ][ -  + ]:         39 :         if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
                 [ #  # ]
    3556                 :            :         {
    3557 [ +  - ][ +  - ]:         24 :             rParam.mpEngine->SetText(rtl::OUString("###"));
                 [ +  - ]
    3558         [ +  - ]:         24 :             nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
    3559         [ +  - ]:         24 :             if (rParam.mbPixelToLogic)
    3560         [ +  - ]:         24 :                 nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
    3561                 :            :             else
    3562                 :          0 :                 nNeededPixel = nEngineWidth;
    3563                 :         24 :             nNeededPixel += nLeftM + nRightM;
    3564                 :            : 
    3565                 :            :             //  No clip marks if "###" doesn't fit (same as in DrawStrings)
    3566                 :            :         }
    3567                 :            :     }
    3568                 :            : 
    3569                 :        193 :     long nStartX = aAreaParam.maAlignRect.Left();
    3570                 :        193 :     long nStartY = aAreaParam.maAlignRect.Top();
    3571         [ +  - ]:        193 :     long nCellWidth = aAreaParam.maAlignRect.GetWidth();
    3572                 :        193 :     long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
    3573         [ +  - ]:        193 :     long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
    3574                 :            : 
    3575         [ +  + ]:        193 :     if (rParam.mbBreak)
    3576                 :            :     {
    3577                 :            :         //  text with automatic breaks is aligned only within the
    3578                 :            :         //  edit engine's paper size, the output of the whole area
    3579                 :            :         //  is always left-aligned
    3580                 :            : 
    3581                 :        154 :         nStartX += nLeftM;
    3582         [ +  + ]:        154 :         if (rParam.meHorJust == SVX_HOR_JUSTIFY_BLOCK)
    3583                 :        117 :             nStartX += aPaperSize.Height();
    3584                 :            :     }
    3585                 :            :     else
    3586                 :            :     {
    3587         [ -  + ]:         39 :         if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
    3588                 :          0 :             nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
    3589         [ +  - ]:         39 :         else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
    3590                 :         39 :             nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
    3591                 :            :         else
    3592                 :          0 :             nStartX += nLeftM;
    3593                 :            :     }
    3594                 :            : 
    3595 [ +  - ][ -  + ]:        193 :     bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
    3596         [ +  - ]:        193 :     if (bOutside)
    3597                 :            :         return;
    3598                 :            : 
    3599         [ -  + ]:        193 :     if ( aAreaParam.maClipRect.Left() < nScrX )
    3600                 :            :     {
    3601                 :          0 :         aAreaParam.maClipRect.Left() = nScrX;
    3602                 :          0 :         aAreaParam.mbLeftClip = true;
    3603                 :            :     }
    3604         [ -  + ]:        193 :     if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
    3605                 :            :     {
    3606                 :          0 :         aAreaParam.maClipRect.Right() = nScrX + nScrW;          //! minus one?
    3607                 :          0 :         aAreaParam.mbRightClip = true;
    3608                 :            :     }
    3609                 :            : 
    3610 [ +  + ][ -  + ]:        193 :     bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
    3611                 :        193 :     bool bSimClip = false;
    3612                 :            : 
    3613         [ -  + ]:        193 :     if ( bWrapFields )
    3614                 :            :     {
    3615                 :            :         //  Fields in a cell with automatic breaks: clip to cell width
    3616                 :          0 :         bClip = true;
    3617                 :            :     }
    3618                 :            : 
    3619         [ -  + ]:        193 :     if ( aAreaParam.maClipRect.Top() < nScrY )
    3620                 :            :     {
    3621                 :          0 :         aAreaParam.maClipRect.Top() = nScrY;
    3622                 :          0 :         bClip = true;
    3623                 :            :     }
    3624         [ -  + ]:        193 :     if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
    3625                 :            :     {
    3626                 :          0 :         aAreaParam.maClipRect.Bottom() = nScrY + nScrH;     //! minus one?
    3627                 :          0 :         bClip = true;
    3628                 :            :     }
    3629                 :            : 
    3630                 :        193 :     Size aCellSize;         // output area, excluding margins, in logical units
    3631         [ +  - ]:        193 :     if (rParam.mbPixelToLogic)
    3632         [ +  - ]:        193 :         aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
    3633                 :            :     else
    3634                 :          0 :         aCellSize = Size( nOutWidth, nOutHeight );
    3635                 :            : 
    3636         [ +  + ]:        193 :     if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
    3637                 :            :     {
    3638                 :            :         const ScMergeAttr* pMerge =
    3639         [ +  - ]:         18 :                 (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
    3640 [ +  - ][ -  + ]:         18 :         bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
    3641                 :            : 
    3642                 :            :         //  Don't clip for text height when printing rows with optimal height,
    3643                 :            :         //  except when font size is from conditional formatting.
    3644                 :            :         //! Allow clipping when vertically merged?
    3645 [ -  + ][ #  # ]:         18 :         if ( eType != OUTTYPE_PRINTER ||
         [ #  # ][ #  # ]
                 [ +  - ]
    3646         [ #  # ]:          0 :             ( mpDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
    3647                 :            :             ( rParam.mpCondSet && SFX_ITEM_SET ==
    3648         [ #  # ]:          0 :                 rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
    3649                 :         18 :             bClip = true;
    3650                 :            :         else
    3651                 :          0 :             bSimClip = true;
    3652                 :            : 
    3653                 :            :         //  Show clip marks if height is at least 5pt too small and
    3654                 :            :         //  there are several lines of text.
    3655                 :            :         //  Not for asian vertical text, because that would interfere
    3656                 :            :         //  with the default right position of the text.
    3657                 :            :         //  Only with automatic line breaks, to avoid having to find
    3658                 :            :         //  the cells with the horizontal end of the text again.
    3659 [ -  + ][ #  # ]:         18 :         if ( nEngineHeight - aCellSize.Height() > 100 &&
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
    3660                 :            :              rParam.mbBreak && bMarkClipped &&
    3661 [ #  # ][ #  # ]:          0 :              ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
    3662                 :            :         {
    3663                 :          0 :             CellInfo* pClipMarkCell = NULL;
    3664         [ #  # ]:          0 :             if ( bMerged )
    3665                 :            :             {
    3666                 :            :                 //  anywhere in the merged area...
    3667         [ #  # ]:          0 :                 SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
    3668         [ #  # ]:          0 :                 pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
    3669                 :            :             }
    3670                 :            :             else
    3671                 :          0 :                 pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
    3672                 :            : 
    3673                 :          0 :             pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT;      //! also allow left?
    3674                 :          0 :             bAnyClipped = true;
    3675                 :            : 
    3676                 :          0 :             long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
    3677         [ #  # ]:          0 :             if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
    3678                 :          0 :                 aAreaParam.maClipRect.Right() -= nMarkPixel;
    3679                 :            :         }
    3680                 :            :     }
    3681                 :            : 
    3682         [ +  - ]:        193 :     Rectangle aLogicClip;
    3683 [ +  + ][ -  + ]:        193 :     if (bClip || bSimClip)
    3684                 :            :     {
    3685                 :            :         // Clip marks are already handled in GetOutputArea
    3686                 :            : 
    3687         [ +  - ]:         39 :         if (rParam.mbPixelToLogic)
    3688         [ +  - ]:         39 :             aLogicClip = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
    3689                 :            :         else
    3690                 :          0 :             aLogicClip = aAreaParam.maClipRect;
    3691                 :            : 
    3692         [ +  - ]:         39 :         if (bClip)  // bei bSimClip nur aClipRect initialisieren
    3693                 :            :         {
    3694         [ -  + ]:         39 :             if (bMetaFile)
    3695                 :            :             {
    3696         [ #  # ]:          0 :                 mpDev->Push();
    3697         [ #  # ]:          0 :                 mpDev->IntersectClipRegion( aLogicClip );
    3698                 :            :             }
    3699                 :            :             else
    3700 [ +  - ][ +  - ]:         39 :                 mpDev->SetClipRegion( Region( aLogicClip ) );
                 [ +  - ]
    3701                 :            :         }
    3702                 :            :     }
    3703                 :            : 
    3704                 :        193 :     Point aLogicStart(nStartX, nStartY);
    3705         [ +  - ]:        193 :     rParam.calcStartPosForVertical(aLogicStart, aCellSize.Width(), nEngineWidth, nTopM, mpRefDevice);
    3706                 :            : 
    3707                 :        193 :     Point aURLStart = aLogicStart;      // copy before modifying for orientation
    3708                 :            : 
    3709         [ +  + ]:        193 :     if (rParam.meHorJust != SVX_HOR_JUSTIFY_BLOCK)
    3710                 :            :     {
    3711                 :         76 :         aLogicStart.X() += nEngineWidth;
    3712         [ +  + ]:         76 :         if (!rParam.mbBreak)
    3713                 :            :         {
    3714                 :            :             // Set the paper width to text size.
    3715         [ +  - ]:         39 :             Size aPSize = rParam.mpEngine->GetPaperSize();
    3716         [ +  - ]:         39 :             aPSize.Width() = rParam.mpEngine->CalcTextWidth();
    3717         [ +  - ]:         39 :             rParam.mpEngine->SetPaperSize(aPSize);
    3718                 :            : 
    3719                 :         39 :             long nGap = 0;
    3720                 :         39 :             long nTopOffset = 0; // offset by top margin
    3721         [ +  - ]:         39 :             if (rParam.mbPixelToLogic)
    3722                 :            :             {
    3723 [ +  - ][ +  - ]:         39 :                 nGap = mpRefDevice->LogicToPixel(aPSize).Width() - mpRefDevice->LogicToPixel(aCellSize).Height();
    3724         [ +  - ]:         39 :                 nGap = mpRefDevice->PixelToLogic(Size(0, nGap)).Height();
    3725         [ +  - ]:         39 :                 nTopOffset = mpRefDevice->PixelToLogic(Size(0,nTopM)).Height();
    3726                 :            :             }
    3727                 :            :             else
    3728                 :            :             {
    3729                 :          0 :                 nGap = aPSize.Width() - aCellSize.Height();
    3730                 :          0 :                 nTopOffset = nTopM;
    3731                 :            :             }
    3732                 :         39 :             aLogicStart.Y() += nTopOffset;
    3733                 :            : 
    3734      [ +  -  - ]:         39 :             switch (rParam.meVerJust)
    3735                 :            :             {
    3736                 :            :                 case SVX_VER_JUSTIFY_STANDARD:
    3737                 :            :                 case SVX_VER_JUSTIFY_BOTTOM:
    3738                 :            :                     // align to bottom
    3739                 :         39 :                     aLogicStart.Y() -= nGap;
    3740                 :         39 :                 break;
    3741                 :            :                 case SVX_VER_JUSTIFY_CENTER:
    3742                 :            :                     // center it.
    3743                 :          0 :                     aLogicStart.Y() -= nGap / 2;
    3744                 :         39 :                 break;
    3745                 :            :                 case SVX_VER_JUSTIFY_BLOCK:
    3746                 :            :                 case SVX_VER_JUSTIFY_TOP:
    3747                 :            :                     // align to top (do nothing)
    3748                 :            :                 default:
    3749                 :            :                     ;
    3750                 :            :             }
    3751                 :            :         }
    3752                 :            :     }
    3753                 :            : 
    3754         [ +  - ]:        193 :     rParam.adjustForRTL();
    3755                 :            : 
    3756                 :            :     // bMoveClipped handling has been replaced by complete alignment
    3757                 :            :     // handling (also extending to the left).
    3758                 :            : 
    3759         [ +  - ]:        193 :     rParam.mpEngine->Draw(mpDev, aLogicStart, 2700);
    3760                 :            : 
    3761         [ +  + ]:        193 :     if (bClip)
    3762                 :            :     {
    3763         [ -  + ]:         39 :         if (bMetaFile)
    3764         [ #  # ]:          0 :             mpDev->Pop();
    3765                 :            :         else
    3766         [ +  - ]:         39 :             mpDev->SetClipRegion();
    3767                 :            :     }
    3768                 :            : 
    3769         [ +  - ]:        193 :     rParam.adjustForHyperlinkInPDF(aURLStart, mpDev);
    3770                 :            : }
    3771                 :            : 
    3772                 :          0 : void ScOutputData::DrawEditStacked(DrawEditParam& rParam)
    3773                 :            : {
    3774                 :            :     OSL_ASSERT(rParam.meHorJust != SVX_HOR_JUSTIFY_REPEAT);
    3775         [ #  # ]:          0 :     Size aRefOne = mpRefDevice->PixelToLogic(Size(1,1));
    3776                 :            : 
    3777 [ #  # ][ #  # ]:          0 :     bool bRepeat = (rParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT && !rParam.mbBreak);
    3778 [ #  # ][ #  # ]:          0 :     bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
         [ #  # ][ #  # ]
    3779                 :            : 
    3780                 :            :     rParam.mbAsianVertical =
    3781         [ #  # ]:          0 :         lcl_GetBoolValue(*rParam.mpPattern, ATTR_VERTICAL_ASIAN, rParam.mpCondSet);
    3782                 :            : 
    3783         [ #  # ]:          0 :     if ( rParam.mbAsianVertical )
    3784                 :            :     {
    3785                 :            :         // in asian mode, use EditEngine::SetVertical instead of EE_CNTRL_ONECHARPERLINE
    3786                 :          0 :         rParam.meOrient = SVX_ORIENTATION_STANDARD;
    3787         [ #  # ]:          0 :         DrawEditAsianVertical(rParam);
    3788                 :            :         return;
    3789                 :            :     }
    3790                 :            : 
    3791                 :            :     SvxCellHorJustify eOutHorJust =
    3792                 :            :         ( rParam.meHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? rParam.meHorJust :
    3793 [ #  # ][ #  # ]:          0 :         ( rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
    3794                 :            : 
    3795 [ #  # ][ #  # ]:          0 :     if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
    3796                 :          0 :         eOutHorJust = SVX_HOR_JUSTIFY_LEFT;     // repeat is not yet implemented
    3797                 :            : 
    3798                 :            :     //! mirror margin values for RTL?
    3799                 :            :     //! move margin down to after final GetOutputArea call
    3800                 :            :     long nTopM, nLeftM, nBottomM, nRightM;
    3801         [ #  # ]:          0 :     rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, mnPPTX, mnPPTY);
    3802                 :            : 
    3803                 :          0 :     SCCOL nXForPos = rParam.mnX;
    3804         [ #  # ]:          0 :     if ( nXForPos < nX1 )
    3805                 :            :     {
    3806                 :          0 :         nXForPos = nX1;
    3807                 :          0 :         rParam.mnPosX = rParam.mnInitPosX;
    3808                 :            :     }
    3809                 :          0 :     SCSIZE nArrYForPos = rParam.mnArrY;
    3810         [ #  # ]:          0 :     if ( nArrYForPos < 1 )
    3811                 :            :     {
    3812                 :          0 :         nArrYForPos = 1;
    3813                 :          0 :         rParam.mnPosY = nScrY;
    3814                 :            :     }
    3815                 :            : 
    3816         [ #  # ]:          0 :     OutputAreaParam aAreaParam;
    3817                 :            : 
    3818                 :            :     //
    3819                 :            :     //  Initial page size - large for normal text, cell size for automatic line breaks
    3820                 :            :     //
    3821                 :            : 
    3822                 :          0 :     Size aPaperSize = Size( 1000000, 1000000 );
    3823                 :            :     //  call GetOutputArea with nNeeded=0, to get only the cell width
    3824                 :            : 
    3825                 :            :     //! handle nArrY == 0
    3826                 :            :     GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
    3827                 :          0 :                    *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    3828         [ #  # ]:          0 :                    rParam.mbCellIsValue, true, false, aAreaParam );
    3829                 :            : 
    3830                 :            :     //! special ScEditUtil handling if formatting for printer
    3831         [ #  # ]:          0 :     rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, mnPPTX, mnPPTY);
    3832                 :            : 
    3833         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    3834                 :            :     {
    3835         [ #  # ]:          0 :         Size aLogicSize = mpRefDevice->PixelToLogic(aPaperSize);
    3836 [ #  # ][ #  # ]:          0 :         if ( rParam.mbBreak && mpRefDevice != pFmtDevice )
    3837                 :            :         {
    3838                 :            :             // #i85342# screen display and formatting for printer,
    3839                 :            :             // use same GetEditArea call as in ScViewData::SetEditEngine
    3840                 :            : 
    3841         [ #  # ]:          0 :             Fraction aFract(1,1);
    3842                 :            :             Rectangle aUtilRect = ScEditUtil( mpDoc, rParam.mnCellX, rParam.mnCellY, nTab, Point(0,0), pFmtDevice,
    3843 [ #  # ][ #  # ]:          0 :                 HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( rParam.mpPattern, false );
    3844         [ #  # ]:          0 :             aLogicSize.Width() = aUtilRect.GetWidth();
    3845                 :            :         }
    3846         [ #  # ]:          0 :         rParam.mpEngine->SetPaperSize(aLogicSize);
    3847                 :            :     }
    3848                 :            :     else
    3849         [ #  # ]:          0 :         rParam.mpEngine->SetPaperSize(aPaperSize);
    3850                 :            : 
    3851                 :            :     //
    3852                 :            :     //  Fill the EditEngine (cell attributes and text)
    3853                 :            :     //
    3854                 :            : 
    3855         [ #  # ]:          0 :     rParam.setPatternToEngine(mbUseStyleColor);
    3856         [ #  # ]:          0 :     rParam.setAlignmentToEngine();
    3857                 :            : 
    3858                 :            :     //  Read content from cell
    3859                 :            : 
    3860                 :          0 :     bool bWrapFields = false;
    3861 [ #  # ][ #  # ]:          0 :     if (!rParam.readCellContent(mpDoc, mbShowNullValues, mbShowFormulas, mbSyntaxMode, mbUseStyleColor, mbForceAutoColor, bWrapFields))
    3862                 :            :         // Failed to read cell content.  Bail out.
    3863                 :            :         return;
    3864                 :            : 
    3865         [ #  # ]:          0 :     if ( mbSyntaxMode )
    3866         [ #  # ]:          0 :         SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
    3867 [ #  # ][ #  # ]:          0 :     else if ( mbUseStyleColor && mbForceAutoColor )
    3868         [ #  # ]:          0 :         lcl_SetEditColor( *rParam.mpEngine, COL_AUTO );     //! or have a flag at EditEngine
    3869                 :            : 
    3870         [ #  # ]:          0 :     rParam.mpEngine->SetUpdateMode( true );     // after SetText, before CalcTextWidth/GetTextHeight
    3871                 :            : 
    3872                 :            :     //
    3873                 :            :     //  Get final output area using the calculated width
    3874                 :            :     //
    3875                 :            : 
    3876                 :            :     long nEngineWidth, nEngineHeight;
    3877         [ #  # ]:          0 :     rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
    3878                 :            : 
    3879                 :          0 :     long nNeededPixel = nEngineWidth;
    3880         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    3881         [ #  # ]:          0 :         nNeededPixel = mpRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
    3882                 :          0 :     nNeededPixel += nLeftM + nRightM;
    3883                 :            : 
    3884         [ #  # ]:          0 :     if (bShrink)
    3885                 :            :     {
    3886                 :            :         // for break, the first GetOutputArea call is sufficient
    3887                 :            :         GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
    3888                 :          0 :                        *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    3889         [ #  # ]:          0 :                        true, false, false, aAreaParam );
    3890                 :            : 
    3891                 :            :         ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
    3892                 :            :             nLeftM, nTopM, nRightM, nBottomM, true,
    3893                 :          0 :             sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
    3894                 :            :             nEngineWidth, nEngineHeight, nNeededPixel,
    3895         [ #  # ]:          0 :             aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
    3896                 :            : 
    3897 [ #  # ][ #  # ]:          0 :         if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    3898                 :            :         {
    3899                 :            :             // First check if twice the space for the formatted text is available
    3900                 :            :             // (otherwise just keep it unchanged).
    3901                 :            : 
    3902                 :          0 :             long nFormatted = nNeededPixel - nLeftM - nRightM;      // without margin
    3903         [ #  # ]:          0 :             long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
    3904         [ #  # ]:          0 :             if ( nAvailable >= 2 * nFormatted )
    3905                 :            :             {
    3906                 :            :                 // "repeat" is handled with unformatted text (for performance reasons)
    3907         [ #  # ]:          0 :                 String aCellStr = rParam.mpEngine->GetText();
    3908         [ #  # ]:          0 :                 rParam.mpEngine->SetText( aCellStr );
    3909                 :            : 
    3910         [ #  # ]:          0 :                 long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
    3911         [ #  # ]:          0 :                 if (rParam.mbPixelToLogic)
    3912         [ #  # ]:          0 :                     nRepeatSize = mpRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
    3913         [ #  # ]:          0 :                 if ( pFmtDevice != mpRefDevice )
    3914                 :          0 :                     ++nRepeatSize;
    3915         [ #  # ]:          0 :                 if ( nRepeatSize > 0 )
    3916                 :            :                 {
    3917                 :          0 :                     long nRepeatCount = nAvailable / nRepeatSize;
    3918         [ #  # ]:          0 :                     if ( nRepeatCount > 1 )
    3919                 :            :                     {
    3920         [ #  # ]:          0 :                         String aRepeated = aCellStr;
    3921         [ #  # ]:          0 :                         for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
    3922         [ #  # ]:          0 :                             aRepeated.Append( aCellStr );
    3923         [ #  # ]:          0 :                         rParam.mpEngine->SetText( aRepeated );
    3924                 :            : 
    3925         [ #  # ]:          0 :                         nEngineHeight = rParam.mpEngine->GetTextHeight();
    3926         [ #  # ]:          0 :                         nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
    3927         [ #  # ]:          0 :                         if (rParam.mbPixelToLogic)
    3928         [ #  # ]:          0 :                             nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
    3929                 :            :                         else
    3930                 :          0 :                             nNeededPixel = nEngineWidth;
    3931         [ #  # ]:          0 :                         nNeededPixel += nLeftM + nRightM;
    3932                 :            :                     }
    3933         [ #  # ]:          0 :                 }
    3934                 :            :             }
    3935                 :            :         }
    3936                 :            : 
    3937 [ #  # ][ #  # ]:          0 :         if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
                 [ #  # ]
    3938                 :            :         {
    3939 [ #  # ][ #  # ]:          0 :             rParam.mpEngine->SetText(rtl::OUString("###"));
                 [ #  # ]
    3940         [ #  # ]:          0 :             nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
    3941         [ #  # ]:          0 :             if (rParam.mbPixelToLogic)
    3942         [ #  # ]:          0 :                 nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
    3943                 :            :             else
    3944                 :          0 :                 nNeededPixel = nEngineWidth;
    3945                 :          0 :             nNeededPixel += nLeftM + nRightM;
    3946                 :            : 
    3947                 :            :             //  No clip marks if "###" doesn't fit (same as in DrawStrings)
    3948                 :            :         }
    3949                 :            : 
    3950         [ #  # ]:          0 :         if ( eOutHorJust != SVX_HOR_JUSTIFY_LEFT )
    3951                 :            :         {
    3952                 :          0 :             aPaperSize.Width() = nNeededPixel + 1;
    3953         [ #  # ]:          0 :             if (rParam.mbPixelToLogic)
    3954 [ #  # ][ #  # ]:          0 :                 rParam.mpEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
    3955                 :            :             else
    3956         [ #  # ]:          0 :                 rParam.mpEngine->SetPaperSize(aPaperSize);
    3957                 :            :         }
    3958                 :            :     }
    3959                 :            : 
    3960                 :          0 :     long nStartX = aAreaParam.maAlignRect.Left();
    3961                 :          0 :     long nStartY = aAreaParam.maAlignRect.Top();
    3962         [ #  # ]:          0 :     long nCellWidth = aAreaParam.maAlignRect.GetWidth();
    3963                 :          0 :     long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
    3964         [ #  # ]:          0 :     long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
    3965                 :            : 
    3966         [ #  # ]:          0 :     if (rParam.mbBreak)
    3967                 :            :     {
    3968                 :            :         //  text with automatic breaks is aligned only within the
    3969                 :            :         //  edit engine's paper size, the output of the whole area
    3970                 :            :         //  is always left-aligned
    3971                 :            : 
    3972                 :          0 :         nStartX += nLeftM;
    3973                 :            :     }
    3974                 :            :     else
    3975                 :            :     {
    3976         [ #  # ]:          0 :         if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
    3977                 :          0 :             nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
    3978         [ #  # ]:          0 :         else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
    3979                 :          0 :             nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
    3980                 :            :         else
    3981                 :          0 :             nStartX += nLeftM;
    3982                 :            :     }
    3983                 :            : 
    3984 [ #  # ][ #  # ]:          0 :     bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
    3985         [ #  # ]:          0 :     if (bOutside)
    3986                 :            :         return;
    3987                 :            : 
    3988         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Left() < nScrX )
    3989                 :            :     {
    3990                 :          0 :         aAreaParam.maClipRect.Left() = nScrX;
    3991                 :          0 :         aAreaParam.mbLeftClip = true;
    3992                 :            :     }
    3993         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
    3994                 :            :     {
    3995                 :          0 :         aAreaParam.maClipRect.Right() = nScrX + nScrW;          //! minus one?
    3996                 :          0 :         aAreaParam.mbRightClip = true;
    3997                 :            :     }
    3998                 :            : 
    3999 [ #  # ][ #  # ]:          0 :     bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
    4000                 :          0 :     bool bSimClip = false;
    4001                 :            : 
    4002         [ #  # ]:          0 :     if ( bWrapFields )
    4003                 :            :     {
    4004                 :            :         //  Fields in a cell with automatic breaks: clip to cell width
    4005                 :          0 :         bClip = true;
    4006                 :            :     }
    4007                 :            : 
    4008         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Top() < nScrY )
    4009                 :            :     {
    4010                 :          0 :         aAreaParam.maClipRect.Top() = nScrY;
    4011                 :          0 :         bClip = true;
    4012                 :            :     }
    4013         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
    4014                 :            :     {
    4015                 :          0 :         aAreaParam.maClipRect.Bottom() = nScrY + nScrH;     //! minus one?
    4016                 :          0 :         bClip = true;
    4017                 :            :     }
    4018                 :            : 
    4019                 :          0 :     Size aCellSize;         // output area, excluding margins, in logical units
    4020         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    4021         [ #  # ]:          0 :         aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
    4022                 :            :     else
    4023                 :          0 :         aCellSize = Size( nOutWidth, nOutHeight );
    4024                 :            : 
    4025         [ #  # ]:          0 :     if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
    4026                 :            :     {
    4027                 :            :         const ScMergeAttr* pMerge =
    4028         [ #  # ]:          0 :                 (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
    4029 [ #  # ][ #  # ]:          0 :         bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
    4030                 :            : 
    4031                 :            :         //  Don't clip for text height when printing rows with optimal height,
    4032                 :            :         //  except when font size is from conditional formatting.
    4033                 :            :         //! Allow clipping when vertically merged?
    4034 [ #  # ][ #  # ]:          0 :         if ( eType != OUTTYPE_PRINTER ||
         [ #  # ][ #  # ]
                 [ #  # ]
    4035         [ #  # ]:          0 :             ( mpDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
    4036                 :            :             ( rParam.mpCondSet && SFX_ITEM_SET ==
    4037         [ #  # ]:          0 :                 rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
    4038                 :          0 :             bClip = true;
    4039                 :            :         else
    4040                 :          0 :             bSimClip = true;
    4041                 :            : 
    4042                 :            :         //  Show clip marks if height is at least 5pt too small and
    4043                 :            :         //  there are several lines of text.
    4044                 :            :         //  Not for asian vertical text, because that would interfere
    4045                 :            :         //  with the default right position of the text.
    4046                 :            :         //  Only with automatic line breaks, to avoid having to find
    4047                 :            :         //  the cells with the horizontal end of the text again.
    4048 [ #  # ][ #  # ]:          0 :         if ( nEngineHeight - aCellSize.Height() > 100 &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    4049                 :            :              rParam.mbBreak && bMarkClipped &&
    4050 [ #  # ][ #  # ]:          0 :              ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
    4051                 :            :         {
    4052                 :          0 :             CellInfo* pClipMarkCell = NULL;
    4053         [ #  # ]:          0 :             if ( bMerged )
    4054                 :            :             {
    4055                 :            :                 //  anywhere in the merged area...
    4056         [ #  # ]:          0 :                 SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
    4057         [ #  # ]:          0 :                 pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
    4058                 :            :             }
    4059                 :            :             else
    4060                 :          0 :                 pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
    4061                 :            : 
    4062                 :          0 :             pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT;      //! also allow left?
    4063                 :          0 :             bAnyClipped = true;
    4064                 :            : 
    4065                 :          0 :             long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
    4066         [ #  # ]:          0 :             if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
    4067                 :          0 :                 aAreaParam.maClipRect.Right() -= nMarkPixel;
    4068                 :            :         }
    4069                 :            :     }
    4070                 :            : 
    4071         [ #  # ]:          0 :     Rectangle aLogicClip;
    4072 [ #  # ][ #  # ]:          0 :     if (bClip || bSimClip)
    4073                 :            :     {
    4074                 :            :         // Clip marks are already handled in GetOutputArea
    4075                 :            : 
    4076         [ #  # ]:          0 :         if (rParam.mbPixelToLogic)
    4077         [ #  # ]:          0 :             aLogicClip = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
    4078                 :            :         else
    4079                 :          0 :             aLogicClip = aAreaParam.maClipRect;
    4080                 :            : 
    4081         [ #  # ]:          0 :         if (bClip)  // bei bSimClip nur aClipRect initialisieren
    4082                 :            :         {
    4083         [ #  # ]:          0 :             if (bMetaFile)
    4084                 :            :             {
    4085         [ #  # ]:          0 :                 mpDev->Push();
    4086         [ #  # ]:          0 :                 mpDev->IntersectClipRegion( aLogicClip );
    4087                 :            :             }
    4088                 :            :             else
    4089 [ #  # ][ #  # ]:          0 :                 mpDev->SetClipRegion( Region( aLogicClip ) );
                 [ #  # ]
    4090                 :            :         }
    4091                 :            :     }
    4092                 :            : 
    4093                 :          0 :     Point aLogicStart;
    4094         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    4095         [ #  # ]:          0 :         aLogicStart = mpRefDevice->PixelToLogic( Point(nStartX,nStartY) );
    4096                 :            :     else
    4097                 :          0 :         aLogicStart = Point(nStartX, nStartY);
    4098                 :            : 
    4099 [ #  # ][ #  # ]:          0 :     if (rParam.meVerJust==SVX_VER_JUSTIFY_BOTTOM ||
    4100                 :            :         rParam.meVerJust==SVX_VER_JUSTIFY_STANDARD)
    4101                 :            :     {
    4102                 :            :         //! if pRefDevice != pFmtDevice, keep heights in logic units,
    4103                 :            :         //! only converting margin?
    4104                 :            : 
    4105         [ #  # ]:          0 :         if (rParam.mbPixelToLogic)
    4106                 :          0 :             aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0, nTopM +
    4107         [ #  # ]:          0 :                             mpRefDevice->LogicToPixel(aCellSize).Height() -
    4108         [ #  # ]:          0 :                             mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
    4109         [ #  # ]:          0 :                             )).Height();
    4110                 :            :         else
    4111                 :          0 :             aLogicStart.Y() += nTopM + aCellSize.Height() - nEngineHeight;
    4112                 :            :     }
    4113         [ #  # ]:          0 :     else if (rParam.meVerJust==SVX_VER_JUSTIFY_CENTER)
    4114                 :            :     {
    4115         [ #  # ]:          0 :         if (rParam.mbPixelToLogic)
    4116                 :          0 :             aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0, nTopM + (
    4117         [ #  # ]:          0 :                             mpRefDevice->LogicToPixel(aCellSize).Height() -
    4118         [ #  # ]:          0 :                             mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height() )
    4119         [ #  # ]:          0 :                             / 2)).Height();
    4120                 :            :         else
    4121                 :          0 :             aLogicStart.Y() += nTopM + (aCellSize.Height() - nEngineHeight) / 2;
    4122                 :            :     }
    4123                 :            :     else        // top
    4124                 :            :     {
    4125         [ #  # ]:          0 :         if (rParam.mbPixelToLogic)
    4126         [ #  # ]:          0 :             aLogicStart.Y() += mpRefDevice->PixelToLogic(Size(0,nTopM)).Height();
    4127                 :            :         else
    4128                 :          0 :             aLogicStart.Y() += nTopM;
    4129                 :            :     }
    4130                 :            : 
    4131                 :          0 :     Point aURLStart = aLogicStart;      // copy before modifying for orientation
    4132                 :            : 
    4133         [ #  # ]:          0 :     Size aPaperLogic = rParam.mpEngine->GetPaperSize();
    4134                 :          0 :     aPaperLogic.Width() = nEngineWidth;
    4135         [ #  # ]:          0 :     rParam.mpEngine->SetPaperSize(aPaperLogic);
    4136                 :            : 
    4137         [ #  # ]:          0 :     rParam.adjustForRTL();
    4138                 :            : 
    4139                 :            :     // bMoveClipped handling has been replaced by complete alignment
    4140                 :            :     // handling (also extending to the left).
    4141                 :            : 
    4142         [ #  # ]:          0 :     if (bSimClip)
    4143                 :            :     {
    4144                 :            :         //  kein hartes Clipping, aber nur die betroffenen
    4145                 :            :         //  Zeilen ausgeben
    4146                 :            : 
    4147                 :          0 :         Point aDocStart = aLogicClip.TopLeft();
    4148                 :          0 :         aDocStart -= aLogicStart;
    4149         [ #  # ]:          0 :         rParam.mpEngine->Draw( mpDev, aLogicClip, aDocStart, false );
    4150                 :            :     }
    4151                 :            :     else
    4152                 :            :     {
    4153         [ #  # ]:          0 :         rParam.mpEngine->Draw( mpDev, aLogicStart, 0 );
    4154                 :            :     }
    4155                 :            : 
    4156         [ #  # ]:          0 :     if (bClip)
    4157                 :            :     {
    4158         [ #  # ]:          0 :         if (bMetaFile)
    4159         [ #  # ]:          0 :             mpDev->Pop();
    4160                 :            :         else
    4161         [ #  # ]:          0 :             mpDev->SetClipRegion();
    4162                 :            :     }
    4163                 :            : 
    4164         [ #  # ]:          0 :     rParam.adjustForHyperlinkInPDF(aURLStart, mpDev);
    4165                 :            : }
    4166                 :            : 
    4167                 :          0 : void ScOutputData::DrawEditAsianVertical(DrawEditParam& rParam)
    4168                 :            : {
    4169                 :            :     // When in asian vertical orientation, the orientation value is STANDARD,
    4170                 :            :     // and the asian vertical boolean is true.
    4171                 :            :     OSL_ASSERT(rParam.meOrient == SVX_ORIENTATION_STANDARD);
    4172                 :            :     OSL_ASSERT(rParam.mbAsianVertical);
    4173                 :            :     OSL_ASSERT(rParam.meHorJust != SVX_HOR_JUSTIFY_REPEAT);
    4174                 :            : 
    4175         [ #  # ]:          0 :     Size aRefOne = mpRefDevice->PixelToLogic(Size(1,1));
    4176                 :            : 
    4177                 :          0 :     bool bHidden = false;
    4178                 :          0 :     bool bRepeat = false;
    4179 [ #  # ][ #  # ]:          0 :     bool bShrink = !rParam.mbBreak && !bRepeat && lcl_GetBoolValue(*rParam.mpPattern, ATTR_SHRINKTOFIT, rParam.mpCondSet);
         [ #  # ][ #  # ]
    4180         [ #  # ]:          0 :     long nAttrRotate = lcl_GetValue<SfxInt32Item, long>(*rParam.mpPattern, ATTR_ROTATE_VALUE, rParam.mpCondSet);
    4181                 :            : 
    4182         [ #  # ]:          0 :     if (nAttrRotate)
    4183                 :            :     {
    4184                 :            :         //! Flag setzen, um die Zelle in DrawRotated wiederzufinden ?
    4185                 :            :         //! (oder Flag schon bei DrawBackground, dann hier keine Abfrage)
    4186                 :          0 :         bHidden = true;     // gedreht wird getrennt ausgegeben
    4187                 :            :     }
    4188                 :            : 
    4189                 :            :     // default alignment for asian vertical mode is top-right
    4190         [ #  # ]:          0 :     if ( rParam.meHorJust == SVX_HOR_JUSTIFY_STANDARD )
    4191                 :          0 :         rParam.meHorJust = SVX_HOR_JUSTIFY_RIGHT;
    4192                 :            : 
    4193                 :            :     SvxCellHorJustify eOutHorJust =
    4194                 :            :         ( rParam.meHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? rParam.meHorJust :
    4195 [ #  # ][ #  # ]:          0 :         ( rParam.mbCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
    4196                 :            : 
    4197 [ #  # ][ #  # ]:          0 :     if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
    4198                 :          0 :         eOutHorJust = SVX_HOR_JUSTIFY_LEFT;     // repeat is not yet implemented
    4199                 :            : 
    4200         [ #  # ]:          0 :     if (bHidden)
    4201                 :            :         return;
    4202                 :            : 
    4203                 :            :     //! mirror margin values for RTL?
    4204                 :            :     //! move margin down to after final GetOutputArea call
    4205                 :            :     long nTopM, nLeftM, nBottomM, nRightM;
    4206         [ #  # ]:          0 :     rParam.calcMargins(nTopM, nLeftM, nBottomM, nRightM, mnPPTX, mnPPTY);
    4207                 :            : 
    4208                 :          0 :     SCCOL nXForPos = rParam.mnX;
    4209         [ #  # ]:          0 :     if ( nXForPos < nX1 )
    4210                 :            :     {
    4211                 :          0 :         nXForPos = nX1;
    4212                 :          0 :         rParam.mnPosX = rParam.mnInitPosX;
    4213                 :            :     }
    4214                 :          0 :     SCSIZE nArrYForPos = rParam.mnArrY;
    4215         [ #  # ]:          0 :     if ( nArrYForPos < 1 )
    4216                 :            :     {
    4217                 :          0 :         nArrYForPos = 1;
    4218                 :          0 :         rParam.mnPosY = nScrY;
    4219                 :            :     }
    4220                 :            : 
    4221         [ #  # ]:          0 :     OutputAreaParam aAreaParam;
    4222                 :            : 
    4223                 :            :     //
    4224                 :            :     //  Initial page size - large for normal text, cell size for automatic line breaks
    4225                 :            :     //
    4226                 :            : 
    4227                 :          0 :     Size aPaperSize = Size( 1000000, 1000000 );
    4228                 :            :     //  call GetOutputArea with nNeeded=0, to get only the cell width
    4229                 :            : 
    4230                 :            :     //! handle nArrY == 0
    4231                 :            :     GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, 0,
    4232                 :          0 :                    *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    4233         [ #  # ]:          0 :                    rParam.mbCellIsValue, true, false, aAreaParam );
    4234                 :            : 
    4235                 :            :     //! special ScEditUtil handling if formatting for printer
    4236         [ #  # ]:          0 :     rParam.calcPaperSize(aPaperSize, aAreaParam.maAlignRect, mnPPTX, mnPPTY);
    4237                 :            : 
    4238         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    4239                 :            :     {
    4240         [ #  # ]:          0 :         Size aLogicSize = mpRefDevice->PixelToLogic(aPaperSize);
    4241 [ #  # ][ #  # ]:          0 :         if ( rParam.mbBreak && !rParam.mbAsianVertical && mpRefDevice != pFmtDevice )
                 [ #  # ]
    4242                 :            :         {
    4243                 :            :             // #i85342# screen display and formatting for printer,
    4244                 :            :             // use same GetEditArea call as in ScViewData::SetEditEngine
    4245                 :            : 
    4246         [ #  # ]:          0 :             Fraction aFract(1,1);
    4247                 :            :             Rectangle aUtilRect = ScEditUtil( mpDoc, rParam.mnCellX, rParam.mnCellY, nTab, Point(0,0), pFmtDevice,
    4248 [ #  # ][ #  # ]:          0 :                 HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( rParam.mpPattern, false );
    4249         [ #  # ]:          0 :             aLogicSize.Width() = aUtilRect.GetWidth();
    4250                 :            :         }
    4251         [ #  # ]:          0 :         rParam.mpEngine->SetPaperSize(aLogicSize);
    4252                 :            :     }
    4253                 :            :     else
    4254         [ #  # ]:          0 :         rParam.mpEngine->SetPaperSize(aPaperSize);
    4255                 :            : 
    4256                 :            :     //
    4257                 :            :     //  Fill the EditEngine (cell attributes and text)
    4258                 :            :     //
    4259                 :            : 
    4260                 :            :     // default alignment for asian vertical mode is top-right
    4261         [ #  # ]:          0 :     if ( rParam.meVerJust == SVX_VER_JUSTIFY_STANDARD )
    4262                 :          0 :         rParam.meVerJust = SVX_VER_JUSTIFY_TOP;
    4263                 :            : 
    4264         [ #  # ]:          0 :     rParam.setPatternToEngine(mbUseStyleColor);
    4265         [ #  # ]:          0 :     rParam.setAlignmentToEngine();
    4266                 :            : 
    4267                 :            :     //  Read content from cell
    4268                 :            : 
    4269                 :          0 :     bool bWrapFields = false;
    4270 [ #  # ][ #  # ]:          0 :     if (!rParam.readCellContent(mpDoc, mbShowNullValues, mbShowFormulas, mbSyntaxMode, mbUseStyleColor, mbForceAutoColor, bWrapFields))
    4271                 :            :         // Failed to read cell content.  Bail out.
    4272                 :            :         return;
    4273                 :            : 
    4274         [ #  # ]:          0 :     if ( mbSyntaxMode )
    4275         [ #  # ]:          0 :         SetEditSyntaxColor( *rParam.mpEngine, rParam.mpCell );
    4276 [ #  # ][ #  # ]:          0 :     else if ( mbUseStyleColor && mbForceAutoColor )
    4277         [ #  # ]:          0 :         lcl_SetEditColor( *rParam.mpEngine, COL_AUTO );     //! or have a flag at EditEngine
    4278                 :            : 
    4279         [ #  # ]:          0 :     rParam.mpEngine->SetUpdateMode( true );     // after SetText, before CalcTextWidth/GetTextHeight
    4280                 :            : 
    4281                 :            :     //
    4282                 :            :     //  Get final output area using the calculated width
    4283                 :            :     //
    4284                 :            : 
    4285                 :            :     long nEngineWidth, nEngineHeight;
    4286         [ #  # ]:          0 :     rParam.getEngineSize(rParam.mpEngine, nEngineWidth, nEngineHeight);
    4287                 :            : 
    4288                 :          0 :     long nNeededPixel = nEngineWidth;
    4289         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    4290         [ #  # ]:          0 :         nNeededPixel = mpRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
    4291                 :          0 :     nNeededPixel += nLeftM + nRightM;
    4292                 :            : 
    4293                 :            :     // for break, the first GetOutputArea call is sufficient
    4294                 :            :     GetOutputArea( nXForPos, nArrYForPos, rParam.mnPosX, rParam.mnPosY, rParam.mnCellX, rParam.mnCellY, nNeededPixel,
    4295                 :          0 :                    *rParam.mpPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    4296 [ #  # ][ #  # ]:          0 :                    rParam.mbCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
         [ #  # ][ #  # ]
    4297                 :            : 
    4298         [ #  # ]:          0 :     if ( bShrink )
    4299                 :            :     {
    4300                 :            :         ShrinkEditEngine( *rParam.mpEngine, aAreaParam.maAlignRect,
    4301                 :            :             nLeftM, nTopM, nRightM, nBottomM, false,
    4302                 :          0 :             sal::static_int_cast<sal_uInt16>(rParam.meOrient), 0, rParam.mbPixelToLogic,
    4303                 :            :             nEngineWidth, nEngineHeight, nNeededPixel,
    4304         [ #  # ]:          0 :             aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
    4305                 :            :     }
    4306 [ #  # ][ #  # ]:          0 :     if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && rParam.mpEngine->GetParagraphCount() == 1 )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    4307                 :            :     {
    4308                 :            :         // First check if twice the space for the formatted text is available
    4309                 :            :         // (otherwise just keep it unchanged).
    4310                 :            : 
    4311                 :          0 :         long nFormatted = nNeededPixel - nLeftM - nRightM;      // without margin
    4312         [ #  # ]:          0 :         long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
    4313         [ #  # ]:          0 :         if ( nAvailable >= 2 * nFormatted )
    4314                 :            :         {
    4315                 :            :             // "repeat" is handled with unformatted text (for performance reasons)
    4316         [ #  # ]:          0 :             String aCellStr = rParam.mpEngine->GetText();
    4317         [ #  # ]:          0 :             rParam.mpEngine->SetText( aCellStr );
    4318                 :            : 
    4319         [ #  # ]:          0 :             long nRepeatSize = (long) rParam.mpEngine->CalcTextWidth();
    4320         [ #  # ]:          0 :             if (rParam.mbPixelToLogic)
    4321         [ #  # ]:          0 :                 nRepeatSize = mpRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
    4322         [ #  # ]:          0 :             if ( pFmtDevice != mpRefDevice )
    4323                 :          0 :                 ++nRepeatSize;
    4324         [ #  # ]:          0 :             if ( nRepeatSize > 0 )
    4325                 :            :             {
    4326                 :          0 :                 long nRepeatCount = nAvailable / nRepeatSize;
    4327         [ #  # ]:          0 :                 if ( nRepeatCount > 1 )
    4328                 :            :                 {
    4329         [ #  # ]:          0 :                     String aRepeated = aCellStr;
    4330         [ #  # ]:          0 :                     for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
    4331         [ #  # ]:          0 :                         aRepeated.Append( aCellStr );
    4332         [ #  # ]:          0 :                     rParam.mpEngine->SetText( aRepeated );
    4333                 :            : 
    4334         [ #  # ]:          0 :                     nEngineHeight = rParam.mpEngine->GetTextHeight();
    4335         [ #  # ]:          0 :                     nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
    4336         [ #  # ]:          0 :                     if (rParam.mbPixelToLogic)
    4337         [ #  # ]:          0 :                         nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
    4338                 :            :                     else
    4339                 :          0 :                         nNeededPixel = nEngineWidth;
    4340         [ #  # ]:          0 :                     nNeededPixel += nLeftM + nRightM;
    4341                 :            :                 }
    4342         [ #  # ]:          0 :             }
    4343                 :            :         }
    4344                 :            :     }
    4345                 :            : 
    4346 [ #  # ][ #  # ]:          0 :     if ( rParam.mbCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
                 [ #  # ]
    4347                 :            :     {
    4348 [ #  # ][ #  # ]:          0 :         rParam.mpEngine->SetText(rtl::OUString("###"));
                 [ #  # ]
    4349         [ #  # ]:          0 :         nEngineWidth = (long) rParam.mpEngine->CalcTextWidth();
    4350         [ #  # ]:          0 :         if (rParam.mbPixelToLogic)
    4351         [ #  # ]:          0 :             nNeededPixel = mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
    4352                 :            :         else
    4353                 :          0 :             nNeededPixel = nEngineWidth;
    4354                 :          0 :         nNeededPixel += nLeftM + nRightM;
    4355                 :            : 
    4356                 :            :         //  No clip marks if "###" doesn't fit (same as in DrawStrings)
    4357                 :            :     }
    4358                 :            : 
    4359         [ #  # ]:          0 :     if (eOutHorJust != SVX_HOR_JUSTIFY_LEFT)
    4360                 :            :     {
    4361                 :          0 :         aPaperSize.Width() = nNeededPixel + 1;
    4362         [ #  # ]:          0 :         if (rParam.mbPixelToLogic)
    4363 [ #  # ][ #  # ]:          0 :             rParam.mpEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
    4364                 :            :         else
    4365         [ #  # ]:          0 :             rParam.mpEngine->SetPaperSize(aPaperSize);
    4366                 :            :     }
    4367                 :            : 
    4368                 :          0 :     long nStartX = aAreaParam.maAlignRect.Left();
    4369                 :          0 :     long nStartY = aAreaParam.maAlignRect.Top();
    4370         [ #  # ]:          0 :     long nCellWidth = aAreaParam.maAlignRect.GetWidth();
    4371                 :          0 :     long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
    4372         [ #  # ]:          0 :     long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
    4373                 :            : 
    4374                 :            :     //  text with automatic breaks is aligned only within the
    4375                 :            :     //  edit engine's paper size, the output of the whole area
    4376                 :            :     //  is always left-aligned
    4377                 :            : 
    4378                 :          0 :     nStartX += nLeftM;
    4379                 :            : 
    4380 [ #  # ][ #  # ]:          0 :     bool bOutside = (aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW);
    4381         [ #  # ]:          0 :     if (bOutside)
    4382                 :            :         return;
    4383                 :            : 
    4384         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Left() < nScrX )
    4385                 :            :     {
    4386                 :          0 :         aAreaParam.maClipRect.Left() = nScrX;
    4387                 :          0 :         aAreaParam.mbLeftClip = true;
    4388                 :            :     }
    4389         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
    4390                 :            :     {
    4391                 :          0 :         aAreaParam.maClipRect.Right() = nScrX + nScrW;          //! minus one?
    4392                 :          0 :         aAreaParam.mbRightClip = true;
    4393                 :            :     }
    4394                 :            : 
    4395 [ #  # ][ #  # ]:          0 :     bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
    4396                 :          0 :     bool bSimClip = false;
    4397                 :            : 
    4398         [ #  # ]:          0 :     if ( bWrapFields )
    4399                 :            :     {
    4400                 :            :         //  Fields in a cell with automatic breaks: clip to cell width
    4401                 :          0 :         bClip = true;
    4402                 :            :     }
    4403                 :            : 
    4404         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Top() < nScrY )
    4405                 :            :     {
    4406                 :          0 :         aAreaParam.maClipRect.Top() = nScrY;
    4407                 :          0 :         bClip = true;
    4408                 :            :     }
    4409         [ #  # ]:          0 :     if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
    4410                 :            :     {
    4411                 :          0 :         aAreaParam.maClipRect.Bottom() = nScrY + nScrH;     //! minus one?
    4412                 :          0 :         bClip = true;
    4413                 :            :     }
    4414                 :            : 
    4415                 :          0 :     Size aCellSize;         // output area, excluding margins, in logical units
    4416         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    4417         [ #  # ]:          0 :         aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
    4418                 :            :     else
    4419                 :          0 :         aCellSize = Size( nOutWidth, nOutHeight );
    4420                 :            : 
    4421         [ #  # ]:          0 :     if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
    4422                 :            :     {
    4423                 :            :         const ScMergeAttr* pMerge =
    4424         [ #  # ]:          0 :                 (ScMergeAttr*)&rParam.mpPattern->GetItem(ATTR_MERGE);
    4425 [ #  # ][ #  # ]:          0 :         bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
    4426                 :            : 
    4427                 :            :         //  Don't clip for text height when printing rows with optimal height,
    4428                 :            :         //  except when font size is from conditional formatting.
    4429                 :            :         //! Allow clipping when vertically merged?
    4430 [ #  # ][ #  # ]:          0 :         if ( eType != OUTTYPE_PRINTER ||
         [ #  # ][ #  # ]
                 [ #  # ]
    4431         [ #  # ]:          0 :             ( mpDoc->GetRowFlags( rParam.mnCellY, nTab ) & CR_MANUALSIZE ) ||
    4432                 :            :             ( rParam.mpCondSet && SFX_ITEM_SET ==
    4433         [ #  # ]:          0 :                 rParam.mpCondSet->GetItemState(ATTR_FONT_HEIGHT, true) ) )
    4434                 :          0 :             bClip = true;
    4435                 :            :         else
    4436                 :          0 :             bSimClip = true;
    4437                 :            : 
    4438                 :            :         //  Show clip marks if height is at least 5pt too small and
    4439                 :            :         //  there are several lines of text.
    4440                 :            :         //  Not for asian vertical text, because that would interfere
    4441                 :            :         //  with the default right position of the text.
    4442                 :            :         //  Only with automatic line breaks, to avoid having to find
    4443                 :            :         //  the cells with the horizontal end of the text again.
    4444 [ #  # ][ #  # ]:          0 :         if ( nEngineHeight - aCellSize.Height() > 100 &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    4445                 :            :              ( rParam.mbBreak || rParam.meOrient == SVX_ORIENTATION_STACKED ) &&
    4446                 :          0 :              !rParam.mbAsianVertical && bMarkClipped &&
    4447 [ #  # ][ #  # ]:          0 :              ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 ) )
    4448                 :            :         {
    4449                 :          0 :             CellInfo* pClipMarkCell = NULL;
    4450         [ #  # ]:          0 :             if ( bMerged )
    4451                 :            :             {
    4452                 :            :                 //  anywhere in the merged area...
    4453         [ #  # ]:          0 :                 SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
    4454         [ #  # ]:          0 :                 pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
    4455                 :            :             }
    4456                 :            :             else
    4457                 :          0 :                 pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
    4458                 :            : 
    4459                 :          0 :             pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT;      //! also allow left?
    4460                 :          0 :             bAnyClipped = true;
    4461                 :            : 
    4462                 :          0 :             long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
    4463         [ #  # ]:          0 :             if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
    4464                 :          0 :                 aAreaParam.maClipRect.Right() -= nMarkPixel;
    4465                 :            :         }
    4466                 :            :     }
    4467                 :            : 
    4468         [ #  # ]:          0 :     Rectangle aLogicClip;
    4469 [ #  # ][ #  # ]:          0 :     if (bClip || bSimClip)
    4470                 :            :     {
    4471                 :            :         // Clip marks are already handled in GetOutputArea
    4472                 :            : 
    4473         [ #  # ]:          0 :         if (rParam.mbPixelToLogic)
    4474         [ #  # ]:          0 :             aLogicClip = mpRefDevice->PixelToLogic( aAreaParam.maClipRect );
    4475                 :            :         else
    4476                 :          0 :             aLogicClip = aAreaParam.maClipRect;
    4477                 :            : 
    4478         [ #  # ]:          0 :         if (bClip)  // bei bSimClip nur aClipRect initialisieren
    4479                 :            :         {
    4480         [ #  # ]:          0 :             if (bMetaFile)
    4481                 :            :             {
    4482         [ #  # ]:          0 :                 mpDev->Push();
    4483         [ #  # ]:          0 :                 mpDev->IntersectClipRegion( aLogicClip );
    4484                 :            :             }
    4485                 :            :             else
    4486 [ #  # ][ #  # ]:          0 :                 mpDev->SetClipRegion( Region( aLogicClip ) );
                 [ #  # ]
    4487                 :            :         }
    4488                 :            :     }
    4489                 :            : 
    4490                 :          0 :     Point aLogicStart;
    4491         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    4492         [ #  # ]:          0 :         aLogicStart = mpRefDevice->PixelToLogic( Point(nStartX,nStartY) );
    4493                 :            :     else
    4494                 :          0 :         aLogicStart = Point(nStartX, nStartY);
    4495                 :            : 
    4496                 :          0 :     long nAvailWidth = aCellSize.Width();
    4497                 :            :     // space for AutoFilter is already handled in GetOutputArea
    4498                 :            : 
    4499                 :            :     //  horizontal alignment
    4500                 :            : 
    4501         [ #  # ]:          0 :     if (rParam.meHorJust==SVX_HOR_JUSTIFY_RIGHT)
    4502                 :          0 :         aLogicStart.X() += nAvailWidth - nEngineWidth;
    4503         [ #  # ]:          0 :     else if (rParam.meHorJust==SVX_HOR_JUSTIFY_CENTER)
    4504                 :          0 :         aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
    4505                 :            : 
    4506                 :            :     // paper size is subtracted below
    4507                 :          0 :     aLogicStart.X() += nEngineWidth;
    4508                 :            : 
    4509                 :            :     // vertical adjustment is within the EditEngine
    4510         [ #  # ]:          0 :     if (rParam.mbPixelToLogic)
    4511         [ #  # ]:          0 :         aLogicStart.Y() += mpRefDevice->PixelToLogic(Size(0,nTopM)).Height();
    4512                 :            :     else
    4513                 :          0 :         aLogicStart.Y() += nTopM;
    4514                 :            : 
    4515                 :          0 :     Point aURLStart = aLogicStart;      // copy before modifying for orientation
    4516                 :            : 
    4517         [ #  # ]:          0 :     rParam.adjustForRTL();
    4518                 :            : 
    4519                 :            :     // bMoveClipped handling has been replaced by complete alignment
    4520                 :            :     // handling (also extending to the left).
    4521                 :            : 
    4522                 :            :     //  with SetVertical, the start position is top left of
    4523                 :            :     //  the whole output area, not the text itself
    4524         [ #  # ]:          0 :     aLogicStart.X() -= rParam.mpEngine->GetPaperSize().Width();
    4525                 :            : 
    4526         [ #  # ]:          0 :     rParam.mpEngine->Draw(mpDev, aLogicStart, 0);
    4527                 :            : 
    4528         [ #  # ]:          0 :     if (bClip)
    4529                 :            :     {
    4530         [ #  # ]:          0 :         if (bMetaFile)
    4531         [ #  # ]:          0 :             mpDev->Pop();
    4532                 :            :         else
    4533         [ #  # ]:          0 :             mpDev->SetClipRegion();
    4534                 :            :     }
    4535                 :            : 
    4536         [ #  # ]:          0 :     rParam.adjustForHyperlinkInPDF(aURLStart, mpDev);
    4537                 :            : }
    4538                 :            : 
    4539                 :       1345 : void ScOutputData::DrawEdit(sal_Bool bPixelToLogic)
    4540                 :            : {
    4541                 :       1345 :     ScFieldEditEngine* pEngine = NULL;
    4542                 :       1345 :     bool bHyphenatorSet = false;
    4543                 :       1345 :     const ScPatternAttr* pOldPattern = NULL;
    4544                 :       1345 :     const SfxItemSet*    pOldCondSet = NULL;
    4545                 :       1345 :     ScBaseCell* pCell = NULL;
    4546                 :            : 
    4547                 :       1345 :     long nInitPosX = nScrX;
    4548         [ +  + ]:       1345 :     if ( bLayoutRTL )
    4549                 :            :     {
    4550                 :          2 :         nInitPosX += nMirrorW - 1;
    4551                 :            :     }
    4552         [ +  + ]:       1345 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
    4553                 :            : 
    4554                 :            :     //! store nLastContentCol as member!
    4555                 :       1345 :     SCCOL nLastContentCol = MAXCOL;
    4556         [ +  - ]:       1345 :     if ( nX2 < MAXCOL )
    4557                 :            :         nLastContentCol = sal::static_int_cast<SCCOL>(
    4558         [ +  - ]:       1345 :             nLastContentCol - mpDoc->GetEmptyLinesInBlock( nX2+1, nY1, nTab, MAXCOL, nY2, nTab, DIR_RIGHT ) );
    4559                 :            : 
    4560                 :       1345 :     long nRowPosY = nScrY;
    4561         [ +  + ]:      18557 :     for (SCSIZE nArrY=0; nArrY+1<nArrCount; nArrY++)            // 0 fuer Reste von zusammengefassten
    4562                 :            :     {
    4563                 :      17212 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
    4564                 :            : 
    4565         [ +  + ]:      17212 :         if (nArrY==1) nRowPosY = nScrY;                         // vorher wird einzeln berechnet
    4566                 :            : 
    4567 [ -  + ][ #  # ]:      17212 :         if ( pThisRowInfo->bChanged || nArrY==0 )
    4568                 :            :         {
    4569                 :      17212 :             long nPosX = 0;
    4570         [ +  + ]:     185084 :             for (SCCOL nX=0; nX<=nX2; nX++)                 // wegen Ueberhaengen
    4571                 :            :             {
    4572         [ +  + ]:     167872 :                 if (nX==nX1) nPosX = nInitPosX;                 // positions before nX1 are calculated individually
    4573                 :            : 
    4574                 :     167872 :                 CellInfo*   pInfo = &pThisRowInfo->pCellInfo[nX+1];
    4575         [ +  + ]:     167872 :                 if (pInfo->bEditEngine)
    4576                 :            :                 {
    4577                 :       1033 :                     SCROW nY = pThisRowInfo->nRowNo;
    4578                 :            : 
    4579                 :       1033 :                     SCCOL nCellX = nX;                  // position where the cell really starts
    4580                 :       1033 :                     SCROW nCellY = nY;
    4581                 :       1033 :                     sal_Bool bDoCell = false;
    4582                 :            : 
    4583                 :       1033 :                     long nPosY = nRowPosY;
    4584         [ -  + ]:       1033 :                     if ( nArrY == 0 )
    4585                 :            :                     {
    4586                 :          0 :                         nPosY = nScrY;
    4587                 :          0 :                         nY = pRowInfo[1].nRowNo;
    4588                 :            :                         SCCOL nOverX;                   // start of the merged cells
    4589                 :            :                         SCROW nOverY;
    4590 [ #  # ][ #  # ]:          0 :                         if (GetMergeOrigin( nX,nY, 1, nOverX,nOverY, sal_True ))
    4591                 :            :                         {
    4592                 :          0 :                             nCellX = nOverX;
    4593                 :          0 :                             nCellY = nOverY;
    4594                 :          0 :                             bDoCell = sal_True;
    4595                 :            :                         }
    4596                 :            :                     }
    4597 [ +  + ][ -  + ]:       1033 :                     else if ( nX == nX2 && !pThisRowInfo->pCellInfo[nX+1].pCell )
    4598                 :            :                     {
    4599                 :            :                         //  Rest of a long text further to the right?
    4600                 :            : 
    4601                 :          0 :                         SCCOL nTempX=nX;
    4602 [ #  # ][ #  # ]:          0 :                         while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
         [ #  # ][ #  # ]
    4603                 :          0 :                             ++nTempX;
    4604                 :            : 
    4605 [ #  # ][ #  # ]:          0 :                         if ( nTempX > nX &&
         [ #  # ][ #  # ]
    4606         [ #  # ]:          0 :                              !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
    4607         [ #  # ]:          0 :                              !mpDoc->HasAttrib( nTempX,nY,nTab, nX,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
    4608                 :            :                         {
    4609                 :          0 :                             nCellX = nTempX;
    4610                 :          0 :                             bDoCell = sal_True;
    4611                 :          0 :                         }
    4612                 :            :                     }
    4613                 :            :                     else
    4614                 :            :                     {
    4615                 :       1033 :                         bDoCell = sal_True;
    4616                 :            :                     }
    4617                 :            : 
    4618 [ +  - ][ -  + ]:       1033 :                     if ( bDoCell && bEditMode && nCellX == nEditCol && nCellY == nEditRow )
         [ #  # ][ #  # ]
    4619                 :          0 :                         bDoCell = false;
    4620                 :            : 
    4621                 :       1033 :                     const ScPatternAttr* pPattern = NULL;
    4622                 :       1033 :                     const SfxItemSet* pCondSet = NULL;
    4623         [ +  - ]:       1033 :                     if (bDoCell)
    4624                 :            :                     {
    4625 [ +  - ][ +  + ]:       2065 :                         if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 &&
         [ +  - ][ +  - ]
                 [ +  + ]
    4626         [ +  - ]:       1032 :                              !mpDoc->ColHidden(nCellX, nTab) )
    4627                 :            :                         {
    4628                 :       1032 :                             CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1];
    4629                 :       1032 :                             pPattern = rCellInfo.pPatternAttr;
    4630                 :       1032 :                             pCondSet = rCellInfo.pConditionSet;
    4631                 :       1032 :                             pCell = rCellInfo.pCell;
    4632                 :            :                         }
    4633                 :            :                         else        // get from document
    4634                 :            :                         {
    4635         [ +  - ]:          1 :                             pPattern = mpDoc->GetPattern( nCellX, nCellY, nTab );
    4636         [ +  - ]:          1 :                             pCondSet = mpDoc->GetCondResult( nCellX, nCellY, nTab );
    4637         [ +  - ]:          1 :                             GetVisibleCell( nCellX, nCellY, nTab, pCell );
    4638                 :            :                         }
    4639         [ -  + ]:       1033 :                         if ( !pCell )
    4640                 :          0 :                             bDoCell = false;
    4641                 :            :                     }
    4642         [ +  - ]:       1033 :                     if (bDoCell)
    4643                 :            :                     {
    4644         [ +  + ]:       1033 :                         if (!pEngine)
    4645         [ +  - ]:        306 :                             pEngine = CreateOutputEditEngine();
    4646                 :            :                         else
    4647         [ +  - ]:        727 :                             lcl_ClearEdit( *pEngine );      // also calls SetUpdateMode(sal_False)
    4648                 :            : 
    4649                 :            :                         // fdo#32530: Check if the first character is RTL.
    4650         [ +  - ]:       1033 :                         rtl::OUString aStr = mpDoc->GetString(nCellX, nCellY, nTab);
    4651                 :            : 
    4652 [ +  - ][ +  - ]:       1033 :                         DrawEditParam aParam(pPattern, pCondSet, lcl_SafeIsValue(pCell));
    4653                 :       1033 :                         aParam.mbPixelToLogic = bPixelToLogic;
    4654                 :       1033 :                         aParam.mbHyphenatorSet = bHyphenatorSet;
    4655         [ +  - ]:       1033 :                         aParam.mbRTL = beginsWithRTLCharacter(aStr);
    4656                 :       1033 :                         aParam.mpEngine = pEngine;
    4657                 :       1033 :                         aParam.mpCell = pCell;
    4658                 :       1033 :                         aParam.mnArrY = nArrY;
    4659                 :       1033 :                         aParam.mnX = nX;
    4660                 :       1033 :                         aParam.mnY = nY;
    4661                 :       1033 :                         aParam.mnCellX = nCellX;
    4662                 :       1033 :                         aParam.mnCellY = nCellY;
    4663                 :       1033 :                         aParam.mnPosX = nPosX;
    4664                 :       1033 :                         aParam.mnPosY = nPosY;
    4665                 :       1033 :                         aParam.mnInitPosX = nInitPosX;
    4666                 :       1033 :                         aParam.mpOldPattern = pOldPattern;
    4667                 :       1033 :                         aParam.mpOldCondSet = pOldCondSet;
    4668                 :       1033 :                         aParam.mpThisRowInfo = pThisRowInfo;
    4669         [ -  + ]:       1033 :                         if (aParam.meHorJust == SVX_HOR_JUSTIFY_REPEAT)
    4670                 :            :                         {
    4671                 :            :                             // ignore orientation/rotation if "repeat" is active
    4672                 :          0 :                             aParam.meOrient = SVX_ORIENTATION_STANDARD;
    4673                 :            :                         }
    4674   [ -  +  -  + ]:       1033 :                         switch (aParam.meOrient)
    4675                 :            :                         {
    4676                 :            :                             case SVX_ORIENTATION_BOTTOMTOP:
    4677         [ #  # ]:          0 :                                 DrawEditBottomTop(aParam);
    4678                 :          0 :                             break;
    4679                 :            :                             case SVX_ORIENTATION_TOPBOTTOM:
    4680         [ +  - ]:        193 :                                 DrawEditTopBottom(aParam);
    4681                 :        193 :                             break;
    4682                 :            :                             case SVX_ORIENTATION_STACKED:
    4683                 :            :                                 // this can be vertically stacked or asian vertical.
    4684         [ #  # ]:          0 :                                 DrawEditStacked(aParam);
    4685                 :          0 :                             break;
    4686                 :            :                             default:
    4687         [ +  - ]:        840 :                                 DrawEditStandard(aParam);
    4688                 :            :                         }
    4689                 :            : 
    4690                 :            :                         // Retrieve parameters for next iteration.
    4691                 :       1033 :                         pOldPattern = aParam.mpOldPattern;
    4692                 :       1033 :                         pOldCondSet = aParam.mpOldCondSet;
    4693                 :       1033 :                         bHyphenatorSet = aParam.mbHyphenatorSet;
    4694                 :            :                     }
    4695                 :            :                 }
    4696                 :     167872 :                 nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
    4697                 :            :             }
    4698                 :            :         }
    4699                 :      17212 :         nRowPosY += pRowInfo[nArrY].nHeight;
    4700                 :            :     }
    4701                 :            : 
    4702 [ +  + ][ +  - ]:       1345 :     delete pEngine;
    4703                 :            : 
    4704         [ +  + ]:       1345 :     if (bAnyRotated)
    4705         [ +  - ]:         99 :         DrawRotated(bPixelToLogic);     //! von aussen rufen ?
    4706                 :       1345 : }
    4707                 :            : 
    4708                 :            : //  -------------------------------------------------------------------------------
    4709                 :            : 
    4710                 :         99 : void ScOutputData::DrawRotated(sal_Bool bPixelToLogic)
    4711                 :            : {
    4712                 :            :     //! nRotMax speichern
    4713                 :         99 :     SCCOL nRotMax = nX2;
    4714         [ +  + ]:        736 :     for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
    4715 [ +  + ][ -  + ]:        637 :         if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
    4716                 :          0 :             nRotMax = pRowInfo[nRotY].nRotMaxCol;
    4717                 :            : 
    4718                 :            : 
    4719         [ +  - ]:         99 :     ScModule* pScMod = SC_MOD();
    4720 [ +  - ][ +  - ]:         99 :     sal_Int32 nConfBackColor = pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
    4721                 :            :     sal_Bool bCellContrast = mbUseStyleColor &&
    4722 [ +  - ][ +  - ]:         99 :             Application::GetSettings().GetStyleSettings().GetHighContrastMode();
                 [ -  + ]
    4723                 :            : 
    4724                 :         99 :     ScFieldEditEngine* pEngine = NULL;
    4725                 :         99 :     sal_Bool bHyphenatorSet = false;
    4726                 :            :     const ScPatternAttr* pPattern;
    4727                 :            :     const SfxItemSet*    pCondSet;
    4728                 :         99 :     const ScPatternAttr* pOldPattern = NULL;
    4729                 :         99 :     const SfxItemSet*    pOldCondSet = NULL;
    4730                 :         99 :     ScBaseCell* pCell = NULL;
    4731                 :            : 
    4732                 :         99 :     long nInitPosX = nScrX;
    4733         [ -  + ]:         99 :     if ( bLayoutRTL )
    4734                 :            :     {
    4735                 :          0 :         nInitPosX += nMirrorW - 1;
    4736                 :            :     }
    4737         [ -  + ]:         99 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
    4738                 :            : 
    4739                 :         99 :     long nRowPosY = nScrY;
    4740         [ +  + ]:        637 :     for (SCSIZE nArrY=0; nArrY+1<nArrCount; nArrY++)            // 0 fuer Reste von zusammengefassten
    4741                 :            :     {
    4742                 :        538 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
    4743                 :        538 :         long nCellHeight = (long) pThisRowInfo->nHeight;
    4744         [ +  + ]:        538 :         if (nArrY==1) nRowPosY = nScrY;                         // vorher wird einzeln berechnet
    4745                 :            : 
    4746 [ -  + ][ #  # ]:        538 :         if ( ( pThisRowInfo->bChanged || nArrY==0 ) && pThisRowInfo->nRotMaxCol != SC_ROTMAX_NONE )
                 [ +  + ]
    4747                 :            :         {
    4748                 :        366 :             long nPosX = 0;
    4749         [ +  + ]:       4026 :             for (SCCOL nX=0; nX<=nRotMax; nX++)
    4750                 :            :             {
    4751         [ +  + ]:       3660 :                 if (nX==nX1) nPosX = nInitPosX;                 // positions before nX1 are calculated individually
    4752                 :            : 
    4753                 :       3660 :                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
    4754         [ +  + ]:       3660 :                 if ( pInfo->nRotateDir != SC_ROTDIR_NONE )
    4755                 :            :                 {
    4756                 :       1455 :                     SCROW nY = pThisRowInfo->nRowNo;
    4757                 :            : 
    4758                 :       1455 :                     sal_Bool bHidden = false;
    4759         [ -  + ]:       1455 :                     if (bEditMode)
    4760 [ #  # ][ #  # ]:          0 :                         if ( nX == nEditCol && nY == nEditRow )
    4761                 :          0 :                             bHidden = sal_True;
    4762                 :            : 
    4763         [ +  - ]:       1455 :                     if (!bHidden)
    4764                 :            :                     {
    4765         [ +  + ]:       1455 :                         if (!pEngine)
    4766         [ +  - ]:         99 :                             pEngine = CreateOutputEditEngine();
    4767                 :            :                         else
    4768         [ +  - ]:       1356 :                             lcl_ClearEdit( *pEngine );      // also calls SetUpdateMode(sal_False)
    4769                 :            : 
    4770                 :       1455 :                         long nPosY = nRowPosY;
    4771                 :       1455 :                         sal_Bool bVisChanged = false;
    4772                 :            : 
    4773                 :            :                         //! Rest von zusammengefasster Zelle weiter oben funktioniert nicht!
    4774                 :            : 
    4775                 :       1455 :                         sal_Bool bFromDoc = false;
    4776                 :       1455 :                         pPattern = pInfo->pPatternAttr;
    4777                 :       1455 :                         pCondSet = pInfo->pConditionSet;
    4778         [ -  + ]:       1455 :                         if (!pPattern)
    4779                 :            :                         {
    4780         [ #  # ]:          0 :                             pPattern = mpDoc->GetPattern( nX, nY, nTab );
    4781                 :          0 :                             bFromDoc = sal_True;
    4782                 :            :                         }
    4783                 :       1455 :                         pCell = pInfo->pCell;
    4784         [ -  + ]:       1455 :                         if (bFromDoc)
    4785         [ #  # ]:          0 :                             pCondSet = mpDoc->GetCondResult( nX, nY, nTab );
    4786                 :            : 
    4787 [ +  + ][ -  + ]:       1455 :                         if (!pCell && nX>nX2)
    4788         [ #  # ]:          0 :                             GetVisibleCell( nX, nY, nTab, pCell );
    4789                 :            : 
    4790 [ +  + ][ +  - ]:       1455 :                         if ( !pCell || IsEmptyCellText( pThisRowInfo, nX, nY ) )
         [ -  + ][ +  + ]
    4791                 :        794 :                             bHidden = sal_True;     // nRotateDir is also set without a cell
    4792                 :            : 
    4793                 :       1455 :                         long nCellWidth = (long) pRowInfo[0].pCellInfo[nX+1].nWidth;
    4794                 :            : 
    4795                 :            :                         SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
    4796         [ +  - ]:       1455 :                                             pPattern->GetItem(ATTR_HOR_JUSTIFY, pCondSet)).GetValue();
    4797                 :            :                         sal_Bool bBreak = ( eHorJust == SVX_HOR_JUSTIFY_BLOCK ) ||
    4798 [ +  - ][ +  + ]:       1455 :                                     ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue();
                 [ +  + ]
    4799 [ -  + ][ #  # ]:       1455 :                         sal_Bool bRepeat = ( eHorJust == SVX_HOR_JUSTIFY_REPEAT && !bBreak );
    4800                 :            :                         sal_Bool bShrink = !bBreak && !bRepeat && static_cast<const SfxBoolItem&>
    4801 [ +  + ][ +  - ]:       1455 :                                         (pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
         [ +  - ][ +  - ]
    4802         [ +  - ]:       1455 :                         SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet );
    4803                 :            : 
    4804                 :            :                         const ScMergeAttr* pMerge =
    4805         [ +  - ]:       1455 :                                 (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
    4806 [ +  - ][ -  + ]:       1455 :                         sal_Bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
    4807                 :            : 
    4808                 :       1455 :                         long nStartX = nPosX;
    4809                 :       1455 :                         long nStartY = nPosY;
    4810         [ -  + ]:       1455 :                         if (nX<nX1)
    4811                 :            :                         {
    4812 [ #  # ][ #  # ]:          0 :                             if ((bBreak || eOrient!=SVX_ORIENTATION_STANDARD) && !bMerged)
                 [ #  # ]
    4813                 :          0 :                                 bHidden = sal_True;
    4814                 :            :                             else
    4815                 :            :                             {
    4816                 :          0 :                                 nStartX = nInitPosX;
    4817                 :          0 :                                 SCCOL nCol = nX1;
    4818         [ #  # ]:          0 :                                 while (nCol > nX)
    4819                 :            :                                 {
    4820                 :          0 :                                     --nCol;
    4821                 :          0 :                                     nStartX -= nLayoutSign * (long) pRowInfo[0].pCellInfo[nCol+1].nWidth;
    4822                 :            :                                 }
    4823                 :            :                             }
    4824                 :            :                         }
    4825                 :       1455 :                         long nCellStartX = nStartX;
    4826                 :            : 
    4827                 :            :                         //  Ersatzdarstellung fuer zu kleinen Text weggelassen
    4828                 :            : 
    4829         [ +  + ]:       1455 :                         if (!bHidden)
    4830                 :            :                         {
    4831                 :        661 :                             long nOutWidth = nCellWidth - 1;
    4832                 :        661 :                             long nOutHeight = nCellHeight;
    4833                 :            : 
    4834         [ -  + ]:        661 :                             if ( bMerged )                              // Zusammengefasst
    4835                 :            :                             {
    4836                 :          0 :                                 SCCOL nCountX = pMerge->GetColMerge();
    4837         [ #  # ]:          0 :                                 for (SCCOL i=1; i<nCountX; i++)
    4838         [ #  # ]:          0 :                                     nOutWidth += (long) ( mpDoc->GetColWidth(nX+i,nTab) * mnPPTX );
    4839                 :          0 :                                 SCROW nCountY = pMerge->GetRowMerge();
    4840         [ #  # ]:          0 :                                 nOutHeight += (long) mpDoc->GetScaledRowHeight( nY+1, nY+nCountY-1, nTab, mnPPTY);
    4841                 :            :                             }
    4842                 :            : 
    4843                 :            :                             SvxCellVerJustify eVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)
    4844         [ +  - ]:        661 :                                                 pPattern->GetItem(ATTR_VER_JUSTIFY, pCondSet)).GetValue();
    4845                 :            : 
    4846                 :            :                             // Syntax-Modus wird hier ignoriert...
    4847                 :            : 
    4848                 :            :                             // StringDiffer doesn't look at hyphenate, language items
    4849 [ -  + ][ +  + ]:        661 :                             if ( pPattern != pOldPattern || pCondSet != pOldCondSet )
    4850                 :            :                             {
    4851 [ +  - ][ +  - ]:         99 :                                 SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() );
                 [ +  - ]
    4852         [ +  - ]:         99 :                                 pPattern->FillEditItemSet( pSet, pCondSet );
    4853                 :            : 
    4854                 :            :                                                                     // Ausrichtung fuer EditEngine
    4855                 :         99 :                                 SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
    4856         [ -  + ]:         99 :                                 if (eOrient==SVX_ORIENTATION_STACKED)
    4857                 :          0 :                                     eSvxAdjust = SVX_ADJUST_CENTER;
    4858                 :            :                                 // Adjustment fuer bBreak ist hier weggelassen
    4859 [ +  - ][ +  - ]:         99 :                                 pSet->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
                 [ +  - ]
    4860                 :            : 
    4861         [ +  - ]:         99 :                                 pEngine->SetDefaults( pSet );
    4862                 :         99 :                                 pOldPattern = pPattern;
    4863                 :         99 :                                 pOldCondSet = pCondSet;
    4864                 :            : 
    4865         [ +  - ]:         99 :                                 sal_uLong nControl = pEngine->GetControlWord();
    4866         [ -  + ]:         99 :                                 if (eOrient==SVX_ORIENTATION_STACKED)
    4867                 :          0 :                                     nControl |= EE_CNTRL_ONECHARPERLINE;
    4868                 :            :                                 else
    4869                 :         99 :                                     nControl &= ~EE_CNTRL_ONECHARPERLINE;
    4870         [ +  - ]:         99 :                                 pEngine->SetControlWord( nControl );
    4871                 :            : 
    4872 [ +  - ][ +  - ]:         99 :                                 if ( !bHyphenatorSet && ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() )
         [ +  + ][ +  + ]
    4873                 :            :                                 {
    4874                 :            :                                     //  set hyphenator the first time it is needed
    4875         [ +  - ]:         65 :                                     com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
    4876         [ +  - ]:         65 :                                     pEngine->SetHyphenator( xXHyphenator );
    4877                 :         65 :                                     bHyphenatorSet = sal_True;
    4878                 :            :                                 }
    4879                 :            : 
    4880                 :            :                                 Color aBackCol = ((const SvxBrushItem&)
    4881         [ +  - ]:         99 :                                     pPattern->GetItem( ATTR_BACKGROUND, pCondSet )).GetColor();
    4882 [ +  + ][ -  + ]:         99 :                                 if ( mbUseStyleColor && ( aBackCol.GetTransparency() > 0 || bCellContrast ) )
         [ +  + ][ +  - ]
    4883                 :         34 :                                     aBackCol.SetColor( nConfBackColor );
    4884         [ +  - ]:         99 :                                 pEngine->SetBackgroundColor( aBackCol );
    4885                 :            :                             }
    4886                 :            : 
    4887                 :            :                             //  Raender
    4888                 :            : 
    4889                 :            :                             //!     Position und Papersize auf EditUtil umstellen !!!
    4890                 :            : 
    4891                 :            :                             const SvxMarginItem* pMargin = (const SvxMarginItem*)
    4892         [ +  - ]:        661 :                                                     &pPattern->GetItem(ATTR_MARGIN, pCondSet);
    4893                 :        661 :                             sal_uInt16 nIndent = 0;
    4894         [ -  + ]:        661 :                             if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
    4895                 :            :                                 nIndent = ((const SfxUInt16Item&)pPattern->
    4896         [ #  # ]:          0 :                                                     GetItem(ATTR_INDENT, pCondSet)).GetValue();
    4897                 :            : 
    4898                 :        661 :                             long nTotalHeight = nOutHeight; // ohne Rand abzuziehen
    4899         [ +  - ]:        661 :                             if ( bPixelToLogic )
    4900         [ +  - ]:        661 :                                 nTotalHeight = mpRefDevice->PixelToLogic(Size(0,nTotalHeight)).Height();
    4901                 :            : 
    4902                 :        661 :                             long nLeftM = (long) ( (pMargin->GetLeftMargin() + nIndent) * mnPPTX );
    4903                 :        661 :                             long nTopM  = (long) ( pMargin->GetTopMargin() * mnPPTY );
    4904                 :        661 :                             long nRightM  = (long) ( pMargin->GetRightMargin() * mnPPTX );
    4905                 :        661 :                             long nBottomM = (long) ( pMargin->GetBottomMargin() * mnPPTY );
    4906                 :        661 :                             nStartX += nLeftM;
    4907                 :        661 :                             nStartY += nTopM;
    4908                 :        661 :                             nOutWidth -= nLeftM + nRightM;
    4909                 :        661 :                             nOutHeight -= nTopM + nBottomM;
    4910                 :            : 
    4911                 :            :                             //  Rotation schon hier, um bei Umbruch auch PaperSize anzupassen
    4912                 :        661 :                             long nAttrRotate = 0;
    4913                 :        661 :                             double nSin = 0.0;
    4914                 :        661 :                             double nCos = 1.0;
    4915                 :        661 :                             SvxRotateMode eRotMode = SVX_ROTATE_MODE_STANDARD;
    4916         [ +  - ]:        661 :                             if ( eOrient == SVX_ORIENTATION_STANDARD )
    4917                 :            :                             {
    4918                 :            :                                 nAttrRotate = ((const SfxInt32Item&)pPattern->
    4919         [ +  - ]:        661 :                                                     GetItem(ATTR_ROTATE_VALUE, pCondSet)).GetValue();
    4920         [ +  - ]:        661 :                                 if ( nAttrRotate )
    4921                 :            :                                 {
    4922                 :            :                                     eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
    4923         [ +  - ]:        661 :                                                 pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
    4924                 :            : 
    4925         [ -  + ]:        661 :                                     if ( nAttrRotate == 18000 )
    4926                 :          0 :                                         eRotMode = SVX_ROTATE_MODE_STANDARD;    // keinen Ueberlauf
    4927                 :            : 
    4928         [ -  + ]:        661 :                                     if ( bLayoutRTL )
    4929                 :          0 :                                         nAttrRotate = -nAttrRotate;
    4930                 :            : 
    4931                 :        661 :                                     double nRealOrient = nAttrRotate * F_PI18000;   // 1/100 Grad
    4932                 :        661 :                                     nCos = cos( nRealOrient );
    4933                 :        661 :                                     nSin = sin( nRealOrient );
    4934                 :            :                                 }
    4935                 :            :                             }
    4936                 :            : 
    4937                 :        661 :                             Size aPaperSize = Size( 1000000, 1000000 );
    4938         [ -  + ]:        661 :                             if (eOrient==SVX_ORIENTATION_STACKED)
    4939                 :          0 :                                 aPaperSize.Width() = nOutWidth;             // zum Zentrieren
    4940         [ +  + ]:        661 :                             else if (bBreak)
    4941                 :            :                             {
    4942         [ +  - ]:        570 :                                 if (nAttrRotate)
    4943                 :            :                                 {
    4944                 :            :                                     //! richtige PaperSize fuer Umbruch haengt von der Zeilenzahl
    4945                 :            :                                     //! ab, solange die Zeilen nicht einzeln versetzt ausgegeben
    4946                 :            :                                     //! werden koennen -> darum unbegrenzt, also kein Umbruch.
    4947                 :            :                                     //! Mit versetzten Zeilen waere das folgende richtig:
    4948                 :        570 :                                     aPaperSize.Width() = (long)(nOutHeight / fabs(nSin));
    4949                 :            :                                 }
    4950         [ #  # ]:          0 :                                 else if (eOrient == SVX_ORIENTATION_STANDARD)
    4951                 :          0 :                                     aPaperSize.Width() = nOutWidth;
    4952                 :            :                                 else
    4953                 :          0 :                                     aPaperSize.Width() = nOutHeight - 1;
    4954                 :            :                             }
    4955         [ +  - ]:        661 :                             if (bPixelToLogic)
    4956 [ +  - ][ +  - ]:        661 :                                 pEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
    4957                 :            :                             else
    4958         [ #  # ]:          0 :                                 pEngine->SetPaperSize(aPaperSize);  // Scale ist immer 1
    4959                 :            : 
    4960                 :            :                             //  Daten aus Zelle lesen
    4961                 :            : 
    4962         [ +  - ]:        661 :                             if (pCell)
    4963                 :            :                             {
    4964         [ +  + ]:        661 :                                 if (pCell->GetCellType() == CELLTYPE_EDIT)
    4965                 :            :                                 {
    4966                 :            :                                     const EditTextObject* pData;
    4967         [ +  - ]:         84 :                                     ((ScEditCell*)pCell)->GetData(pData);
    4968                 :            : 
    4969         [ +  - ]:         84 :                                     if (pData)
    4970         [ +  - ]:         84 :                                         pEngine->SetText(*pData);
    4971                 :            :                                     else
    4972                 :            :                                     {
    4973                 :            :                                         OSL_FAIL("pData == 0");
    4974                 :            :                                     }
    4975                 :            :                                 }
    4976                 :            :                                 else
    4977                 :            :                                 {
    4978                 :            :                                     sal_uLong nFormat = pPattern->GetNumberFormat(
    4979 [ +  - ][ +  - ]:        577 :                                                                 mpDoc->GetFormatTable(), pCondSet );
    4980                 :        577 :                                     rtl::OUString aString;
    4981                 :            :                                     Color* pColor;
    4982                 :            :                                     ScCellFormat::GetString( pCell,
    4983                 :            :                                                              nFormat,aString, &pColor,
    4984         [ +  - ]:        577 :                                                              *mpDoc->GetFormatTable(),
    4985                 :            :                                                              mbShowNullValues,
    4986                 :            :                                                              mbShowFormulas,
    4987         [ +  - ]:        577 :                                                              ftCheck );
    4988                 :            : 
    4989 [ +  - ][ +  - ]:        577 :                                     pEngine->SetText(aString);
                 [ +  - ]
    4990 [ -  + ][ #  # ]:        577 :                                     if ( pColor && !mbSyntaxMode && !( mbUseStyleColor && mbForceAutoColor ) )
         [ #  # ][ #  # ]
    4991         [ #  # ]:        577 :                                         lcl_SetEditColor( *pEngine, *pColor );
    4992                 :            :                                 }
    4993                 :            : 
    4994         [ -  + ]:        661 :                                 if ( mbSyntaxMode )
    4995         [ #  # ]:          0 :                                     SetEditSyntaxColor( *pEngine, pCell );
    4996 [ +  - ][ -  + ]:        661 :                                 else if ( mbUseStyleColor && mbForceAutoColor )
    4997         [ #  # ]:          0 :                                     lcl_SetEditColor( *pEngine, COL_AUTO );     //! or have a flag at EditEngine
    4998                 :            :                             }
    4999                 :            :                             else
    5000                 :            :                             {
    5001                 :            :                                 OSL_FAIL("pCell == NULL");
    5002                 :            :                             }
    5003                 :            : 
    5004         [ +  - ]:        661 :                             pEngine->SetUpdateMode( sal_True );     // after SetText, before CalcTextWidth/GetTextHeight
    5005                 :            : 
    5006         [ +  - ]:        661 :                             long nEngineWidth  = (long) pEngine->CalcTextWidth();
    5007         [ +  - ]:        661 :                             long nEngineHeight = pEngine->GetTextHeight();
    5008                 :            : 
    5009 [ +  - ][ +  + ]:        661 :                             if (nAttrRotate && bBreak)
    5010                 :            :                             {
    5011                 :        570 :                                 double nAbsCos = fabs( nCos );
    5012                 :        570 :                                 double nAbsSin = fabs( nSin );
    5013                 :            : 
    5014                 :            :                                 // adjust witdh of papersize for height of text
    5015                 :        570 :                                 int nSteps = 5;
    5016         [ +  + ]:       1335 :                                 while (nSteps > 0)
    5017                 :            :                                 {
    5018                 :            :                                     // everything is in pixels
    5019                 :            :                                     long nEnginePixel = mpRefDevice->LogicToPixel(
    5020         [ +  - ]:        765 :                                                             Size(0,nEngineHeight)).Height();
    5021                 :        765 :                                     long nEffHeight = nOutHeight - (long)(nEnginePixel * nAbsCos) + 2;
    5022                 :        765 :                                     long nNewWidth = (long)(nEffHeight / nAbsSin) + 2;
    5023                 :        765 :                                     sal_Bool bFits = ( nNewWidth >= aPaperSize.Width() );
    5024         [ +  + ]:        765 :                                     if ( bFits )
    5025                 :        570 :                                         nSteps = 0;
    5026                 :            :                                     else
    5027                 :            :                                     {
    5028         [ -  + ]:        195 :                                         if ( nNewWidth < 4 )
    5029                 :            :                                         {
    5030                 :            :                                             // can't fit -> fall back to using half height
    5031                 :          0 :                                             nEffHeight = nOutHeight / 2;
    5032                 :          0 :                                             nNewWidth = (long)(nEffHeight / nAbsSin) + 2;
    5033                 :          0 :                                             nSteps = 0;
    5034                 :            :                                         }
    5035                 :            :                                         else
    5036                 :        195 :                                             --nSteps;
    5037                 :            : 
    5038                 :            :                                         // set paper width and get new text height
    5039                 :        195 :                                         aPaperSize.Width() = nNewWidth;
    5040         [ +  - ]:        195 :                                         if (bPixelToLogic)
    5041 [ +  - ][ +  - ]:        195 :                                             pEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
    5042                 :            :                                         else
    5043         [ #  # ]:          0 :                                             pEngine->SetPaperSize(aPaperSize);  // Scale ist immer 1
    5044                 :            :                                         //pEngine->QuickFormatDoc( sal_True );
    5045         [ +  - ]:        195 :                                         nEngineWidth  = (long) pEngine->CalcTextWidth();
    5046         [ +  - ]:        195 :                                         nEngineHeight = pEngine->GetTextHeight();
    5047                 :            :                                     }
    5048                 :            :                                 }
    5049                 :            :                             }
    5050                 :            : 
    5051                 :        661 :                             long nRealWidth  = nEngineWidth;
    5052                 :        661 :                             long nRealHeight = nEngineHeight;
    5053                 :            : 
    5054                 :            :                             //  wenn gedreht, Groesse anpassen
    5055         [ +  - ]:        661 :                             if (nAttrRotate)
    5056                 :            :                             {
    5057                 :        661 :                                 double nAbsCos = fabs( nCos );
    5058                 :        661 :                                 double nAbsSin = fabs( nSin );
    5059                 :            : 
    5060         [ +  - ]:        661 :                                 if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
    5061                 :            :                                     nEngineWidth = (long) ( nRealWidth * nAbsCos +
    5062                 :        661 :                                                             nRealHeight * nAbsSin );
    5063                 :            :                                 else
    5064                 :          0 :                                     nEngineWidth = (long) ( nRealHeight / nAbsSin );
    5065                 :            :                                 //! begrenzen !!!
    5066                 :            : 
    5067                 :            :                                 nEngineHeight = (long) ( nRealHeight * nAbsCos +
    5068                 :        661 :                                                          nRealWidth * nAbsSin );
    5069                 :            :                             }
    5070                 :            : 
    5071         [ -  + ]:        661 :                             if (!nAttrRotate)           //  hier nur gedrehter Text
    5072                 :          0 :                                 bHidden = sal_True;         //! vorher abfragen !!!
    5073                 :            : 
    5074                 :            :                             //! weglassen, was nicht hereinragt
    5075                 :            : 
    5076         [ +  - ]:        661 :                             if (!bHidden)
    5077                 :            :                             {
    5078                 :        661 :                                 sal_Bool bClip = false;
    5079                 :        661 :                                 Size aClipSize = Size( nScrX+nScrW-nStartX, nScrY+nScrH-nStartY );
    5080                 :            : 
    5081                 :            :                                 //  weiterschreiben
    5082                 :            : 
    5083                 :        661 :                                 Size aCellSize;
    5084         [ +  - ]:        661 :                                 if (bPixelToLogic)
    5085         [ +  - ]:        661 :                                     aCellSize = mpRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
    5086                 :            :                                 else
    5087                 :          0 :                                     aCellSize = Size( nOutWidth, nOutHeight );  // Scale ist 1
    5088                 :            : 
    5089                 :        661 :                                 long nGridWidth = nEngineWidth;
    5090                 :        661 :                                 sal_Bool bNegative = false;
    5091         [ -  + ]:        661 :                                 if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
    5092                 :            :                                 {
    5093                 :          0 :                                     nGridWidth = aCellSize.Width() +
    5094                 :          0 :                                             Abs((long) ( aCellSize.Height() * nCos / nSin ));
    5095                 :          0 :                                     bNegative = ( pInfo->nRotateDir == SC_ROTDIR_LEFT );
    5096         [ #  # ]:          0 :                                     if ( bLayoutRTL )
    5097                 :          0 :                                         bNegative = !bNegative;
    5098                 :            :                                 }
    5099                 :            : 
    5100                 :            :                                 // use GetOutputArea to hide the grid
    5101                 :            :                                 // (clip region is done manually below)
    5102         [ +  - ]:        661 :                                 OutputAreaParam aAreaParam;
    5103                 :            : 
    5104                 :        661 :                                 SCCOL nCellX = nX;
    5105                 :        661 :                                 SCROW nCellY = nY;
    5106                 :        661 :                                 SvxCellHorJustify eOutHorJust = eHorJust;
    5107         [ -  + ]:        661 :                                 if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
    5108         [ #  # ]:          0 :                                     eOutHorJust = bNegative ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT;
    5109                 :        661 :                                 long nNeededWidth = nGridWidth;     // in pixel for GetOutputArea
    5110         [ +  - ]:        661 :                                 if ( bPixelToLogic )
    5111         [ +  - ]:        661 :                                     nNeededWidth =  mpRefDevice->LogicToPixel(Size(nNeededWidth,0)).Width();
    5112                 :            : 
    5113                 :            :                                 GetOutputArea( nX, nArrY, nCellStartX, nPosY, nCellX, nCellY, nNeededWidth,
    5114                 :        661 :                                                 *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
    5115         [ +  - ]:        661 :                                                 false, false, sal_True, aAreaParam );
    5116                 :            : 
    5117         [ +  + ]:        661 :                                 if ( bShrink )
    5118                 :            :                                 {
    5119                 :            :                                     long nPixelWidth = bPixelToLogic ?
    5120 [ +  - ][ +  - ]:         91 :                                         mpRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width() : nEngineWidth;
         [ +  - ][ +  - ]
           [ #  #  #  # ]
    5121                 :         91 :                                     long nNeededPixel = nPixelWidth + nLeftM + nRightM;
    5122                 :            : 
    5123                 :         91 :                                     aAreaParam.mbLeftClip = aAreaParam.mbRightClip = sal_True;
    5124                 :            : 
    5125                 :            :                                     // always do height
    5126                 :            :                                     ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM,
    5127                 :         91 :                                         false, sal::static_int_cast<sal_uInt16>(eOrient), nAttrRotate, bPixelToLogic,
    5128         [ +  - ]:         91 :                                         nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
    5129                 :            : 
    5130         [ +  - ]:         91 :                                     if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
    5131                 :            :                                     {
    5132                 :            :                                         // do width only if rotating within the cell (standard mode)
    5133                 :            :                                         ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM,
    5134                 :         91 :                                             sal_True, sal::static_int_cast<sal_uInt16>(eOrient), nAttrRotate, bPixelToLogic,
    5135         [ +  - ]:         91 :                                             nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
    5136                 :            :                                     }
    5137                 :            : 
    5138                 :            :                                     // nEngineWidth/nEngineHeight is updated in ShrinkEditEngine
    5139                 :            :                                     // (but width is only valid for standard mode)
    5140         [ +  - ]:         91 :                                     nRealWidth  = (long) pEngine->CalcTextWidth();
    5141         [ +  - ]:         91 :                                     nRealHeight = pEngine->GetTextHeight();
    5142                 :            : 
    5143         [ -  + ]:         91 :                                     if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
    5144                 :         91 :                                         nEngineWidth = (long) ( nRealHeight / fabs( nSin ) );
    5145                 :            :                                 }
    5146                 :            : 
    5147                 :        661 :                                 long nClipStartX = nStartX;
    5148         [ -  + ]:        661 :                                 if (nX<nX1)
    5149                 :            :                                 {
    5150                 :            :                                     //! Clipping unnoetig, wenn links am Fenster
    5151                 :            : 
    5152                 :          0 :                                     bClip = sal_True;                   // nur Rest ausgeben!
    5153         [ #  # ]:          0 :                                     if (nStartX<nScrX)
    5154                 :            :                                     {
    5155                 :          0 :                                         long nDif = nScrX - nStartX;
    5156                 :          0 :                                         nClipStartX = nScrX;
    5157                 :          0 :                                         aClipSize.Width() -= nDif;
    5158                 :            :                                     }
    5159                 :            :                                 }
    5160                 :            : 
    5161                 :        661 :                                 long nClipStartY = nStartY;
    5162 [ +  - ][ -  + ]:        661 :                                 if (nArrY==0 || bVisChanged)
    5163                 :            :                                 {
    5164         [ #  # ]:          0 :                                     if ( nClipStartY < nRowPosY )
    5165                 :            :                                     {
    5166                 :          0 :                                         long nDif = nRowPosY - nClipStartY;
    5167                 :          0 :                                         bClip = sal_True;
    5168                 :          0 :                                         nClipStartY = nRowPosY;
    5169                 :          0 :                                         aClipSize.Height() -= nDif;
    5170                 :            :                                     }
    5171                 :            :                                 }
    5172                 :            : 
    5173                 :        661 :                                 bClip = sal_True;       // always clip at the window/page border
    5174                 :            : 
    5175                 :            :                                 //Rectangle aClipRect;
    5176         [ +  - ]:        661 :                                 if (bClip)
    5177                 :            :                                 {
    5178         [ +  - ]:        661 :                                     if ( nAttrRotate /* && eRotMode != SVX_ROTATE_MODE_STANDARD */ )
    5179                 :            :                                     {
    5180                 :            :                                         //  gedrehten, ausgerichteten Text nur an den
    5181                 :            :                                         //  Seitengrenzen clippen
    5182                 :        661 :                                         nClipStartX = nScrX;
    5183                 :        661 :                                         aClipSize.Width() = nScrW;
    5184                 :            :                                     }
    5185                 :            : 
    5186         [ +  - ]:        661 :                                     if (bPixelToLogic)
    5187                 :            :                                         aAreaParam.maClipRect = mpRefDevice->PixelToLogic( Rectangle(
    5188 [ +  - ][ +  - ]:        661 :                                                         Point(nClipStartX,nClipStartY), aClipSize ) );
    5189                 :            :                                     else
    5190                 :            :                                         aAreaParam.maClipRect = Rectangle(Point(nClipStartX, nClipStartY),
    5191         [ #  # ]:          0 :                                                                 aClipSize );    // Scale = 1
    5192                 :            : 
    5193         [ -  + ]:        661 :                                     if (bMetaFile)
    5194                 :            :                                     {
    5195         [ #  # ]:          0 :                                         mpDev->Push();
    5196         [ #  # ]:          0 :                                         mpDev->IntersectClipRegion( aAreaParam.maClipRect );
    5197                 :            :                                     }
    5198                 :            :                                     else
    5199 [ +  - ][ +  - ]:        661 :                                         mpDev->SetClipRegion( Region( aAreaParam.maClipRect ) );
                 [ +  - ]
    5200                 :            :                                 }
    5201                 :            : 
    5202                 :        661 :                                 Point aLogicStart;
    5203         [ +  - ]:        661 :                                 if (bPixelToLogic)
    5204         [ +  - ]:        661 :                                     aLogicStart = mpRefDevice->PixelToLogic( Point(nStartX,nStartY) );
    5205                 :            :                                 else
    5206                 :          0 :                                     aLogicStart = Point(nStartX, nStartY);
    5207 [ +  - ][ +  + ]:        661 :                                 if ( eOrient!=SVX_ORIENTATION_STANDARD || !bBreak )
    5208                 :            :                                 {
    5209                 :         91 :                                     long nAvailWidth = aCellSize.Width();
    5210 [ +  - ][ +  - ]:         91 :                                     if (eType==OUTTYPE_WINDOW &&
         [ -  + ][ +  - ]
    5211                 :            :                                             eOrient!=SVX_ORIENTATION_STACKED &&
    5212                 :            :                                             pInfo && pInfo->bAutoFilter)
    5213                 :            :                                     {
    5214                 :            :                                         // filter drop-down width is now independent from row height
    5215         [ #  # ]:          0 :                                         if (bPixelToLogic)
    5216         [ #  # ]:          0 :                                             nAvailWidth -= mpRefDevice->PixelToLogic(Size(0,DROPDOWN_BITMAP_SIZE)).Height();
    5217                 :            :                                         else
    5218                 :          0 :                                             nAvailWidth -= DROPDOWN_BITMAP_SIZE;
    5219                 :          0 :                                         long nComp = nEngineWidth;
    5220         [ #  # ]:          0 :                                         if (nAvailWidth<nComp) nAvailWidth=nComp;
    5221                 :            :                                     }
    5222                 :            : 
    5223                 :            :                                     //  horizontale Ausrichtung
    5224                 :            : 
    5225 [ +  - ][ -  + ]:         91 :                                     if (eOrient==SVX_ORIENTATION_STANDARD && !nAttrRotate)
    5226                 :            :                                     {
    5227 [ #  # ][ #  # ]:          0 :                                         if (eHorJust==SVX_HOR_JUSTIFY_RIGHT ||
    5228                 :            :                                             eHorJust==SVX_HOR_JUSTIFY_CENTER)
    5229                 :            :                                         {
    5230         [ #  # ]:          0 :                                             pEngine->SetUpdateMode( false );
    5231                 :            : 
    5232                 :            :                                             SvxAdjust eSvxAdjust =
    5233                 :            :                                                 (eHorJust==SVX_HOR_JUSTIFY_RIGHT) ?
    5234         [ #  # ]:          0 :                                                     SVX_ADJUST_RIGHT : SVX_ADJUST_CENTER;
    5235                 :            :                                             pEngine->SetDefaultItem(
    5236 [ #  # ][ #  # ]:          0 :                                                 SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
                 [ #  # ]
    5237                 :            : 
    5238                 :          0 :                                             aPaperSize.Width() = nOutWidth;
    5239         [ #  # ]:          0 :                                             if (bPixelToLogic)
    5240 [ #  # ][ #  # ]:          0 :                                                 pEngine->SetPaperSize(mpRefDevice->PixelToLogic(aPaperSize));
    5241                 :            :                                             else
    5242         [ #  # ]:          0 :                                                 pEngine->SetPaperSize(aPaperSize);
    5243                 :            : 
    5244         [ #  # ]:          0 :                                             pEngine->SetUpdateMode( sal_True );
    5245                 :          0 :                                         }
    5246                 :            :                                     }
    5247                 :            :                                     else
    5248                 :            :                                     {
    5249                 :            :                                         //  bei gedrehtem Text ist Standard zentriert
    5250         [ -  + ]:         91 :                                         if (eHorJust==SVX_HOR_JUSTIFY_RIGHT)
    5251                 :          0 :                                             aLogicStart.X() += nAvailWidth - nEngineWidth;
    5252 [ -  + ][ #  # ]:         91 :                                         else if (eHorJust==SVX_HOR_JUSTIFY_CENTER ||
    5253                 :            :                                                  eHorJust==SVX_HOR_JUSTIFY_STANDARD)
    5254                 :         91 :                                             aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
    5255                 :            :                                     }
    5256                 :            :                                 }
    5257                 :            : 
    5258         [ -  + ]:        661 :                                 if ( bLayoutRTL )
    5259                 :            :                                 {
    5260         [ #  # ]:          0 :                                     if (bPixelToLogic)
    5261                 :          0 :                                         aLogicStart.X() -= mpRefDevice->PixelToLogic(
    5262         [ #  # ]:          0 :                                                         Size( nCellWidth, 0 ) ).Width();
    5263                 :            :                                     else
    5264                 :          0 :                                         aLogicStart.X() -= nCellWidth;
    5265                 :            :                                 }
    5266                 :            : 
    5267 [ -  + ][ #  # ]:        661 :                                 if ( eOrient==SVX_ORIENTATION_STANDARD ||
                 [ #  # ]
    5268                 :            :                                      eOrient==SVX_ORIENTATION_STACKED || !bBreak )
    5269                 :            :                                 {
    5270 [ +  - ][ +  - ]:        661 :                                     if (eVerJust==SVX_VER_JUSTIFY_BOTTOM ||
    5271                 :            :                                         eVerJust==SVX_VER_JUSTIFY_STANDARD)
    5272                 :            :                                     {
    5273         [ +  - ]:       1322 :                                         if (bPixelToLogic)
    5274                 :        661 :                                             aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0,
    5275         [ +  - ]:       1322 :                                                             mpRefDevice->LogicToPixel(aCellSize).Height() -
    5276         [ +  - ]:        661 :                                                             mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
    5277         [ +  - ]:        661 :                                                             )).Height();
    5278                 :            :                                         else
    5279                 :          0 :                                             aLogicStart.Y() += aCellSize.Height() - nEngineHeight;
    5280                 :            :                                     }
    5281                 :            : 
    5282         [ #  # ]:          0 :                                     else if (eVerJust==SVX_VER_JUSTIFY_CENTER)
    5283                 :            :                                     {
    5284         [ #  # ]:          0 :                                         if (bPixelToLogic)
    5285                 :          0 :                                             aLogicStart.Y() += mpRefDevice->PixelToLogic( Size(0,(
    5286         [ #  # ]:          0 :                                                             mpRefDevice->LogicToPixel(aCellSize).Height() -
    5287         [ #  # ]:          0 :                                                             mpRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height())
    5288         [ #  # ]:          0 :                                                             / 2)).Height();
    5289                 :            :                                         else
    5290                 :          0 :                                             aLogicStart.Y() += (aCellSize.Height() - nEngineHeight) / 2;
    5291                 :            :                                     }
    5292                 :            :                                 }
    5293                 :            : 
    5294                 :            :                                 // TOPBOTTON and BOTTOMTOP are handled in DrawStrings/DrawEdit
    5295                 :            :                                 OSL_ENSURE( eOrient == SVX_ORIENTATION_STANDARD && nAttrRotate,
    5296                 :            :                                             "DrawRotated: no rotation" );
    5297                 :            : 
    5298                 :        661 :                                 long nOriVal = 0;
    5299         [ +  - ]:        661 :                                 if ( nAttrRotate )
    5300                 :            :                                 {
    5301                 :            :                                     // Attribut ist 1/100, Font 1/10 Grad
    5302                 :        661 :                                     nOriVal = nAttrRotate / 10;
    5303                 :            : 
    5304                 :        661 :                                     double nAddX = 0.0;
    5305                 :        661 :                                     double nAddY = 0.0;
    5306 [ +  - ][ -  + ]:        661 :                                     if ( nCos > 0.0 && eRotMode != SVX_ROTATE_MODE_STANDARD )
    5307                 :            :                                     {
    5308                 :            :                                         //! begrenzen !!!
    5309                 :          0 :                                         double nH = nRealHeight * nCos;
    5310                 :          0 :                                         nAddX += nH * ( nCos / fabs(nSin) );
    5311                 :            :                                     }
    5312 [ -  + ][ #  # ]:        661 :                                     if ( nCos < 0.0 && eRotMode == SVX_ROTATE_MODE_STANDARD )
    5313                 :          0 :                                         nAddX -= nRealWidth * nCos;
    5314         [ +  + ]:        661 :                                     if ( nSin < 0.0 )
    5315                 :        466 :                                         nAddX -= nRealHeight * nSin;
    5316         [ +  + ]:        661 :                                     if ( nSin > 0.0 )
    5317                 :        195 :                                         nAddY += nRealWidth * nSin;
    5318         [ -  + ]:        661 :                                     if ( nCos < 0.0 )
    5319                 :          0 :                                         nAddY -= nRealHeight * nCos;
    5320                 :            : 
    5321         [ -  + ]:        661 :                                     if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
    5322                 :            :                                     {
    5323                 :            :                                         //! begrenzen !!!
    5324                 :          0 :                                         double nSkew = nTotalHeight * nCos / fabs(nSin);
    5325         [ #  # ]:          0 :                                         if ( eRotMode == SVX_ROTATE_MODE_CENTER )
    5326                 :          0 :                                             nAddX -= nSkew * 0.5;
    5327 [ #  # ][ #  # ]:          0 :                                         if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nSin > 0.0 ) ||
         [ #  # ][ #  # ]
    5328                 :            :                                              ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nSin < 0.0 ) )
    5329                 :          0 :                                             nAddX -= nSkew;
    5330                 :            : 
    5331                 :          0 :                                         long nUp = 0;
    5332         [ #  # ]:          0 :                                         if ( eVerJust == SVX_VER_JUSTIFY_CENTER )
    5333                 :          0 :                                             nUp = ( aCellSize.Height() - nEngineHeight ) / 2;
    5334         [ #  # ]:          0 :                                         else if ( eVerJust == SVX_VER_JUSTIFY_TOP )
    5335                 :            :                                         {
    5336         [ #  # ]:          0 :                                             if ( nSin > 0.0 )
    5337                 :          0 :                                                 nUp = aCellSize.Height() - nEngineHeight;
    5338                 :            :                                         }
    5339                 :            :                                         else    // BOTTOM / STANDARD
    5340                 :            :                                         {
    5341         [ #  # ]:          0 :                                             if ( nSin < 0.0 )
    5342                 :          0 :                                                 nUp = aCellSize.Height() - nEngineHeight;
    5343                 :            :                                         }
    5344         [ #  # ]:          0 :                                         if ( nUp )
    5345                 :          0 :                                             nAddX += ( nUp * nCos / fabs(nSin) );
    5346                 :            :                                     }
    5347                 :            : 
    5348                 :        661 :                                     aLogicStart.X() += (long) nAddX;
    5349                 :        661 :                                     aLogicStart.Y() += (long) nAddY;
    5350                 :            :                                 }
    5351                 :            : 
    5352                 :            :                                 //  bSimClip is not used here (because nOriVal is set)
    5353                 :            : 
    5354 [ +  - ][ -  + ]:        661 :                                 if ( pEngine->IsRightToLeft( 0 ) )
    5355                 :            :                                 {
    5356                 :            :                                     //  For right-to-left, EditEngine always calculates its lines
    5357                 :            :                                     //  beginning from the right edge, but EditLine::nStartPosX is
    5358                 :            :                                     //  of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
    5359         [ #  # ]:          0 :                                     Size aLogicPaper = pEngine->GetPaperSize();
    5360         [ #  # ]:          0 :                                     if ( aLogicPaper.Width() > USHRT_MAX )
    5361                 :            :                                     {
    5362                 :          0 :                                         aLogicPaper.Width() = USHRT_MAX;
    5363         [ #  # ]:          0 :                                         pEngine->SetPaperSize(aLogicPaper);
    5364                 :            :                                     }
    5365                 :            :                                 }
    5366                 :            : 
    5367         [ +  - ]:        661 :                                 pEngine->Draw( mpDev, aLogicStart, (short)nOriVal );
    5368                 :            : 
    5369         [ +  - ]:        661 :                                 if (bClip)
    5370                 :            :                                 {
    5371         [ -  + ]:        661 :                                     if (bMetaFile)
    5372         [ #  # ]:          0 :                                         mpDev->Pop();
    5373                 :            :                                     else
    5374         [ +  - ]:        661 :                                         mpDev->SetClipRegion();
    5375                 :            :                                 }
    5376                 :            :                             }
    5377                 :            :                         }
    5378                 :            :                     }
    5379                 :            :                 }
    5380                 :       3660 :                 nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
    5381                 :            :             }
    5382                 :            :         }
    5383                 :        538 :         nRowPosY += pRowInfo[nArrY].nHeight;
    5384                 :            :     }
    5385                 :            : 
    5386 [ +  - ][ +  - ]:         99 :     delete pEngine;
    5387                 :         99 : }
    5388                 :            : 
    5389                 :            : 
    5390                 :            : 
    5391                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10