LCOV - code coverage report
Current view: top level - sc/source/ui/view - output.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 594 1360 43.7 %
Date: 2015-06-13 12:38:46 Functions: 35 51 68.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/embed/EmbedMisc.hpp>
      21             : 
      22             : #include "scitems.hxx"
      23             : #include <editeng/boxitem.hxx>
      24             : #include <editeng/brushitem.hxx>
      25             : #include <editeng/editdata.hxx>
      26             : #include <svtools/colorcfg.hxx>
      27             : #include <svx/rotmodit.hxx>
      28             : #include <editeng/shaditem.hxx>
      29             : #include <editeng/svxfont.hxx>
      30             : #include <svx/svdoole2.hxx>
      31             : #include <tools/poly.hxx>
      32             : #include <vcl/svapp.hxx>
      33             : #include <vcl/pdfextoutdevdata.hxx>
      34             : #include <svtools/accessibilityoptions.hxx>
      35             : #include <svx/framelinkarray.hxx>
      36             : #include <drawinglayer/geometry/viewinformation2d.hxx>
      37             : #include <drawinglayer/processor2d/baseprocessor2d.hxx>
      38             : #include <basegfx/matrix/b2dhommatrix.hxx>
      39             : #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
      40             : #include <vcl/lineinfo.hxx>
      41             : #include <vcl/gradient.hxx>
      42             : #include <vcl/settings.hxx>
      43             : #include <svx/unoapi.hxx>
      44             : 
      45             : #include "output.hxx"
      46             : #include "document.hxx"
      47             : #include "drwlayer.hxx"
      48             : #include "formulacell.hxx"
      49             : #include "attrib.hxx"
      50             : #include "patattr.hxx"
      51             : #include "docpool.hxx"
      52             : #include "tabvwsh.hxx"
      53             : #include "progress.hxx"
      54             : #include "pagedata.hxx"
      55             : #include "chgtrack.hxx"
      56             : #include "chgviset.hxx"
      57             : #include "viewutil.hxx"
      58             : #include "gridmerg.hxx"
      59             : #include "invmerge.hxx"
      60             : #include "fillinfo.hxx"
      61             : #include "scmod.hxx"
      62             : #include "appoptio.hxx"
      63             : #include "postit.hxx"
      64             : 
      65             : #include "scresid.hxx"
      66             : #include "colorscale.hxx"
      67             : 
      68             : #include <math.h>
      69             : #include <map>
      70             : #include <utility>
      71             : #include <iostream>
      72             : #include <boost/scoped_ptr.hpp>
      73             : 
      74             : using namespace com::sun::star;
      75             : 
      76             : // Static Data
      77             : 
      78             : // color for ChangeTracking "by author" as in the writer (swmodul1.cxx)
      79             : 
      80             : #define SC_AUTHORCOLORCOUNT     9
      81             : 
      82             : static const ColorData nAuthorColor[ SC_AUTHORCOLORCOUNT ] = {
      83             :                     COL_LIGHTRED,       COL_LIGHTBLUE,      COL_LIGHTMAGENTA,
      84             :                     COL_GREEN,          COL_RED,            COL_BLUE,
      85             :                     COL_BROWN,          COL_MAGENTA,        COL_CYAN };
      86             : 
      87             : // Helper class for color assignment to avoid repeated lookups for the same user
      88             : 
      89           0 : ScActionColorChanger::ScActionColorChanger( const ScChangeTrack& rTrack ) :
      90           0 :     rOpt( SC_MOD()->GetAppOptions() ),
      91           0 :     rUsers( rTrack.GetUserCollection() ),
      92             :     nLastUserIndex( 0 ),
      93           0 :     nColor( COL_BLACK )
      94             : {
      95           0 : }
      96             : 
      97           0 : void ScActionColorChanger::Update( const ScChangeAction& rAction )
      98             : {
      99             :     ColorData nSetColor;
     100           0 :     switch (rAction.GetType())
     101             :     {
     102             :         case SC_CAT_INSERT_COLS:
     103             :         case SC_CAT_INSERT_ROWS:
     104             :         case SC_CAT_INSERT_TABS:
     105           0 :             nSetColor = rOpt.GetTrackInsertColor();
     106           0 :             break;
     107             :         case SC_CAT_DELETE_COLS:
     108             :         case SC_CAT_DELETE_ROWS:
     109             :         case SC_CAT_DELETE_TABS:
     110           0 :             nSetColor = rOpt.GetTrackDeleteColor();
     111           0 :             break;
     112             :         case SC_CAT_MOVE:
     113           0 :             nSetColor = rOpt.GetTrackMoveColor();
     114           0 :             break;
     115             :         default:
     116           0 :             nSetColor = rOpt.GetTrackContentColor();
     117           0 :             break;
     118             :     }
     119           0 :     if ( nSetColor != COL_TRANSPARENT )     // color assigned
     120           0 :         nColor = nSetColor;
     121             :     else                                    // by author
     122             :     {
     123           0 :         if (!aLastUserName.equals(rAction.GetUser()))
     124             :         {
     125           0 :             aLastUserName = rAction.GetUser();
     126           0 :             std::set<OUString>::const_iterator it = rUsers.find(aLastUserName);
     127           0 :             if (it == rUsers.end())
     128             :             {
     129             :                 // empty string is possible if a name wasn't found while saving a 5.0 file
     130             :                 SAL_INFO_IF( aLastUserName.isEmpty(), "sc.ui", "Author not found" );
     131           0 :                 nLastUserIndex = 0;
     132             :             }
     133             :             else
     134             :             {
     135           0 :                 size_t nPos = std::distance(rUsers.begin(), it);
     136           0 :                 nLastUserIndex = nPos % SC_AUTHORCOLORCOUNT;
     137             :             }
     138             :         }
     139           0 :         nColor = nAuthorColor[nLastUserIndex];
     140             :     }
     141           0 : }
     142             : 
     143       10483 : ScOutputData::ScOutputData( OutputDevice* pNewDev, ScOutputType eNewType,
     144             :                             ScTableInfo& rTabInfo, ScDocument* pNewDoc,
     145             :                             SCTAB nNewTab, long nNewScrX, long nNewScrY,
     146             :                             SCCOL nNewX1, SCROW nNewY1, SCCOL nNewX2, SCROW nNewY2,
     147             :                             double nPixelPerTwipsX, double nPixelPerTwipsY,
     148             :                             const Fraction* pZoomX, const Fraction* pZoomY ) :
     149             :     mpDev( pNewDev ),
     150             :     mpRefDevice( pNewDev ),      // default is output device
     151             :     pFmtDevice( pNewDev ),      // default is output device
     152             :     mrTabInfo( rTabInfo ),
     153             :     pRowInfo( rTabInfo.mpRowInfo ),
     154             :     nArrCount( rTabInfo.mnArrCount ),
     155             :     mpDoc( pNewDoc ),
     156             :     nTab( nNewTab ),
     157             :     nScrX( nNewScrX ),
     158             :     nScrY( nNewScrY ),
     159             :     nX1( nNewX1 ),
     160             :     nY1( nNewY1 ),
     161             :     nX2( nNewX2 ),
     162             :     nY2( nNewY2 ),
     163             :     eType( eNewType ),
     164             :     mnPPTX( nPixelPerTwipsX ),
     165             :     mnPPTY( nPixelPerTwipsY ),
     166             :     pEditObj( NULL ),
     167             :     pViewShell( NULL ),
     168             :     pDrawView( NULL ), // #114135#
     169             :     bEditMode( false ),
     170             :     nEditCol( 0 ),
     171             :     nEditRow( 0 ),
     172             :     bMetaFile( false ),
     173             :     bSingleGrid( false ),
     174             :     bPagebreakMode( false ),
     175             :     bSolidBackground( false ),
     176             :     mbUseStyleColor( false ),
     177       10483 :     mbForceAutoColor( SC_MOD()->GetAccessOptions().GetIsAutomaticFontColor() ),
     178             :     mbSyntaxMode( false ),
     179             :     pValueColor( NULL ),
     180             :     pTextColor( NULL ),
     181             :     pFormulaColor( NULL ),
     182             :     aGridColor( COL_BLACK ),
     183             :     mbShowNullValues( true ),
     184             :     mbShowFormulas( false ),
     185             :     bShowSpellErrors( false ),
     186             :     bMarkClipped( false ), // sal_False for printer/metafile etc.
     187             :     bSnapPixel( false ),
     188             :     bAnyRotated( false ),
     189             :     bAnyClipped( false ),
     190             :     mpTargetPaintWindow(NULL), // #i74769# use SdrPaintWindow direct
     191       20966 :     mpSpellCheckCxt(NULL)
     192             : {
     193       10483 :     if (pZoomX)
     194       10456 :         aZoomX = *pZoomX;
     195             :     else
     196          27 :         aZoomX = Fraction(1,1);
     197       10483 :     if (pZoomY)
     198       10456 :         aZoomY = *pZoomY;
     199             :     else
     200          27 :         aZoomY = Fraction(1,1);
     201             : 
     202       10483 :     nVisX1 = nX1;
     203       10483 :     nVisY1 = nY1;
     204       10483 :     nVisX2 = nX2;
     205       10483 :     nVisY2 = nY2;
     206       10483 :     mpDoc->StripHidden( nVisX1, nVisY1, nVisX2, nVisY2, nTab );
     207             : 
     208       10483 :     nScrW = 0;
     209      106851 :     for (SCCOL nX=nVisX1; nX<=nVisX2; nX++)
     210       96368 :         nScrW += pRowInfo[0].pCellInfo[nX+1].nWidth;
     211             : 
     212       10483 :     nMirrorW = nScrW;
     213             : 
     214       10483 :     nScrH = 0;
     215      221087 :     for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
     216      210604 :         nScrH += pRowInfo[nArrY].nHeight;
     217             : 
     218       10483 :     bTabProtected = mpDoc->IsTabProtected( nTab );
     219       10483 :     nTabTextDirection = mpDoc->GetEditTextDirection( nTab );
     220       10483 :     bLayoutRTL = mpDoc->IsLayoutRTL( nTab );
     221       10483 : }
     222             : 
     223       20966 : ScOutputData::~ScOutputData()
     224             : {
     225       10483 :     delete pValueColor;
     226       10483 :     delete pTextColor;
     227       10483 :     delete pFormulaColor;
     228       10483 : }
     229             : 
     230        2964 : void ScOutputData::SetSpellCheckContext( const sc::SpellCheckContext* pCxt )
     231             : {
     232        2964 :     mpSpellCheckCxt = pCxt;
     233        2964 : }
     234             : 
     235        2964 : void ScOutputData::SetContentDevice( OutputDevice* pContentDev )
     236             : {
     237             :     // use pContentDev instead of pDev where used
     238             : 
     239        2964 :     if ( mpRefDevice == mpDev )
     240        2964 :         mpRefDevice = pContentDev;
     241        2964 :     if ( pFmtDevice == mpDev )
     242        2937 :         pFmtDevice = pContentDev;
     243        2964 :     mpDev = pContentDev;
     244        2964 : }
     245             : 
     246       10456 : void ScOutputData::SetMirrorWidth( long nNew )
     247             : {
     248       10456 :     nMirrorW = nNew;
     249       10456 : }
     250             : 
     251        2986 : void ScOutputData::SetGridColor( const Color& rColor )
     252             : {
     253        2986 :     aGridColor = rColor;
     254        2986 : }
     255             : 
     256        2964 : void ScOutputData::SetMarkClipped( bool bSet )
     257             : {
     258        2964 :     bMarkClipped = bSet;
     259        2964 : }
     260             : 
     261        2991 : void ScOutputData::SetShowNullValues( bool bSet )
     262             : {
     263        2991 :     mbShowNullValues = bSet;
     264        2991 : }
     265             : 
     266        2991 : void ScOutputData::SetShowFormulas( bool bSet )
     267             : {
     268        2991 :     mbShowFormulas = bSet;
     269        2991 : }
     270             : 
     271        2964 : void ScOutputData::SetShowSpellErrors( bool bSet )
     272             : {
     273        2964 :     bShowSpellErrors = bSet;
     274        2964 : }
     275             : 
     276           5 : void ScOutputData::SetSnapPixel( bool bSet )
     277             : {
     278           5 :     bSnapPixel = bSet;
     279           5 : }
     280             : 
     281           0 : void ScOutputData::SetEditCell( SCCOL nCol, SCROW nRow )
     282             : {
     283           0 :     nEditCol = nCol;
     284           0 :     nEditRow = nRow;
     285           0 :     bEditMode = true;
     286           0 : }
     287             : 
     288           5 : void ScOutputData::SetMetaFileMode( bool bNewMode )
     289             : {
     290           5 :     bMetaFile = bNewMode;
     291           5 : }
     292             : 
     293           0 : void ScOutputData::SetSingleGrid( bool bNewMode )
     294             : {
     295           0 :     bSingleGrid = bNewMode;
     296           0 : }
     297             : 
     298        2964 : void ScOutputData::SetSyntaxMode( bool bNewMode )
     299             : {
     300        2964 :     mbSyntaxMode = bNewMode;
     301        2964 :     if (bNewMode)
     302           0 :         if (!pValueColor)
     303             :         {
     304           0 :             pValueColor = new Color( COL_LIGHTBLUE );
     305           0 :             pTextColor = new Color( COL_BLACK );
     306           0 :             pFormulaColor = new Color( COL_GREEN );
     307             :         }
     308        2964 : }
     309             : 
     310        2964 : void ScOutputData::DrawGrid(vcl::RenderContext& rRenderContext, bool bGrid, bool bPage)
     311             : {
     312             :     SCCOL nX;
     313             :     SCROW nY;
     314             :     long nPosX;
     315             :     long nPosY;
     316             :     SCSIZE nArrY;
     317        2964 :     ScBreakType nBreak    = BREAK_NONE;
     318        2964 :     ScBreakType nBreakOld = BREAK_NONE;
     319             : 
     320             :     bool bSingle;
     321        2964 :     Color aPageColor;
     322        2964 :     Color aManualColor;
     323             : 
     324        2964 :     if (bPagebreakMode)
     325           0 :         bPage = false;          // no "normal" breaks over the whole width/height
     326             : 
     327             :     // It is a big mess to distinguish when we are using pixels and when logic
     328             :     // units for drawing.  Ultimately we want to work only in the logic units,
     329             :     // but until that happens, we need to special-case:
     330             :     // * metafile
     331             :     // * drawing to the screen - everything is internally counted in pixels there
     332        2964 :     bool bWorksInPixels = bMetaFile;
     333             : 
     334        2964 :     if ( eType == OUTTYPE_WINDOW )
     335             :     {
     336        2964 :         bWorksInPixels = true;
     337        2964 :         const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
     338        2964 :         aPageColor.SetColor( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor );
     339        2964 :         aManualColor.SetColor( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKMANUAL).nColor );
     340             :     }
     341             :     else
     342             :     {
     343           0 :         aPageColor = aGridColor;
     344           0 :         aManualColor = aGridColor;
     345             :     }
     346             : 
     347        2964 :     long nOneX = 1;
     348        2964 :     long nOneY = 1;
     349        2964 :     if (!bWorksInPixels)
     350             :     {
     351           0 :         Size aOnePixel = rRenderContext.PixelToLogic(Size(1,1));
     352           0 :         nOneX = aOnePixel.Width();
     353           0 :         nOneY = aOnePixel.Height();
     354             :     }
     355             : 
     356        2964 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
     357        2964 :     long nSignedOneX = nOneX * nLayoutSign;
     358             : 
     359        2964 :     rRenderContext.SetLineColor(aGridColor);
     360        2964 :     ScGridMerger aGrid(&rRenderContext, nOneX, nOneY);
     361             : 
     362             :     // vertical lines
     363             : 
     364        2964 :     nPosX = nScrX;
     365        2964 :     if ( bLayoutRTL )
     366           1 :         nPosX += nMirrorW - nOneX;
     367             : 
     368       25343 :     for (nX=nX1; nX<=nX2; nX++)
     369             :     {
     370       22379 :         SCCOL nXplus1 = nX+1;
     371       22379 :         SCCOL nXplus2 = nX+2;
     372       22379 :         sal_uInt16 nWidth = pRowInfo[0].pCellInfo[nXplus1].nWidth;
     373       22379 :         if (nWidth)
     374             :         {
     375       22379 :             nPosX += nWidth * nLayoutSign;
     376             : 
     377       22379 :             if ( bPage )
     378             :             {
     379             :                 //  Seitenumbrueche auch in ausgeblendeten suchen
     380       22379 :                 SCCOL nCol = nXplus1;
     381       44758 :                 while (nCol <= MAXCOL)
     382             :                 {
     383       22374 :                     nBreak = mpDoc->HasColBreak(nCol, nTab);
     384       22374 :                     bool bHidden = mpDoc->ColHidden(nCol, nTab);
     385             : 
     386       22374 :                     if ( nBreak || !bHidden )
     387             :                         break;
     388           0 :                     ++nCol;
     389             :                 }
     390             : 
     391       22379 :                 if (nBreak != nBreakOld)
     392             :                 {
     393           8 :                     aGrid.Flush();
     394           8 :                     rRenderContext.SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor :
     395           8 :                                         nBreak ? aPageColor : aGridColor );
     396           8 :                     nBreakOld = nBreak;
     397             :                 }
     398             :             }
     399             : 
     400       22379 :             bool bDraw = bGrid || nBreakOld; // simple grid only if set that way
     401             : 
     402       22379 :             sal_uInt16 nWidthXplus2 = pRowInfo[0].pCellInfo[nXplus2].nWidth;
     403       22379 :             bSingle = bSingleGrid; //! get into Fillinfo !!!!!
     404       22379 :             if ( nX<MAXCOL && !bSingle )
     405             :             {
     406       22374 :                 bSingle = ( nWidthXplus2 == 0 );
     407      227738 :                 for (nArrY=1; nArrY+1<nArrCount && !bSingle; nArrY++)
     408             :                 {
     409      205364 :                     if (pRowInfo[nArrY].pCellInfo[nXplus2].bHOverlapped)
     410          31 :                         bSingle = true;
     411      205364 :                     if (pRowInfo[nArrY].pCellInfo[nXplus1].bHideGrid)
     412           0 :                         bSingle = true;
     413             :                 }
     414             :             }
     415             : 
     416       22379 :             if (bDraw)
     417             :             {
     418       22336 :                 if ( nX<MAXCOL && bSingle )
     419             :                 {
     420          31 :                     SCCOL nVisX = nXplus1;
     421          62 :                     while ( nVisX < MAXCOL && !mpDoc->GetColWidth(nVisX,nTab) )
     422           0 :                         ++nVisX;
     423             : 
     424          31 :                     nPosY = nScrY;
     425         661 :                     for (nArrY=1; nArrY+1<nArrCount; nArrY++)
     426             :                     {
     427         630 :                         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
     428         630 :                         const long nNextY = nPosY + pThisRowInfo->nHeight;
     429             : 
     430         630 :                         bool bHOver = pThisRowInfo->pCellInfo[nXplus1].bHideGrid;
     431         630 :                         if (!bHOver)
     432             :                         {
     433         630 :                             if (nWidthXplus2)
     434         630 :                                 bHOver = pThisRowInfo->pCellInfo[nXplus2].bHOverlapped;
     435             :                             else
     436             :                             {
     437           0 :                                 if (nVisX <= nX2)
     438           0 :                                     bHOver = pThisRowInfo->pCellInfo[nVisX+1].bHOverlapped;
     439             :                                 else
     440             :                                     bHOver = static_cast<const ScMergeFlagAttr*>(mpDoc->GetAttr(
     441           0 :                                                 nVisX,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG))
     442           0 :                                                 ->IsHorOverlapped();
     443           0 :                                 if (bHOver)
     444             :                                     bHOver = static_cast<const ScMergeFlagAttr*>(mpDoc->GetAttr(
     445           0 :                                                 nXplus1,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG))
     446           0 :                                                 ->IsHorOverlapped();
     447             :                             }
     448             :                         }
     449             : 
     450         630 :                         if (pThisRowInfo->bChanged && !bHOver)
     451             :                         {
     452         531 :                             aGrid.AddVerLine(bWorksInPixels, nPosX-nSignedOneX, nPosY, nNextY-nOneY);
     453             :                         }
     454         630 :                         nPosY = nNextY;
     455          31 :                     }
     456             :                 }
     457             :                 else
     458             :                 {
     459       22305 :                     aGrid.AddVerLine(bWorksInPixels, nPosX-nSignedOneX, nScrY, nScrY+nScrH-nOneY);
     460             :                 }
     461             :             }
     462             :         }
     463             :     }
     464             : 
     465             :     // horizontal lines
     466             : 
     467        2964 :     bool bHiddenRow = true;
     468        2964 :     SCROW nHiddenEndRow = -1;
     469        2964 :     nPosY = nScrY;
     470       25913 :     for (nArrY=1; nArrY+1<nArrCount; nArrY++)
     471             :     {
     472       22949 :         SCSIZE nArrYplus1 = nArrY+1;
     473       22949 :         nY = pRowInfo[nArrY].nRowNo;
     474       22949 :         SCROW nYplus1 = nY+1;
     475       22949 :         nPosY += pRowInfo[nArrY].nHeight;
     476             : 
     477       22949 :         if (pRowInfo[nArrY].bChanged)
     478             :         {
     479       22949 :             if ( bPage )
     480             :             {
     481       23025 :                 for (SCROW i = nYplus1; i <= MAXROW; ++i)
     482             :                 {
     483       23017 :                     if (i > nHiddenEndRow)
     484        3005 :                         bHiddenRow = mpDoc->RowHidden(i, nTab, NULL, &nHiddenEndRow);
     485             :                     /* TODO: optimize the row break thing for large hidden
     486             :                      * segments where HasRowBreak() has to be called
     487             :                      * nevertheless for each row, as a row break is drawn also
     488             :                      * for hidden rows, above them. This needed to be done only
     489             :                      * once per hidden segment, maybe giving manual breaks
     490             :                      * priority. Something like GetNextRowBreak() and
     491             :                      * GetNextManualRowBreak(). */
     492       23017 :                     nBreak = mpDoc->HasRowBreak(i, nTab);
     493       23017 :                     if (!bHiddenRow || nBreak)
     494             :                         break;
     495             :                 }
     496             : 
     497       22949 :                 if (nBreakOld != nBreak)
     498             :                 {
     499           2 :                     aGrid.Flush();
     500           2 :                     rRenderContext.SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor :
     501           2 :                                         (nBreak) ? aPageColor : aGridColor );
     502           2 :                     nBreakOld = nBreak;
     503             :                 }
     504             :             }
     505             : 
     506       22949 :             bool bDraw = bGrid || nBreakOld;    // simple grid only if set so
     507             : 
     508       22949 :             bool bNextYisNextRow = (pRowInfo[nArrYplus1].nRowNo == nYplus1);
     509       22949 :             bSingle = !bNextYisNextRow;             // Hidden
     510      228492 :             for (SCCOL i=nX1; i<=nX2 && !bSingle; i++)
     511             :             {
     512      205543 :                 if (pRowInfo[nArrYplus1].pCellInfo[i+1].bVOverlapped)
     513          47 :                     bSingle = true;
     514             :             }
     515             : 
     516       22949 :             if (bDraw)
     517             :             {
     518       22823 :                 if ( bSingle && nY<MAXROW )
     519             :                 {
     520          79 :                     SCROW nVisY = pRowInfo[nArrYplus1].nRowNo;
     521             : 
     522          79 :                     nPosX = nScrX;
     523          79 :                     if ( bLayoutRTL )
     524           0 :                         nPosX += nMirrorW - nOneX;
     525             : 
     526        1030 :                     for (SCCOL i=nX1; i<=nX2; i++)
     527             :                     {
     528         951 :                         const long nNextX = nPosX + pRowInfo[0].pCellInfo[i+1].nWidth * nLayoutSign;
     529         951 :                         if (nNextX != nPosX)                                // visible
     530             :                         {
     531             :                             bool bVOver;
     532         951 :                             if ( bNextYisNextRow )
     533         645 :                                 bVOver = pRowInfo[nArrYplus1].pCellInfo[i+1].bVOverlapped;
     534             :                             else
     535             :                             {
     536             :                                 bVOver = static_cast<const ScMergeFlagAttr*>(mpDoc->GetAttr(
     537         306 :                                             i,nYplus1,nTab,ATTR_MERGE_FLAG))
     538         306 :                                             ->IsVerOverlapped()
     539         306 :                                     &&   static_cast<const ScMergeFlagAttr*>(mpDoc->GetAttr(
     540           0 :                                             i,nVisY,nTab,ATTR_MERGE_FLAG))
     541         306 :                                             ->IsVerOverlapped();
     542             :                                     //! nVisY from Array ??
     543             :                             }
     544         951 :                             if (!bVOver)
     545             :                             {
     546         840 :                                 aGrid.AddHorLine(bWorksInPixels, nPosX, nNextX-nSignedOneX, nPosY-nOneY);
     547             :                             }
     548             :                         }
     549         951 :                         nPosX = nNextX;
     550          79 :                     }
     551             :                 }
     552             :                 else
     553             :                 {
     554       22744 :                     aGrid.AddHorLine(bWorksInPixels, nScrX, nScrX+nScrW-nOneX, nPosY-nOneY);
     555             :                 }
     556             :             }
     557             :         }
     558        2964 :     }
     559        2964 : }
     560             : 
     561           0 : void ScOutputData::SetPagebreakMode( ScPageBreakData* pPageData )
     562             : {
     563           0 :     bPagebreakMode = true;
     564           0 :     if (!pPageData)
     565           0 :         return;                     // not yet initialized -> everything "not printed"
     566             : 
     567             :     // mark printed range
     568             :     // (everything in FillInfo is already initialized to sal_False)
     569             : 
     570           0 :     sal_uInt16 nRangeCount = sal::static_int_cast<sal_uInt16>(pPageData->GetCount());
     571           0 :     for (sal_uInt16 nPos=0; nPos<nRangeCount; nPos++)
     572             :     {
     573           0 :         ScRange aRange = pPageData->GetData( nPos ).GetPrintRange();
     574             : 
     575           0 :         SCCOL nStartX = std::max( aRange.aStart.Col(), nX1 );
     576           0 :         SCCOL nEndX   = std::min( aRange.aEnd.Col(),   nX2 );
     577           0 :         SCROW nStartY = std::max( aRange.aStart.Row(), nY1 );
     578           0 :         SCROW nEndY   = std::min( aRange.aEnd.Row(),   nY2 );
     579             : 
     580           0 :         for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
     581             :         {
     582           0 :             RowInfo* pThisRowInfo = &pRowInfo[nArrY];
     583           0 :             if ( pThisRowInfo->bChanged && pThisRowInfo->nRowNo >= nStartY &&
     584           0 :                                            pThisRowInfo->nRowNo <= nEndY )
     585             :             {
     586           0 :                 for (SCCOL nX=nStartX; nX<=nEndX; nX++)
     587           0 :                     pThisRowInfo->pCellInfo[nX+1].bPrinted = true;
     588             :             }
     589             :         }
     590             :     }
     591             : }
     592             : 
     593        2991 : void ScOutputData::FindRotated()
     594             : {
     595             :     //! save nRotMax
     596        2991 :     SCCOL nRotMax = nX2;
     597       32080 :     for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
     598       29089 :         if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
     599           0 :             nRotMax = pRowInfo[nRotY].nRotMaxCol;
     600             : 
     601       29089 :     for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)
     602             :     {
     603       26098 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
     604       26098 :         if ( pThisRowInfo->nRotMaxCol != SC_ROTMAX_NONE &&
     605           0 :              ( pThisRowInfo->bChanged || pRowInfo[nArrY-1].bChanged ||
     606           0 :                ( nArrY+1<nArrCount && pRowInfo[nArrY+1].bChanged ) ) )
     607             :         {
     608         661 :             SCROW nY = pThisRowInfo->nRowNo;
     609             : 
     610        6610 :             for (SCCOL nX=0; nX<=nRotMax; nX++)
     611             :             {
     612        5949 :                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
     613        5949 :                 const ScPatternAttr* pPattern = pInfo->pPatternAttr;
     614        5949 :                 const SfxItemSet* pCondSet = pInfo->pConditionSet;
     615             : 
     616        5949 :                 if ( !pPattern && !mpDoc->ColHidden(nX, nTab) )
     617             :                 {
     618           0 :                     pPattern = mpDoc->GetPattern( nX, nY, nTab );
     619           0 :                     pCondSet = mpDoc->GetCondResult( nX, nY, nTab );
     620             :                 }
     621             : 
     622        5949 :                 if ( pPattern )     // column isn't hidden
     623             :                 {
     624        5949 :                     sal_uInt8 nDir = pPattern->GetRotateDir( pCondSet );
     625        5949 :                     if (nDir != SC_ROTDIR_NONE)
     626             :                     {
     627        2632 :                         pInfo->nRotateDir = nDir;
     628        2632 :                         bAnyRotated = true;
     629             :                     }
     630             :                 }
     631             :             }
     632             :         }
     633             :     }
     634        2991 : }
     635             : 
     636           0 : static sal_uInt16 lcl_GetRotateDir( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
     637             : {
     638           0 :     const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
     639           0 :     const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
     640             : 
     641           0 :     sal_uInt16 nRet = SC_ROTDIR_NONE;
     642             : 
     643           0 :     long nAttrRotate = pPattern->GetRotateVal( pCondSet );
     644           0 :     if ( nAttrRotate )
     645             :     {
     646             :         SvxRotateMode eRotMode = (SvxRotateMode)static_cast<const SvxRotateModeItem&>(
     647           0 :                     pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
     648             : 
     649           0 :         if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
     650           0 :             nRet = SC_ROTDIR_STANDARD;
     651           0 :         else if ( eRotMode == SVX_ROTATE_MODE_CENTER )
     652           0 :             nRet = SC_ROTDIR_CENTER;
     653           0 :         else if ( eRotMode == SVX_ROTATE_MODE_TOP || eRotMode == SVX_ROTATE_MODE_BOTTOM )
     654             :         {
     655           0 :             long nRot180 = nAttrRotate % 18000;     // 1/100 degree
     656           0 :             if ( nRot180 == 9000 )
     657           0 :                 nRet = SC_ROTDIR_CENTER;
     658           0 :             else if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nRot180 < 9000 ) ||
     659           0 :                       ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nRot180 > 9000 ) )
     660           0 :                 nRet = SC_ROTDIR_LEFT;
     661             :             else
     662           0 :                 nRet = SC_ROTDIR_RIGHT;
     663             :         }
     664             :     }
     665             : 
     666           0 :     return nRet;
     667             : }
     668             : 
     669           0 : static const SvxBrushItem* lcl_FindBackground( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
     670             : {
     671           0 :     const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
     672           0 :     const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
     673             :     const SvxBrushItem* pBackground = static_cast<const SvxBrushItem*>(
     674           0 :                             &pPattern->GetItem( ATTR_BACKGROUND, pCondSet ));
     675             : 
     676           0 :     sal_uInt16 nDir = lcl_GetRotateDir( pDoc, nCol, nRow, nTab );
     677             : 
     678             :     // treat CENTER like RIGHT
     679           0 :     if ( nDir == SC_ROTDIR_RIGHT || nDir == SC_ROTDIR_CENTER )
     680             :     {
     681             :         // text goes to the right -> take background from the left
     682           0 :         while ( nCol > 0 && lcl_GetRotateDir( pDoc, nCol, nRow, nTab ) == nDir &&
     683           0 :                             pBackground->GetColor().GetTransparency() != 255 )
     684             :         {
     685           0 :             --nCol;
     686           0 :             pPattern = pDoc->GetPattern( nCol, nRow, nTab );
     687           0 :             pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
     688           0 :             pBackground = static_cast<const SvxBrushItem*>(&pPattern->GetItem( ATTR_BACKGROUND, pCondSet ));
     689             :         }
     690             :     }
     691           0 :     else if ( nDir == SC_ROTDIR_LEFT )
     692             :     {
     693             :         // text goes to the left -> take background from the right
     694           0 :         while ( nCol < MAXCOL && lcl_GetRotateDir( pDoc, nCol, nRow, nTab ) == nDir &&
     695           0 :                             pBackground->GetColor().GetTransparency() != 255 )
     696             :         {
     697           0 :             ++nCol;
     698           0 :             pPattern = pDoc->GetPattern( nCol, nRow, nTab );
     699           0 :             pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
     700           0 :             pBackground = static_cast<const SvxBrushItem*>(&pPattern->GetItem( ATTR_BACKGROUND, pCondSet ));
     701             :         }
     702             :     }
     703             : 
     704           0 :     return pBackground;
     705             : }
     706             : 
     707       19985 : static bool lcl_EqualBack( const RowInfo& rFirst, const RowInfo& rOther,
     708             :                     SCCOL nX1, SCCOL nX2, bool bShowProt, bool bPagebreakMode )
     709             : {
     710       39970 :     if ( rFirst.bChanged   != rOther.bChanged ||
     711       19985 :          rFirst.bEmptyBack != rOther.bEmptyBack )
     712         259 :         return false;
     713             : 
     714             :     SCCOL nX;
     715       19726 :     if ( bShowProt )
     716             :     {
     717           0 :         for ( nX=nX1; nX<=nX2; nX++ )
     718             :         {
     719           0 :             const ScPatternAttr* pPat1 = rFirst.pCellInfo[nX+1].pPatternAttr;
     720           0 :             const ScPatternAttr* pPat2 = rOther.pCellInfo[nX+1].pPatternAttr;
     721           0 :             if ( !pPat1 || !pPat2 ||
     722           0 :                     &pPat1->GetItem(ATTR_PROTECTION) != &pPat2->GetItem(ATTR_PROTECTION) )
     723           0 :                 return false;
     724             :         }
     725             :     }
     726             :     else
     727             :     {
     728      200288 :         for ( nX=nX1; nX<=nX2; nX++ )
     729      180711 :             if ( rFirst.pCellInfo[nX+1].pBackground != rOther.pCellInfo[nX+1].pBackground )
     730         149 :                 return false;
     731             :     }
     732             : 
     733       19577 :     if ( rFirst.nRotMaxCol != SC_ROTMAX_NONE || rOther.nRotMaxCol != SC_ROTMAX_NONE )
     734        3710 :         for ( nX=nX1; nX<=nX2; nX++ )
     735        3339 :             if ( rFirst.pCellInfo[nX+1].nRotateDir != rOther.pCellInfo[nX+1].nRotateDir )
     736           0 :                 return false;
     737             : 
     738       19577 :     if ( bPagebreakMode )
     739           0 :         for ( nX=nX1; nX<=nX2; nX++ )
     740           0 :             if ( rFirst.pCellInfo[nX+1].bPrinted != rOther.pCellInfo[nX+1].bPrinted )
     741           0 :                 return false;
     742             : 
     743      199686 :     for ( nX=nX1; nX<=nX2; nX++ )
     744             :     {
     745      180109 :         const Color* pCol1 = rFirst.pCellInfo[nX+1].pColorScale.get();
     746      180109 :         const Color* pCol2 = rOther.pCellInfo[nX+1].pColorScale.get();
     747      180109 :         if( (pCol1 && !pCol2) || (!pCol1 && pCol2) )
     748           0 :             return false;
     749             : 
     750      180109 :         if (pCol1 && (*pCol1 != *pCol2))
     751           0 :             return false;
     752             : 
     753      180109 :         const ScDataBarInfo* pInfo1 = rFirst.pCellInfo[nX+1].pDataBar.get();
     754      180109 :         const ScDataBarInfo* pInfo2 = rOther.pCellInfo[nX+1].pDataBar.get();
     755             : 
     756      180109 :         if( (pInfo1 && !pInfo2) || (!pInfo1 && pInfo2) )
     757           0 :             return false;
     758             : 
     759      180109 :         if (pInfo1 && (*pInfo1 != *pInfo2))
     760           0 :             return false;
     761             : 
     762             :         // each cell with an icon set should be painted the same way
     763      180109 :         const ScIconSetInfo* pIconSet1 = rFirst.pCellInfo[nX+1].pIconSet.get();
     764      180109 :         const ScIconSetInfo* pIconSet2 = rOther.pCellInfo[nX+1].pIconSet.get();
     765             : 
     766      180109 :         if(pIconSet1 || pIconSet2)
     767           0 :             return false;
     768             :     }
     769             : 
     770       19577 :     return true;
     771             : }
     772             : 
     773        2964 : void ScOutputData::DrawDocumentBackground()
     774             : {
     775        2964 :     if ( !bSolidBackground )
     776        2964 :         return;
     777             : 
     778        2964 :     Color aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
     779        2964 :     mpDev->SetLineColor(aBgColor);
     780        2964 :     mpDev->SetFillColor(aBgColor);
     781             : 
     782        2964 :     Point aScreenPos  = mpDev->PixelToLogic(Point(nScrX, nScrY));
     783        2964 :     Size  aScreenSize = mpDev->PixelToLogic(Size(nScrW - 1,nScrH - 1));
     784             : 
     785        2964 :     mpDev->DrawRect(Rectangle(aScreenPos, aScreenSize));
     786             : }
     787             : 
     788             : namespace {
     789             : 
     790             : static const double lclCornerRectTransparency = 40.0;
     791             : 
     792           0 : void drawDataBars( const ScDataBarInfo* pOldDataBarInfo, vcl::RenderContext* pDev, const Rectangle& rRect)
     793             : {
     794           0 :     long nPosZero = 0;
     795           0 :     Rectangle aPaintRect = rRect;
     796           0 :     aPaintRect.Top() += 2;
     797           0 :     aPaintRect.Bottom() -= 2;
     798           0 :     aPaintRect.Left() += 2;
     799           0 :     aPaintRect.Right() -= 2;
     800           0 :     if(pOldDataBarInfo->mnZero)
     801             :     {
     802             :         // need to calculate null point in cell
     803           0 :         long nLength = aPaintRect.Right() - aPaintRect.Left();
     804           0 :         nPosZero = static_cast<long>(aPaintRect.Left() + nLength*pOldDataBarInfo->mnZero/100.0);
     805             :     }
     806             :     else
     807             :     {
     808           0 :         nPosZero = aPaintRect.Left();
     809             :     }
     810             : 
     811           0 :     if(pOldDataBarInfo->mnLength < 0)
     812             :     {
     813           0 :         aPaintRect.Right() = nPosZero;
     814           0 :         long nLength = nPosZero - aPaintRect.Left();
     815           0 :         aPaintRect.Left() = nPosZero + static_cast<long>(nLength * pOldDataBarInfo->mnLength/100.0);
     816             :     }
     817           0 :     else if(pOldDataBarInfo->mnLength > 0)
     818             :     {
     819           0 :         aPaintRect.Left() = nPosZero;
     820           0 :         long nLength = aPaintRect.Right() - nPosZero;
     821           0 :         aPaintRect.Right() = nPosZero + static_cast<long>(nLength * pOldDataBarInfo->mnLength/100.0);
     822             :     }
     823             :     else
     824           0 :         return;
     825             : 
     826           0 :     if(pOldDataBarInfo->mbGradient)
     827             :     {
     828           0 :         pDev->SetLineColor(pOldDataBarInfo->maColor);
     829           0 :         Gradient aGradient(GradientStyle_LINEAR, pOldDataBarInfo->maColor, COL_TRANSPARENT);
     830             : 
     831           0 :         if(pOldDataBarInfo->mnLength < 0)
     832           0 :             aGradient.SetAngle(2700);
     833             :         else
     834           0 :             aGradient.SetAngle(900);
     835             : 
     836           0 :         pDev->DrawGradient(aPaintRect, aGradient);
     837             : 
     838           0 :         pDev->SetLineColor();
     839             :     }
     840             :     else
     841             :     {
     842           0 :         pDev->SetFillColor(pOldDataBarInfo->maColor);
     843           0 :         pDev->DrawRect(aPaintRect);
     844             :     }
     845             : 
     846             :     //draw axis
     847           0 :     if(pOldDataBarInfo->mnZero && pOldDataBarInfo->mnZero != 100)
     848             :     {
     849           0 :         Point aPoint1(nPosZero, rRect.Top());
     850           0 :         Point aPoint2(nPosZero, rRect.Bottom());
     851           0 :         LineInfo aLineInfo(LINE_DASH, 1);
     852           0 :         aLineInfo.SetDashCount( 4 );
     853           0 :         aLineInfo.SetDistance( 3 );
     854           0 :         aLineInfo.SetDashLen( 3 );
     855           0 :         pDev->SetFillColor(pOldDataBarInfo->maAxisColor);
     856           0 :         pDev->SetLineColor(pOldDataBarInfo->maAxisColor);
     857           0 :         pDev->DrawLine(aPoint1, aPoint2, aLineInfo);
     858           0 :         pDev->SetLineColor();
     859           0 :         pDev->SetFillColor();
     860             :     }
     861             : }
     862             : 
     863           0 : BitmapEx& getIcon( ScIconSetType eType, sal_Int32 nIndex )
     864             : {
     865           0 :     return ScIconSetFormat::getBitmap( eType, nIndex );
     866             : }
     867             : 
     868           0 : void drawIconSets( const ScIconSetInfo* pOldIconSetInfo, vcl::RenderContext* pDev, const Rectangle& rRect )
     869             : {
     870             :     //long nSize = 16;
     871           0 :     ScIconSetType eType = pOldIconSetInfo->eIconSetType;
     872           0 :     sal_Int32 nIndex = pOldIconSetInfo->nIconIndex;
     873           0 :     BitmapEx& rIcon = getIcon( eType, nIndex );
     874           0 :     long aOrigSize = std::max<long>(0,std::min(rRect.GetSize().getWidth() - 4, rRect.GetSize().getHeight() -4));
     875           0 :     pDev->DrawBitmapEx( Point( rRect.Left() +2, rRect.Top() + 2 ), Size(aOrigSize, aOrigSize), rIcon );
     876           0 : }
     877             : 
     878       29268 : void drawCells(const Color* pColor, const SvxBrushItem* pBackground, const Color*& pOldColor, const SvxBrushItem*& pOldBackground,
     879             :         Rectangle& rRect, long nPosX, long nSignedOneX, vcl::RenderContext* pDev, const ScDataBarInfo* pDataBarInfo, const ScDataBarInfo*& pOldDataBarInfo,
     880             :         const ScIconSetInfo* pIconSetInfo, const ScIconSetInfo*& pOldIconSetInfo)
     881             : {
     882             : 
     883             :     // need to paint if old color scale has been used and now
     884             :     // we have a different color or a style based background
     885             :     // we can here fall back to pointer comparison
     886       29268 :     if (pOldColor && (pBackground || pOldColor != pColor || pOldDataBarInfo || pDataBarInfo || pIconSetInfo || pOldIconSetInfo))
     887             :     {
     888           0 :         rRect.Right() = nPosX-nSignedOneX;
     889           0 :         if( !pOldColor->GetTransparency() )
     890             :         {
     891           0 :             pDev->SetFillColor( *pOldColor );
     892           0 :             pDev->DrawRect( rRect );
     893             :         }
     894           0 :         if( pOldDataBarInfo )
     895           0 :             drawDataBars( pOldDataBarInfo, pDev, rRect );
     896           0 :         if( pOldIconSetInfo )
     897           0 :             drawIconSets( pOldIconSetInfo, pDev, rRect );
     898             : 
     899           0 :         rRect.Left() = nPosX - nSignedOneX;
     900             :     }
     901             : 
     902       29268 :     if ( pOldBackground && (pColor ||pBackground != pOldBackground || pOldDataBarInfo || pDataBarInfo || pIconSetInfo || pOldIconSetInfo) )
     903             :     {
     904        4221 :         rRect.Right() = nPosX-nSignedOneX;
     905        4221 :         if (pOldBackground)             // ==0 if hidden
     906             :         {
     907        4221 :             Color aBackCol = pOldBackground->GetColor();
     908        4221 :             if ( !aBackCol.GetTransparency() )      //! partial transparency?
     909             :             {
     910         450 :                 pDev->SetFillColor( aBackCol );
     911         450 :                 pDev->DrawRect( rRect );
     912             :             }
     913             :         }
     914        4221 :         if( pOldDataBarInfo )
     915           0 :             drawDataBars( pOldDataBarInfo, pDev, rRect );
     916        4221 :         if( pOldIconSetInfo )
     917           0 :             drawIconSets( pOldIconSetInfo, pDev, rRect );
     918             : 
     919        4221 :         rRect.Left() = nPosX - nSignedOneX;
     920             :     }
     921             : 
     922       29268 :     if (!pOldBackground && !pOldColor && (pDataBarInfo || pIconSetInfo))
     923             :     {
     924           0 :         rRect.Right() = nPosX -nSignedOneX;
     925           0 :         rRect.Left() = nPosX - nSignedOneX;
     926             :     }
     927             : 
     928       29268 :     if(pColor)
     929             :     {
     930             :         // only update pOldColor if the colors changed
     931           0 :         if (!pOldColor || *pOldColor != *pColor)
     932           0 :             pOldColor = pColor;
     933             : 
     934           0 :         pOldBackground = NULL;
     935             :     }
     936       29268 :     else if(pBackground)
     937             :     {
     938       25896 :         pOldBackground = pBackground;
     939       25896 :         pOldColor = NULL;
     940             :     }
     941             : 
     942       29268 :     if(pDataBarInfo)
     943           0 :         pOldDataBarInfo = pDataBarInfo;
     944             :     else
     945       29268 :         pOldDataBarInfo = NULL;
     946             : 
     947       29268 :     if(pIconSetInfo)
     948           0 :         pOldIconSetInfo = pIconSetInfo;
     949             :     else
     950       29268 :         pOldIconSetInfo = NULL;
     951       29268 : }
     952             : 
     953             : }
     954             : 
     955        2991 : void ScOutputData::DrawBackground()
     956             : {
     957        2991 :     FindRotated();              //! from the outside?
     958             : 
     959        2991 :     Rectangle aRect;
     960        2991 :     Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
     961        2991 :     long nOneX = aOnePixel.Width();
     962        2991 :     long nOneY = aOnePixel.Height();
     963             : 
     964        2991 :     if (bMetaFile)
     965           5 :         nOneX = nOneY = 0;
     966             : 
     967        2991 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
     968        2991 :     long nSignedOneX = nOneX * nLayoutSign;
     969             : 
     970        2991 :     mpDev->SetLineColor();
     971             : 
     972        2991 :     bool bShowProt = mbSyntaxMode && mpDoc->IsTabProtected(nTab);
     973        2991 :     bool bDoAll = bShowProt || bPagebreakMode || bSolidBackground;
     974             : 
     975        5977 :     bool bCellContrast = mbUseStyleColor &&
     976        5977 :             Application::GetSettings().GetStyleSettings().GetHighContrastMode();
     977             : 
     978        2991 :     long nPosY = nScrY;
     979        6521 :     for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
     980             :     {
     981        3530 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
     982        3530 :         long nRowHeight = pThisRowInfo->nHeight;
     983             : 
     984        3530 :         if ( pThisRowInfo->bChanged )
     985             :         {
     986        3530 :             if ( ( ( pThisRowInfo->bEmptyBack ) || mbSyntaxMode ) && !bDoAll )
     987             :             {
     988             :                 // nothing
     989             :             }
     990             :             else
     991             :             {
     992             :                 // scan for rows with the same background:
     993        3372 :                 SCSIZE nSkip = 0;
     994       46306 :                 while ( nArrY+nSkip+2<nArrCount &&
     995       39970 :                         lcl_EqualBack( *pThisRowInfo, pRowInfo[nArrY+nSkip+1],
     996       59955 :                                         nX1, nX2, bShowProt, bPagebreakMode ) )
     997             :                 {
     998       19577 :                     ++nSkip;
     999       19577 :                     nRowHeight += pRowInfo[nArrY+nSkip].nHeight;    // after incrementing
    1000             :                 }
    1001             : 
    1002        3372 :                 long nPosX = nScrX;
    1003        3372 :                 if ( bLayoutRTL )
    1004           1 :                     nPosX += nMirrorW - nOneX;
    1005        3372 :                 aRect = Rectangle( nPosX, nPosY-nOneY, nPosX, nPosY+nRowHeight-nOneY );
    1006             : 
    1007        3372 :                 const SvxBrushItem* pOldBackground = NULL;
    1008             :                 const SvxBrushItem* pBackground;
    1009        3372 :                 const Color* pOldColor = NULL;
    1010        3372 :                 const ScDataBarInfo* pOldDataBarInfo = NULL;
    1011        3372 :                 const ScIconSetInfo* pOldIconSetInfo = NULL;
    1012        3372 :                 SCCOL nMergedCells = 1;
    1013        3372 :                 SCCOL nOldMerged = 0;
    1014             : 
    1015       29268 :                 for (SCCOL nX=nX1; nX + nMergedCells <= nX2 + 1; nX += nOldMerged)
    1016             :                 {
    1017       25896 :                     CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+nMergedCells];
    1018             : 
    1019       25896 :                     nOldMerged = nMergedCells;
    1020             : 
    1021       25896 :                     if (bCellContrast)
    1022             :                     {
    1023             :                         //  high contrast for cell borders and backgrounds -> empty background
    1024           0 :                         pBackground = ScGlobal::GetEmptyBrushItem();
    1025             :                     }
    1026       25896 :                     else if (bShowProt)         // show cell protection in syntax mode
    1027             :                     {
    1028           0 :                         const ScPatternAttr* pP = pInfo->pPatternAttr;
    1029           0 :                         if (pP)
    1030             :                         {
    1031             :                             const ScProtectionAttr& rProt = static_cast<const ScProtectionAttr&>(
    1032           0 :                                                                 pP->GetItem(ATTR_PROTECTION));
    1033           0 :                             if (rProt.GetProtection() || rProt.GetHideCell())
    1034           0 :                                 pBackground = ScGlobal::GetProtectedBrushItem();
    1035             :                             else
    1036           0 :                                 pBackground = ScGlobal::GetEmptyBrushItem();
    1037             :                         }
    1038             :                         else
    1039           0 :                             pBackground = NULL;
    1040             :                     }
    1041             :                     else
    1042       25896 :                         pBackground = pInfo->pBackground;
    1043             : 
    1044       25896 :                     if ( bPagebreakMode && !pInfo->bPrinted )
    1045           0 :                         pBackground = ScGlobal::GetProtectedBrushItem();
    1046             : 
    1047       51792 :                     if ( pInfo->nRotateDir > SC_ROTDIR_STANDARD &&
    1048       25896 :                             pBackground->GetColor().GetTransparency() != 255 &&
    1049           0 :                             !bCellContrast )
    1050             :                     {
    1051           0 :                         SCROW nY = pRowInfo[nArrY].nRowNo;
    1052           0 :                         pBackground = lcl_FindBackground( mpDoc, nX, nY, nTab );
    1053             :                     }
    1054             : 
    1055       25896 :                     const Color* pColor = pInfo->pColorScale.get();
    1056       25896 :                     const ScDataBarInfo* pDataBarInfo = pInfo->pDataBar.get();
    1057       25896 :                     const ScIconSetInfo* pIconSetInfo = pInfo->pIconSet.get();
    1058       25896 :                     drawCells( pColor, pBackground, pOldColor, pOldBackground, aRect, nPosX, nSignedOneX, mpDev, pDataBarInfo, pOldDataBarInfo, pIconSetInfo, pOldIconSetInfo );
    1059             : 
    1060             :                     // extend for all merged cells
    1061       25896 :                     nMergedCells = 1;
    1062       25896 :                     if (pInfo->bMerged && pInfo->pPatternAttr)
    1063             :                     {
    1064             :                             const ScMergeAttr* pMerge =
    1065          18 :                                     static_cast<const ScMergeAttr*>(&pInfo->pPatternAttr->GetItem(ATTR_MERGE));
    1066          18 :                             nMergedCells = std::max<SCCOL>(1, pMerge->GetColMerge());
    1067             :                     }
    1068             : 
    1069       51815 :                     for (SCCOL nMerged = 0; nMerged < nMergedCells; ++nMerged)
    1070             :                     {
    1071       25919 :                         nPosX += pRowInfo[0].pCellInfo[nX+nOldMerged+nMerged].nWidth * nLayoutSign;
    1072             :                     }
    1073             :                 }
    1074        3372 :                 drawCells( NULL, NULL, pOldColor, pOldBackground, aRect, nPosX, nSignedOneX, mpDev, NULL, pOldDataBarInfo, NULL, pOldIconSetInfo );
    1075             : 
    1076        3372 :                 nArrY += nSkip;
    1077             :             }
    1078             :         }
    1079        3530 :         nPosY += nRowHeight;
    1080             :     }
    1081        2991 : }
    1082             : 
    1083        2969 : void ScOutputData::DrawShadow()
    1084             : {
    1085        2969 :     DrawExtraShadow( false, false, false, false );
    1086        2969 : }
    1087             : 
    1088        2991 : void ScOutputData::DrawExtraShadow(bool bLeft, bool bTop, bool bRight, bool bBottom)
    1089             : {
    1090        2991 :     mpDev->SetLineColor();
    1091             : 
    1092        2991 :     const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    1093        2991 :     bool bCellContrast = mbUseStyleColor && rStyleSettings.GetHighContrastMode();
    1094        2991 :     Color aAutoTextColor;
    1095        2991 :     if ( bCellContrast )
    1096           0 :         aAutoTextColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
    1097             : 
    1098        2991 :     long nInitPosX = nScrX;
    1099        2991 :     if ( bLayoutRTL )
    1100             :     {
    1101           1 :         Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
    1102           1 :         long nOneX = aOnePixel.Width();
    1103           1 :         nInitPosX += nMirrorW - nOneX;
    1104             :     }
    1105        2991 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
    1106             : 
    1107        2991 :     long nPosY = nScrY - pRowInfo[0].nHeight;
    1108       32080 :     for (SCSIZE nArrY=0; nArrY<nArrCount; nArrY++)
    1109             :     {
    1110       29089 :         bool bCornerY = ( nArrY == 0 ) || ( nArrY+1 == nArrCount );
    1111       29089 :         bool bSkipY = ( nArrY==0 && !bTop ) || ( nArrY+1 == nArrCount && !bBottom );
    1112             : 
    1113       29089 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
    1114       29089 :         long nRowHeight = pThisRowInfo->nHeight;
    1115             : 
    1116       29089 :         if ( pThisRowInfo->bChanged && !bSkipY )
    1117             :         {
    1118       23151 :             long nPosX = nInitPosX - pRowInfo[0].pCellInfo[nX1].nWidth * nLayoutSign;
    1119      276103 :             for (SCCOL nArrX=nX1; nArrX<=nX2+2; nArrX++)
    1120             :             {
    1121      252952 :                 bool bCornerX = ( nArrX==nX1 || nArrX==nX2+2 );
    1122      252952 :                 bool bSkipX = ( nArrX==nX1 && !bLeft ) || ( nArrX==nX2+2 && !bRight );
    1123             : 
    1124      758856 :                 for (sal_uInt16 nPass=0; nPass<2; nPass++) // horizontal / vertical
    1125             :                 {
    1126             :                     const SvxShadowItem* pAttr = nPass ?
    1127      252952 :                             pThisRowInfo->pCellInfo[nArrX].pVShadowOrigin :
    1128      758856 :                             pThisRowInfo->pCellInfo[nArrX].pHShadowOrigin;
    1129      505904 :                     if ( pAttr && !bSkipX )
    1130             :                     {
    1131             :                         ScShadowPart ePart = nPass ?
    1132           0 :                                 pThisRowInfo->pCellInfo[nArrX].eVShadowPart :
    1133           0 :                                 pThisRowInfo->pCellInfo[nArrX].eHShadowPart;
    1134             : 
    1135           0 :                         bool bDo = true;
    1136           0 :                         if ( (nPass==0 && bCornerX) || (nPass==1 && bCornerY) )
    1137           0 :                             if ( ePart != SC_SHADOW_CORNER )
    1138           0 :                                 bDo = false;
    1139             : 
    1140           0 :                         if (bDo)
    1141             :                         {
    1142           0 :                             long nThisWidth = pRowInfo[0].pCellInfo[nArrX].nWidth;
    1143           0 :                             long nMaxWidth = nThisWidth;
    1144           0 :                             if (!nMaxWidth)
    1145             :                             {
    1146             :                                 //! direction must depend on shadow location
    1147           0 :                                 SCCOL nWx = nArrX;      // nX+1
    1148           0 :                                 while (nWx<nX2 && !pRowInfo[0].pCellInfo[nWx+1].nWidth)
    1149           0 :                                     ++nWx;
    1150           0 :                                 nMaxWidth = pRowInfo[0].pCellInfo[nWx+1].nWidth;
    1151             :                             }
    1152             : 
    1153             :                             // rectangle is in logical orientation
    1154             :                             Rectangle aRect( nPosX, nPosY,
    1155           0 :                                              nPosX + ( nThisWidth - 1 ) * nLayoutSign,
    1156           0 :                                              nPosY + pRowInfo[nArrY].nHeight - 1 );
    1157             : 
    1158           0 :                             long nSize = pAttr->GetWidth();
    1159           0 :                             long nSizeX = (long)(nSize*mnPPTX);
    1160           0 :                             if (nSizeX >= nMaxWidth) nSizeX = nMaxWidth-1;
    1161           0 :                             long nSizeY = (long)(nSize*mnPPTY);
    1162           0 :                             if (nSizeY >= nRowHeight) nSizeY = nRowHeight-1;
    1163             : 
    1164           0 :                             nSizeX *= nLayoutSign;      // used only to add to rectangle values
    1165             : 
    1166           0 :                             SvxShadowLocation eLoc = pAttr->GetLocation();
    1167           0 :                             if ( bLayoutRTL )
    1168             :                             {
    1169             :                                 //  Shadow location is specified as "visual" (right is always right),
    1170             :                                 //  so the attribute's location value is mirrored here and in FillInfo.
    1171           0 :                                 switch (eLoc)
    1172             :                                 {
    1173           0 :                                     case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT;  break;
    1174           0 :                                     case SVX_SHADOW_BOTTOMLEFT:  eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
    1175           0 :                                     case SVX_SHADOW_TOPRIGHT:    eLoc = SVX_SHADOW_TOPLEFT;     break;
    1176           0 :                                     case SVX_SHADOW_TOPLEFT:     eLoc = SVX_SHADOW_TOPRIGHT;    break;
    1177             :                                     default:
    1178             :                                     {
    1179             :                                         // added to avoid warnings
    1180             :                                     }
    1181             :                                 }
    1182             :                             }
    1183             : 
    1184           0 :                             if (ePart == SC_SHADOW_HORIZ || ePart == SC_SHADOW_HSTART ||
    1185             :                                 ePart == SC_SHADOW_CORNER)
    1186             :                             {
    1187           0 :                                 if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_TOPRIGHT)
    1188           0 :                                     aRect.Top() = aRect.Bottom() - nSizeY;
    1189             :                                 else
    1190           0 :                                     aRect.Bottom() = aRect.Top() + nSizeY;
    1191             :                             }
    1192           0 :                             if (ePart == SC_SHADOW_VERT || ePart == SC_SHADOW_VSTART ||
    1193             :                                 ePart == SC_SHADOW_CORNER)
    1194             :                             {
    1195           0 :                                 if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_BOTTOMLEFT)
    1196           0 :                                     aRect.Left() = aRect.Right() - nSizeX;
    1197             :                                 else
    1198           0 :                                     aRect.Right() = aRect.Left() + nSizeX;
    1199             :                             }
    1200           0 :                             if (ePart == SC_SHADOW_HSTART)
    1201             :                             {
    1202           0 :                                 if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_BOTTOMLEFT)
    1203           0 :                                     aRect.Right() -= nSizeX;
    1204             :                                 else
    1205           0 :                                     aRect.Left() += nSizeX;
    1206             :                             }
    1207           0 :                             if (ePart == SC_SHADOW_VSTART)
    1208             :                             {
    1209           0 :                                 if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_TOPRIGHT)
    1210           0 :                                     aRect.Bottom() -= nSizeY;
    1211             :                                 else
    1212           0 :                                     aRect.Top() += nSizeY;
    1213             :                             }
    1214             : 
    1215             :                             //! merge rectangles?
    1216           0 :                             mpDev->SetFillColor( bCellContrast ? aAutoTextColor : pAttr->GetColor() );
    1217           0 :                             mpDev->DrawRect( aRect );
    1218             :                         }
    1219             :                     }
    1220             :                 }
    1221             : 
    1222      252952 :                 nPosX += pRowInfo[0].pCellInfo[nArrX].nWidth * nLayoutSign;
    1223             :             }
    1224             :         }
    1225       29089 :         nPosY += nRowHeight;
    1226             :     }
    1227        2991 : }
    1228             : 
    1229           0 : void ScOutputData::DrawClear()
    1230             : {
    1231           0 :     Rectangle aRect;
    1232           0 :     Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
    1233           0 :     long nOneX = aOnePixel.Width();
    1234           0 :     long nOneY = aOnePixel.Height();
    1235             : 
    1236             :     // (called only for ScGridWindow)
    1237           0 :     Color aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
    1238             : 
    1239           0 :     if (bMetaFile)
    1240           0 :         nOneX = nOneY = 0;
    1241             : 
    1242           0 :     mpDev->SetLineColor();
    1243             : 
    1244           0 :     mpDev->SetFillColor( aBgColor );
    1245             : 
    1246           0 :     long nPosY = nScrY;
    1247           0 :     for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
    1248             :     {
    1249           0 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
    1250           0 :         long nRowHeight = pThisRowInfo->nHeight;
    1251             : 
    1252           0 :         if ( pThisRowInfo->bChanged )
    1253             :         {
    1254             :             // scan for more rows which must be painted:
    1255           0 :             SCSIZE nSkip = 0;
    1256           0 :             while ( nArrY+nSkip+2<nArrCount && pRowInfo[nArrY+nSkip+1].bChanged )
    1257             :             {
    1258           0 :                 ++nSkip;
    1259           0 :                 nRowHeight += pRowInfo[nArrY+nSkip].nHeight;    // after incrementing
    1260             :             }
    1261             : 
    1262             :             aRect = Rectangle( Point( nScrX, nPosY ),
    1263           0 :                     Size( nScrW+1-nOneX, nRowHeight+1-nOneY) );
    1264           0 :             mpDev->DrawRect( aRect );
    1265             : 
    1266           0 :             nArrY += nSkip;
    1267             :         }
    1268           0 :         nPosY += nRowHeight;
    1269             :     }
    1270           0 : }
    1271             : 
    1272             : // Lines
    1273             : 
    1274       31398 : long lclGetSnappedX( OutputDevice& rDev, long nPosX, bool bSnapPixel )
    1275             : {
    1276       31398 :     return (bSnapPixel && nPosX) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( nPosX, 0 ) ) ).Width() : nPosX;
    1277             : }
    1278             : 
    1279       32080 : long lclGetSnappedY( OutputDevice& rDev, long nPosY, bool bSnapPixel )
    1280             : {
    1281       32080 :     return (bSnapPixel && nPosY) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( 0, nPosY ) ) ).Height() : nPosY;
    1282             : }
    1283             : 
    1284       28407 : size_t lclGetArrayColFromCellInfoX( sal_uInt16 nCellInfoX, sal_uInt16 nCellInfoFirstX, sal_uInt16 nCellInfoLastX, bool bRTL )
    1285             : {
    1286       28407 :     return static_cast< size_t >( bRTL ? (nCellInfoLastX + 2 - nCellInfoX) : (nCellInfoX - nCellInfoFirstX) );
    1287             : }
    1288             : 
    1289        2991 : void ScOutputData::DrawFrame()
    1290             : {
    1291        2991 :     DrawModeFlags nOldDrawMode = mpDev->GetDrawMode();
    1292             : 
    1293        2991 :     Color aSingleColor;
    1294        2991 :     bool bUseSingleColor = false;
    1295        2991 :     const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    1296        2991 :     bool bCellContrast = mbUseStyleColor && rStyleSettings.GetHighContrastMode();
    1297             : 
    1298             :     //  if a Calc OLE object is embedded in Draw/Impress, the VCL DrawMode is used
    1299             :     //  for display mode / B&W printing. The VCL DrawMode handling doesn't work for lines
    1300             :     //  that are drawn with DrawRect, so if the line/background bits are set, the DrawMode
    1301             :     //  must be reset and the border colors handled here.
    1302             : 
    1303        2991 :     if ( ( nOldDrawMode & DrawModeFlags::WhiteFill ) && ( nOldDrawMode & DrawModeFlags::BlackLine ) )
    1304             :     {
    1305           0 :         mpDev->SetDrawMode( nOldDrawMode & (~DrawModeFlags::WhiteFill) );
    1306           0 :         aSingleColor.SetColor( COL_BLACK );
    1307           0 :         bUseSingleColor = true;
    1308             :     }
    1309        2991 :     else if ( ( nOldDrawMode & DrawModeFlags::SettingsFill ) && ( nOldDrawMode & DrawModeFlags::SettingsLine ) )
    1310             :     {
    1311           0 :         mpDev->SetDrawMode( nOldDrawMode & (~DrawModeFlags::SettingsFill) );
    1312           0 :         aSingleColor = rStyleSettings.GetWindowTextColor();     // same as used in VCL for DrawModeFlags::SettingsLine
    1313           0 :         bUseSingleColor = true;
    1314             :     }
    1315        2991 :     else if ( bCellContrast )
    1316             :     {
    1317           0 :         aSingleColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
    1318           0 :         bUseSingleColor = true;
    1319             :     }
    1320             : 
    1321        2991 :     const Color* pForceColor = bUseSingleColor ? &aSingleColor : 0;
    1322             : 
    1323        2991 :     if (bAnyRotated)
    1324         162 :         DrawRotatedFrame( pForceColor );        // removes the lines that must not be painted here
    1325             : 
    1326        2991 :     long nInitPosX = nScrX;
    1327        2991 :     if ( bLayoutRTL )
    1328             :     {
    1329           1 :         Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
    1330           1 :         long nOneX = aOnePixel.Width();
    1331           1 :         nInitPosX += nMirrorW - nOneX;
    1332             :     }
    1333        2991 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
    1334             : 
    1335             :     // *** set column and row sizes of the frame border array ***
    1336             : 
    1337        2991 :     svx::frame::Array& rArray = mrTabInfo.maArray;
    1338        2991 :     size_t nColCount = rArray.GetColCount();
    1339        2991 :     size_t nRowCount = rArray.GetRowCount();
    1340             : 
    1341             :     // row heights
    1342             : 
    1343             :     // row 0 is not visible (dummy for borders from top) - subtract its height from initial position
    1344             :     // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit before
    1345        2991 :     long nOldPosY = nScrY - 1 - pRowInfo[ 0 ].nHeight;
    1346        2991 :     long nOldSnapY = lclGetSnappedY( *mpDev, nOldPosY, bSnapPixel );
    1347        2991 :     rArray.SetYOffset( nOldSnapY );
    1348       32080 :     for( size_t nRow = 0; nRow < nRowCount; ++nRow )
    1349             :     {
    1350       29089 :         long nNewPosY = nOldPosY + pRowInfo[ nRow ].nHeight;
    1351       29089 :         long nNewSnapY = lclGetSnappedY( *mpDev, nNewPosY, bSnapPixel );
    1352       29089 :         rArray.SetRowHeight( nRow, nNewSnapY - nOldSnapY );
    1353       29089 :         nOldPosY = nNewPosY;
    1354       29089 :         nOldSnapY = nNewSnapY;
    1355             :     }
    1356             : 
    1357             :     // column widths
    1358             : 
    1359             :     // column nX1 is not visible (dummy for borders from left) - subtract its width from initial position
    1360             :     // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit above
    1361        2991 :     long nOldPosX = nInitPosX - nLayoutSign * (1 + pRowInfo[ 0 ].pCellInfo[ nX1 ].nWidth);
    1362        2991 :     long nOldSnapX = lclGetSnappedX( *mpDev, nOldPosX, bSnapPixel );
    1363             :     // set X offset for left-to-right sheets; for right-to-left sheets this is done after for() loop
    1364        2991 :     if( !bLayoutRTL )
    1365        2990 :         rArray.SetXOffset( nOldSnapX );
    1366       31398 :     for( sal_uInt16 nInfoIdx = nX1; nInfoIdx <= nX2 + 2; ++nInfoIdx )
    1367             :     {
    1368       28407 :         size_t nCol = lclGetArrayColFromCellInfoX( nInfoIdx, nX1, nX2, bLayoutRTL );
    1369       28407 :         long nNewPosX = nOldPosX + pRowInfo[ 0 ].pCellInfo[ nInfoIdx ].nWidth * nLayoutSign;
    1370       28407 :         long nNewSnapX = lclGetSnappedX( *mpDev, nNewPosX, bSnapPixel );
    1371       28407 :         rArray.SetColWidth( nCol, std::abs( nNewSnapX - nOldSnapX ) );
    1372       28407 :         nOldPosX = nNewPosX;
    1373       28407 :         nOldSnapX = nNewSnapX;
    1374             :     }
    1375        2991 :     if( bLayoutRTL )
    1376           1 :         rArray.SetXOffset( nOldSnapX );
    1377             : 
    1378             :     // *** draw the array ***
    1379             : 
    1380        2991 :     size_t nFirstCol = 1;
    1381        2991 :     size_t nFirstRow = 1;
    1382        2991 :     size_t nLastCol = nColCount - 2;
    1383        2991 :     size_t nLastRow = nRowCount - 2;
    1384             : 
    1385        2991 :     if( mrTabInfo.mbPageMode )
    1386          22 :         rArray.SetClipRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
    1387             : 
    1388             :     // draw only rows with set RowInfo::bChanged flag
    1389        2991 :     size_t nRow1 = nFirstRow;
    1390        2991 :     boost::scoped_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(CreateProcessor2D());
    1391        2991 :     if (!pProcessor)
    1392        2991 :         return;
    1393             : 
    1394        8973 :     while( nRow1 <= nLastRow )
    1395             :     {
    1396        2991 :         while( (nRow1 <= nLastRow) && !pRowInfo[ nRow1 ].bChanged ) ++nRow1;
    1397        2991 :         if( nRow1 <= nLastRow )
    1398             :         {
    1399        2991 :             size_t nRow2 = nRow1;
    1400        2991 :             while( (nRow2 + 1 <= nLastRow) && pRowInfo[ nRow2 + 1 ].bChanged ) ++nRow2;
    1401        2991 :             rArray.DrawRange( pProcessor.get(), nFirstCol, nRow1, nLastCol, nRow2, pForceColor );
    1402        2991 :             nRow1 = nRow2 + 1;
    1403             :         }
    1404             :     }
    1405        2991 :     pProcessor.reset();
    1406             : 
    1407        2991 :     mpDev->SetDrawMode(nOldDrawMode);
    1408             : }
    1409             : 
    1410             : // Line below the cell
    1411             : 
    1412           0 : static const ::editeng::SvxBorderLine* lcl_FindHorLine( ScDocument* pDoc,
    1413             :                         SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nRotDir,
    1414             :                         bool bTopLine )
    1415             : {
    1416           0 :     if ( nRotDir != SC_ROTDIR_LEFT && nRotDir != SC_ROTDIR_RIGHT )
    1417           0 :         return NULL;
    1418             : 
    1419           0 :     bool bFound = false;
    1420           0 :     while (!bFound)
    1421             :     {
    1422           0 :         if ( nRotDir == SC_ROTDIR_LEFT )
    1423             :         {
    1424             :             // text to the left -> line from the right
    1425           0 :             if ( nCol < MAXCOL )
    1426           0 :                 ++nCol;
    1427             :             else
    1428           0 :                 return NULL; // couldn't find it
    1429             :         }
    1430             :         else
    1431             :         {
    1432             :             // text to the right -> line from the left
    1433           0 :             if ( nCol > 0 )
    1434           0 :                 --nCol;
    1435             :             else
    1436           0 :                 return NULL; // couldn't find it
    1437             :         }
    1438           0 :         const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
    1439           0 :         const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
    1440           0 :         if ( !pPattern->GetRotateVal( pCondSet ) ||
    1441             :                 static_cast<const SvxRotateModeItem&>(pPattern->GetItem(
    1442           0 :                     ATTR_ROTATE_MODE, pCondSet)).GetValue() == SVX_ROTATE_MODE_STANDARD )
    1443           0 :             bFound = true;
    1444             :     }
    1445             : 
    1446           0 :     if (bTopLine)
    1447           0 :         --nRow;
    1448             :     const ::editeng::SvxBorderLine* pThisBottom;
    1449           0 :     if ( ValidRow(nRow) )
    1450           0 :         pThisBottom = static_cast<const SvxBoxItem*>(pDoc->GetAttr( nCol, nRow, nTab, ATTR_BORDER ))->GetBottom();
    1451             :     else
    1452           0 :         pThisBottom = NULL;
    1453             :     const ::editeng::SvxBorderLine* pNextTop;
    1454           0 :     if ( nRow < MAXROW )
    1455           0 :         pNextTop = static_cast<const SvxBoxItem*>(pDoc->GetAttr( nCol, nRow+1, nTab, ATTR_BORDER ))->GetTop();
    1456             :     else
    1457           0 :         pNextTop = NULL;
    1458             : 
    1459           0 :     if ( ScHasPriority( pThisBottom, pNextTop ) )
    1460           0 :         return pThisBottom;
    1461             :     else
    1462           0 :         return pNextTop;
    1463             : }
    1464             : 
    1465           0 : static long lcl_getRotate( ScDocument* pDoc, SCTAB nTab, SCCOL nX, SCROW nY )
    1466             : {
    1467           0 :     long nRotate = 0;
    1468             : 
    1469           0 :     const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
    1470           0 :     const SfxItemSet* pCondSet = pDoc->GetCondResult( nX, nY, nTab );
    1471             : 
    1472           0 :     nRotate = pPattern->GetRotateVal( pCondSet );
    1473             : 
    1474           0 :     return nRotate;
    1475             : }
    1476             : 
    1477         162 : void ScOutputData::DrawRotatedFrame( const Color* pForceColor )
    1478             : {
    1479             :     //! save nRotMax
    1480         162 :     SCCOL nRotMax = nX2;
    1481        1052 :     for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
    1482         890 :         if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
    1483           0 :             nRotMax = pRowInfo[nRotY].nRotMaxCol;
    1484             : 
    1485             :     const ScPatternAttr* pPattern;
    1486             :     const SfxItemSet*    pCondSet;
    1487             : 
    1488         162 :     const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    1489         162 :     bool bCellContrast = mbUseStyleColor && rStyleSettings.GetHighContrastMode();
    1490             : 
    1491             :     // color (pForceColor) is determined externally, including DrawMode changes
    1492             : 
    1493         162 :     long nInitPosX = nScrX;
    1494         162 :     if ( bLayoutRTL )
    1495             :     {
    1496           0 :         Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
    1497           0 :         long nOneX = aOnePixel.Width();
    1498           0 :         nInitPosX += nMirrorW - nOneX;
    1499             :     }
    1500         162 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
    1501             : 
    1502         162 :     Rectangle aClipRect( Point(nScrX, nScrY), Size(nScrW, nScrH) );
    1503         162 :     if (bMetaFile)
    1504             :     {
    1505           0 :         mpDev->Push();
    1506           0 :         mpDev->IntersectClipRegion( aClipRect );
    1507             :     }
    1508             :     else
    1509         162 :         mpDev->SetClipRegion( vcl::Region( aClipRect ) );
    1510             : 
    1511         162 :     svx::frame::Array& rArray = mrTabInfo.maArray;
    1512         162 :     boost::scoped_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(CreateProcessor2D( ));
    1513             : 
    1514         162 :     long nPosY = nScrY;
    1515         890 :     for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)
    1516             :     {
    1517             :         // Rotated is also drawn one line above/below Changed if parts extend into the cell
    1518             : 
    1519         728 :         RowInfo& rPrevRowInfo = pRowInfo[nArrY-1];
    1520         728 :         RowInfo& rThisRowInfo = pRowInfo[nArrY];
    1521         728 :         RowInfo& rNextRowInfo = pRowInfo[nArrY+1];
    1522             : 
    1523         728 :         size_t nRow = static_cast< size_t >( nArrY );
    1524             : 
    1525         728 :         long nRowHeight = rThisRowInfo.nHeight;
    1526         728 :         if ( rThisRowInfo.nRotMaxCol != SC_ROTMAX_NONE &&
    1527           0 :              ( rThisRowInfo.bChanged || rPrevRowInfo.bChanged ||
    1528           0 :                ( nArrY+1<nArrCount && rNextRowInfo.bChanged ) ) )
    1529             :         {
    1530         661 :             SCROW nY = rThisRowInfo.nRowNo;
    1531         661 :             long nPosX = 0;
    1532             :             SCCOL nX;
    1533        6610 :             for (nX=0; nX<=nRotMax; nX++)
    1534             :             {
    1535        5949 :                 if (nX==nX1) nPosX = nInitPosX;     // calculated individually for preceding positions
    1536             : 
    1537        5949 :                 sal_uInt16 nArrX = nX + 1;
    1538             : 
    1539        5949 :                 CellInfo* pInfo = &rThisRowInfo.pCellInfo[nArrX];
    1540        5949 :                 long nColWidth = pRowInfo[0].pCellInfo[nArrX].nWidth;
    1541        5949 :                 if ( pInfo->nRotateDir > SC_ROTDIR_STANDARD &&
    1542           0 :                         !pInfo->bHOverlapped && !pInfo->bVOverlapped )
    1543             :                 {
    1544           0 :                     pPattern = pInfo->pPatternAttr;
    1545           0 :                     pCondSet = pInfo->pConditionSet;
    1546           0 :                     if (!pPattern)
    1547             :                     {
    1548           0 :                         pPattern = mpDoc->GetPattern( nX, nY, nTab );
    1549           0 :                         pInfo->pPatternAttr = pPattern;
    1550           0 :                         pCondSet = mpDoc->GetCondResult( nX, nY, nTab );
    1551           0 :                         pInfo->pConditionSet = pCondSet;
    1552             :                     }
    1553             : 
    1554             :                     //! LastPattern etc.
    1555             : 
    1556           0 :                     long nAttrRotate = pPattern->GetRotateVal( pCondSet );
    1557             :                     SvxRotateMode eRotMode = (SvxRotateMode)static_cast<const SvxRotateModeItem&>(
    1558           0 :                                     pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
    1559             : 
    1560           0 :                     if ( nAttrRotate )
    1561             :                     {
    1562           0 :                         if (nX<nX1)         // compute negative position
    1563             :                         {
    1564           0 :                             nPosX = nInitPosX;
    1565           0 :                             SCCOL nCol = nX1;
    1566           0 :                             while (nCol > nX)
    1567             :                             {
    1568           0 :                                 --nCol;
    1569           0 :                                 nPosX -= nLayoutSign * (long) pRowInfo[0].pCellInfo[nCol+1].nWidth;
    1570             :                             }
    1571             :                         }
    1572             : 
    1573             :                         // start position minus 1 so rotated backgrounds suit the border
    1574             :                         // (border is on the grid)
    1575             : 
    1576           0 :                         long nTop = nPosY - 1;
    1577           0 :                         long nBottom = nPosY + nRowHeight - 1;
    1578           0 :                         long nTopLeft = nPosX - nLayoutSign;
    1579           0 :                         long nTopRight = nPosX + ( nColWidth - 1 ) * nLayoutSign;
    1580           0 :                         long nBotLeft = nTopLeft;
    1581           0 :                         long nBotRight = nTopRight;
    1582             : 
    1583             :                         // inclusion of the sign here hasn't been decided yet
    1584             :                         // (if not, the extension of the non-rotated background must also be changed)
    1585           0 :                         double nRealOrient = nLayoutSign * nAttrRotate * F_PI18000;     // 1/100th degrees
    1586           0 :                         double nCos = cos( nRealOrient );
    1587           0 :                         double nSin = sin( nRealOrient );
    1588             :                         //! restrict !!!
    1589           0 :                         long nSkew = (long) ( nRowHeight * nCos / nSin );
    1590             : 
    1591           0 :                         switch (eRotMode)
    1592             :                         {
    1593             :                             case SVX_ROTATE_MODE_BOTTOM:
    1594           0 :                                 nTopLeft += nSkew;
    1595           0 :                                 nTopRight += nSkew;
    1596           0 :                                 break;
    1597             :                             case SVX_ROTATE_MODE_CENTER:
    1598           0 :                                 nSkew /= 2;
    1599           0 :                                 nTopLeft += nSkew;
    1600           0 :                                 nTopRight += nSkew;
    1601           0 :                                 nBotLeft -= nSkew;
    1602           0 :                                 nBotRight -= nSkew;
    1603           0 :                                 break;
    1604             :                             case SVX_ROTATE_MODE_TOP:
    1605           0 :                                 nBotLeft -= nSkew;
    1606           0 :                                 nBotRight -= nSkew;
    1607           0 :                                 break;
    1608             :                             default:
    1609             :                             {
    1610             :                                 // added to avoid warnings
    1611             :                             }
    1612             :                         }
    1613             : 
    1614           0 :                         Point aPoints[4];
    1615           0 :                         aPoints[0] = Point( nTopLeft, nTop );
    1616           0 :                         aPoints[1] = Point( nTopRight, nTop );
    1617           0 :                         aPoints[2] = Point( nBotRight, nBottom );
    1618           0 :                         aPoints[3] = Point( nBotLeft, nBottom );
    1619             : 
    1620           0 :                         const SvxBrushItem* pBackground = pInfo->pBackground;
    1621           0 :                         if (!pBackground)
    1622             :                             pBackground = static_cast<const SvxBrushItem*>( &pPattern->GetItem(
    1623           0 :                                                 ATTR_BACKGROUND, pCondSet ));
    1624           0 :                         if (bCellContrast)
    1625             :                         {
    1626             :                             //  high contrast for cell borders and backgrounds -> empty background
    1627           0 :                             pBackground = ScGlobal::GetEmptyBrushItem();
    1628             :                         }
    1629           0 :                         if(!pInfo->pColorScale)
    1630             :                         {
    1631           0 :                             const Color& rColor = pBackground->GetColor();
    1632           0 :                             if ( rColor.GetTransparency() != 255 )
    1633             :                             {
    1634             :                                 //  draw background only for the changed row itself
    1635             :                                 //  (background doesn't extend into other cells).
    1636             :                                 //  For the borders (rotated and normal), clipping should be
    1637             :                                 //  set if the row isn't changed, but at least the borders
    1638             :                                 //  don't cover the cell contents.
    1639           0 :                                 if ( rThisRowInfo.bChanged )
    1640             :                                 {
    1641           0 :                                     Polygon aPoly( 4, aPoints );
    1642             : 
    1643             :                                     //  ohne Pen wird bei DrawPolygon rechts und unten
    1644             :                                     //  ein Pixel weggelassen...
    1645           0 :                                     if ( rColor.GetTransparency() == 0 )
    1646           0 :                                         mpDev->SetLineColor(rColor);
    1647             :                                     else
    1648           0 :                                         mpDev->SetLineColor();
    1649           0 :                                     mpDev->SetFillColor(rColor);
    1650           0 :                                     mpDev->DrawPolygon( aPoly );
    1651             :                                 }
    1652             :                             }
    1653             :                         }
    1654             :                         else
    1655             :                         {
    1656           0 :                             Polygon aPoly( 4, aPoints );
    1657           0 :                             const Color* pColor = pInfo->pColorScale.get();
    1658             : 
    1659             :                             //  ohne Pen wird bei DrawPolygon rechts und unten
    1660             :                             //  ein Pixel weggelassen...
    1661           0 :                             if ( pColor->GetTransparency() == 0 )
    1662           0 :                                 mpDev->SetLineColor(*pColor);
    1663             :                             else
    1664           0 :                                 mpDev->SetLineColor();
    1665           0 :                             mpDev->SetFillColor(*pColor);
    1666           0 :                             mpDev->DrawPolygon( aPoly );
    1667             : 
    1668             :                         }
    1669             : 
    1670           0 :                         svx::frame::Style aTopLine, aBottomLine, aLeftLine, aRightLine;
    1671             : 
    1672           0 :                         if ( nX < nX1 || nX > nX2 )     // Attribute in FillInfo nicht gesetzt
    1673             :                         {
    1674             :                             //! Seitengrenzen fuer Druck beruecksichtigen !!!!!
    1675             :                             const ::editeng::SvxBorderLine* pLeftLine;
    1676             :                             const ::editeng::SvxBorderLine* pTopLine;
    1677             :                             const ::editeng::SvxBorderLine* pRightLine;
    1678             :                             const ::editeng::SvxBorderLine* pBottomLine;
    1679             :                             mpDoc->GetBorderLines( nX, nY, nTab,
    1680           0 :                                     &pLeftLine, &pTopLine, &pRightLine, &pBottomLine );
    1681           0 :                             aTopLine.Set( pTopLine, mnPPTY );
    1682           0 :                             aBottomLine.Set( pBottomLine, mnPPTY );
    1683           0 :                             aLeftLine.Set( pLeftLine, mnPPTX );
    1684           0 :                             aRightLine.Set( pRightLine, mnPPTX );
    1685             :                         }
    1686             :                         else
    1687             :                         {
    1688           0 :                             size_t nCol = lclGetArrayColFromCellInfoX( nArrX, nX1, nX2, bLayoutRTL );
    1689           0 :                             aTopLine = rArray.GetCellStyleTop( nCol, nRow );
    1690           0 :                             aBottomLine = rArray.GetCellStyleBottom( nCol, nRow );
    1691           0 :                             aLeftLine = rArray.GetCellStyleLeft( nCol, nRow );
    1692           0 :                             aRightLine = rArray.GetCellStyleRight( nCol, nRow );
    1693             :                             // in RTL mode the array is already mirrored -> swap back left/right borders
    1694           0 :                             if( bLayoutRTL )
    1695           0 :                                 std::swap( aLeftLine, aRightLine );
    1696             :                         }
    1697             : 
    1698             :                         // Horizontal lines
    1699           0 :                         if (aTopLine.Prim() || aTopLine.Secn())
    1700             :                         {
    1701           0 :                             long nUpperRotate = lcl_getRotate( mpDoc, nTab, nX, nY - 1 );
    1702             :                             pProcessor->process( svx::frame::CreateBorderPrimitives(
    1703           0 :                                         aPoints[bLayoutRTL?1:0], aPoints[bLayoutRTL?0:1], aTopLine,
    1704             :                                         svx::frame::Style(),
    1705             :                                         svx::frame::Style(),
    1706             :                                         aLeftLine,
    1707             :                                         svx::frame::Style(),
    1708             :                                         svx::frame::Style(),
    1709             :                                         aRightLine,
    1710           0 :                                         pForceColor, nUpperRotate, nAttrRotate ) );
    1711             :                         }
    1712             : 
    1713           0 :                         if (aBottomLine.Prim() || aBottomLine.Secn())
    1714             :                         {
    1715           0 :                             long nLowerRotate = lcl_getRotate( mpDoc, nTab, nX, nY + 1 );
    1716             :                             pProcessor->process( svx::frame::CreateBorderPrimitives(
    1717           0 :                                         aPoints[bLayoutRTL?2:3], aPoints[bLayoutRTL?3:2], aBottomLine,
    1718             :                                         aLeftLine,
    1719             :                                         svx::frame::Style(),
    1720             :                                         svx::frame::Style(),
    1721             :                                         aRightLine,
    1722             :                                         svx::frame::Style(),
    1723             :                                         svx::frame::Style(),
    1724           0 :                                         pForceColor, 18000 - nAttrRotate, 18000 - nLowerRotate ) );
    1725             :                         }
    1726             : 
    1727             :                         // Vertical slanted lines
    1728           0 :                         if (aLeftLine.Prim() || aLeftLine.Secn())
    1729             :                         {
    1730           0 :                             long nLeftRotate = lcl_getRotate( mpDoc, nTab, nX - 1, nY );
    1731             :                             pProcessor->process( svx::frame::CreateBorderPrimitives(
    1732             :                                         aPoints[0], aPoints[3], aLeftLine,
    1733             :                                         aTopLine,
    1734             :                                         svx::frame::Style(),
    1735             :                                         svx::frame::Style(),
    1736             :                                         aBottomLine,
    1737             :                                         svx::frame::Style(),
    1738             :                                         svx::frame::Style(),
    1739           0 :                                         pForceColor, nAttrRotate, nLeftRotate ) );
    1740             :                         }
    1741             : 
    1742           0 :                         if (aRightLine.Prim() || aRightLine.Secn())
    1743             :                         {
    1744           0 :                             long nRightRotate = lcl_getRotate( mpDoc, nTab, nX + 1, nY );
    1745             :                             pProcessor->process( svx::frame::CreateBorderPrimitives(
    1746             :                                         aPoints[1], aPoints[2], aRightLine,
    1747             :                                         svx::frame::Style(),
    1748             :                                         svx::frame::Style(),
    1749             :                                         aTopLine,
    1750             :                                         svx::frame::Style(),
    1751             :                                         svx::frame::Style(),
    1752             :                                         aBottomLine,
    1753           0 :                                         pForceColor, 18000 - nRightRotate, 18000 - nAttrRotate ) );
    1754             :                         }
    1755             :                     }
    1756             :                 }
    1757        5949 :                 nPosX += nColWidth * nLayoutSign;
    1758             :             }
    1759             : 
    1760             :             //  erst hinterher im zweiten Schritt die Linien fuer normale Ausgabe loeschen
    1761             : 
    1762         661 :             nX = nX1 > 0 ? (nX1-1) : static_cast<SCCOL>(0);
    1763        7271 :             for (; nX<=nX2+1; nX++)         // sichtbarer Teil +- 1
    1764             :             {
    1765        6610 :                 sal_uInt16 nArrX = nX + 1;
    1766        6610 :                 CellInfo& rInfo = rThisRowInfo.pCellInfo[nArrX];
    1767        6610 :                 if ( rInfo.nRotateDir > SC_ROTDIR_STANDARD &&
    1768           0 :                         !rInfo.bHOverlapped && !rInfo.bVOverlapped )
    1769             :                 {
    1770           0 :                     size_t nCol = lclGetArrayColFromCellInfoX( nArrX, nX1, nX2, bLayoutRTL );
    1771             : 
    1772             :                     //  horizontal: angrenzende Linie verlaengern
    1773             :                     //  (nur, wenn die gedrehte Zelle eine Umrandung hat)
    1774           0 :                     sal_uInt16 nDir = rInfo.nRotateDir;
    1775           0 :                     if ( rArray.GetCellStyleTop( nCol, nRow ).Prim() )
    1776             :                     {
    1777           0 :                         svx::frame::Style aStyle( lcl_FindHorLine( mpDoc, nX, nY, nTab, nDir, true ), mnPPTY );
    1778           0 :                         rArray.SetCellStyleTop( nCol, nRow, aStyle );
    1779           0 :                         if( nRow > 0 )
    1780           0 :                             rArray.SetCellStyleBottom( nCol, nRow - 1, aStyle );
    1781             :                     }
    1782           0 :                     if ( rArray.GetCellStyleBottom( nCol, nRow ).Prim() )
    1783             :                     {
    1784           0 :                         svx::frame::Style aStyle( lcl_FindHorLine( mpDoc, nX, nY, nTab, nDir, false ), mnPPTY );
    1785           0 :                         rArray.SetCellStyleBottom( nCol, nRow, aStyle );
    1786           0 :                         if( nRow + 1 < rArray.GetRowCount() )
    1787           0 :                             rArray.SetCellStyleTop( nCol, nRow + 1, aStyle );
    1788             :                     }
    1789             : 
    1790             :                     // always remove vertical borders
    1791           0 :                     if( !rArray.IsMergedOverlappedLeft( nCol, nRow ) )
    1792             :                     {
    1793           0 :                         rArray.SetCellStyleLeft( nCol, nRow, svx::frame::Style() );
    1794           0 :                         if( nCol > 0 )
    1795           0 :                             rArray.SetCellStyleRight( nCol - 1, nRow, svx::frame::Style() );
    1796             :                     }
    1797           0 :                     if( !rArray.IsMergedOverlappedRight( nCol, nRow ) )
    1798             :                     {
    1799           0 :                         rArray.SetCellStyleRight( nCol, nRow, svx::frame::Style() );
    1800           0 :                         if( nCol + 1 < rArray.GetColCount() )
    1801           0 :                             rArray.SetCellStyleLeft( nCol + 1, nRow, svx::frame::Style() );
    1802             :                     }
    1803             : 
    1804             :                     // remove diagonal borders
    1805           0 :                     rArray.SetCellStyleTLBR( nCol, nRow, svx::frame::Style() );
    1806           0 :                     rArray.SetCellStyleBLTR( nCol, nRow, svx::frame::Style() );
    1807             :                 }
    1808             :             }
    1809             :         }
    1810         728 :         nPosY += nRowHeight;
    1811             :     }
    1812             : 
    1813         162 :     pProcessor.reset();
    1814             : 
    1815         162 :     if (bMetaFile)
    1816           0 :         mpDev->Pop();
    1817             :     else
    1818         162 :         mpDev->SetClipRegion();
    1819         162 : }
    1820             : 
    1821        3153 : drawinglayer::processor2d::BaseProcessor2D* ScOutputData::CreateProcessor2D( )
    1822             : {
    1823        3153 :     mpDoc->InitDrawLayer(mpDoc->GetDocumentShell());
    1824        3153 :     ScDrawLayer* pDrawLayer = mpDoc->GetDrawLayer();
    1825        3153 :     if (!pDrawLayer)
    1826           0 :         return NULL;
    1827             : 
    1828        3153 :     basegfx::B2DRange aViewRange;
    1829        3153 :     SdrPage *pDrawPage = pDrawLayer->GetPage( static_cast< sal_uInt16 >( nTab ) );
    1830             :     const drawinglayer::geometry::ViewInformation2D aNewViewInfos(
    1831             :             basegfx::B2DHomMatrix(  ),
    1832             :             mpDev->GetViewTransformation(),
    1833             :             aViewRange,
    1834             :             GetXDrawPageForSdrPage( pDrawPage ),
    1835             :             0.0,
    1836        3153 :             uno::Sequence< beans::PropertyValue >() );
    1837             : 
    1838             :     return drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
    1839        3153 :                     *mpDev, aNewViewInfos );
    1840             : }
    1841             : 
    1842             : // Printer
    1843             : 
    1844        7492 : vcl::Region ScOutputData::GetChangedAreaRegion()
    1845             : {
    1846        7492 :     vcl::Region aRegion;
    1847        7492 :     Rectangle aDrawingRect;
    1848        7492 :     bool bHad(false);
    1849        7492 :     long nPosY = nScrY;
    1850             :     SCSIZE nArrY;
    1851             : 
    1852        7492 :     aDrawingRect.Left() = nScrX;
    1853        7492 :     aDrawingRect.Right() = nScrX+nScrW-1;
    1854             : 
    1855      194989 :     for(nArrY=1; nArrY+1<nArrCount; nArrY++)
    1856             :     {
    1857      187497 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
    1858             : 
    1859      187497 :         if(pThisRowInfo->bChanged)
    1860             :         {
    1861          84 :             if(!bHad)
    1862             :             {
    1863          71 :                 aDrawingRect.Top() = nPosY;
    1864          71 :                 bHad = true;
    1865             :             }
    1866             : 
    1867          84 :             aDrawingRect.Bottom() = nPosY + pRowInfo[nArrY].nHeight - 1;
    1868             :         }
    1869      187413 :         else if(bHad)
    1870             :         {
    1871          71 :             aRegion.Union(mpDev->PixelToLogic(aDrawingRect));
    1872          71 :             bHad = false;
    1873             :         }
    1874             : 
    1875      187497 :         nPosY += pRowInfo[nArrY].nHeight;
    1876             :     }
    1877             : 
    1878        7492 :     if(bHad)
    1879             :     {
    1880           0 :         aRegion.Union(mpDev->PixelToLogic(aDrawingRect));
    1881             :     }
    1882             : 
    1883        7492 :     return aRegion;
    1884             : }
    1885             : 
    1886           0 : bool ScOutputData::SetChangedClip()
    1887             : {
    1888           0 :     tools::PolyPolygon aPoly;
    1889             : 
    1890           0 :     Rectangle aDrawingRect;
    1891           0 :     aDrawingRect.Left() = nScrX;
    1892           0 :     aDrawingRect.Right() = nScrX+nScrW-1;
    1893             : 
    1894           0 :     bool    bHad    = false;
    1895           0 :     long    nPosY   = nScrY;
    1896             :     SCSIZE  nArrY;
    1897           0 :     for (nArrY=1; nArrY+1<nArrCount; nArrY++)
    1898             :     {
    1899           0 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
    1900             : 
    1901           0 :         if ( pThisRowInfo->bChanged )
    1902             :         {
    1903           0 :             if (!bHad)
    1904             :             {
    1905           0 :                 aDrawingRect.Top() = nPosY;
    1906           0 :                 bHad = true;
    1907             :             }
    1908           0 :             aDrawingRect.Bottom() = nPosY + pRowInfo[nArrY].nHeight - 1;
    1909             :         }
    1910           0 :         else if (bHad)
    1911             :         {
    1912           0 :             aPoly.Insert( Polygon( mpDev->PixelToLogic(aDrawingRect) ) );
    1913           0 :             bHad = false;
    1914             :         }
    1915           0 :         nPosY += pRowInfo[nArrY].nHeight;
    1916             :     }
    1917             : 
    1918           0 :     if (bHad)
    1919           0 :         aPoly.Insert( Polygon( mpDev->PixelToLogic(aDrawingRect) ) );
    1920             : 
    1921           0 :     bool bRet = (aPoly.Count() != 0);
    1922           0 :     if (bRet)
    1923           0 :         mpDev->SetClipRegion(vcl::Region(aPoly));
    1924           0 :     return bRet;
    1925             : }
    1926             : 
    1927        7492 : void ScOutputData::FindChanged()
    1928             : {
    1929             :     SCCOL   nX;
    1930             :     SCSIZE  nArrY;
    1931             : 
    1932        7492 :     bool bWasIdleEnabled = mpDoc->IsIdleEnabled();
    1933        7492 :     mpDoc->EnableIdle(false);
    1934      209973 :     for (nArrY=0; nArrY<nArrCount; nArrY++)
    1935      202481 :         pRowInfo[nArrY].bChanged = false;
    1936             : 
    1937        7492 :     bool bProgress = false;
    1938      209973 :     for (nArrY=0; nArrY<nArrCount; nArrY++)
    1939             :     {
    1940      202481 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
    1941     2217300 :         for (nX=nX1; nX<=nX2; nX++)
    1942             :         {
    1943     2014819 :             const ScRefCellValue& rCell = pThisRowInfo->pCellInfo[nX+1].maCell;
    1944             : 
    1945     2014819 :             if (rCell.meType != CELLTYPE_FORMULA)
    1946     2010839 :                 continue;
    1947             : 
    1948        3980 :             ScFormulaCell* pFCell = rCell.mpFormula;
    1949        3980 :             if ( !bProgress && pFCell->GetDirty() )
    1950             :             {
    1951          57 :                 ScProgress::CreateInterpretProgress(mpDoc, true);
    1952          57 :                 bProgress = true;
    1953             :             }
    1954        3980 :             if (pFCell->IsRunning())
    1955             :                 // still being interpreted. Skip it.
    1956           0 :                 continue;
    1957             : 
    1958        3980 :             (void)pFCell->GetValue();
    1959        3980 :             if (!pFCell->IsChanged())
    1960             :                 // the result hasn't changed. Skip it.
    1961        3826 :                 continue;
    1962             : 
    1963         154 :             pThisRowInfo->bChanged = true;
    1964         154 :             if ( pThisRowInfo->pCellInfo[nX+1].bMerged )
    1965             :             {
    1966           0 :                 SCSIZE nOverY = nArrY + 1;
    1967           0 :                 while ( nOverY<nArrCount &&
    1968           0 :                         pRowInfo[nOverY].pCellInfo[nX+1].bVOverlapped )
    1969             :                 {
    1970           0 :                     pRowInfo[nOverY].bChanged = true;
    1971           0 :                     ++nOverY;
    1972             :                 }
    1973             :             }
    1974             :         }
    1975             :     }
    1976        7492 :     if ( bProgress )
    1977          57 :         ScProgress::DeleteInterpretProgress();
    1978        7492 :     mpDoc->EnableIdle(bWasIdleEnabled);
    1979        7492 : }
    1980             : 
    1981           0 : void ScOutputData::DrawRefMark( SCCOL nRefStartX, SCROW nRefStartY,
    1982             :                                 SCCOL nRefEndX, SCROW nRefEndY,
    1983             :                                 const Color& rColor, bool bHandle )
    1984             : {
    1985           0 :     PutInOrder( nRefStartX, nRefEndX );
    1986           0 :     PutInOrder( nRefStartY, nRefEndY );
    1987             : 
    1988           0 :     if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
    1989           0 :         mpDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
    1990             : 
    1991           0 :     if ( nRefStartX <= nVisX2 && nRefEndX >= nVisX1 &&
    1992           0 :          nRefStartY <= nVisY2 && nRefEndY >= nVisY1 )
    1993             :     {
    1994           0 :         long nMinX = nScrX;
    1995           0 :         long nMinY = nScrY;
    1996           0 :         long nMaxX = nScrX + nScrW - 1;
    1997           0 :         long nMaxY = nScrY + nScrH - 1;
    1998           0 :         if ( bLayoutRTL )
    1999             :         {
    2000           0 :             long nTemp = nMinX;
    2001           0 :             nMinX = nMaxX;
    2002           0 :             nMaxX = nTemp;
    2003             :         }
    2004           0 :         long nLayoutSign = bLayoutRTL ? -1 : 1;
    2005             : 
    2006           0 :         bool bTop    = false;
    2007           0 :         bool bBottom = false;
    2008           0 :         bool bLeft   = false;
    2009           0 :         bool bRight  = false;
    2010             : 
    2011           0 :         long nPosY = nScrY;
    2012           0 :         bool bNoStartY = ( nY1 < nRefStartY );
    2013           0 :         bool bNoEndY   = false;
    2014           0 :         for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)      // loop to end for bNoEndY check
    2015             :         {
    2016           0 :             SCROW nY = pRowInfo[nArrY].nRowNo;
    2017             : 
    2018           0 :             if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
    2019             :             {
    2020           0 :                 nMinY = nPosY;
    2021           0 :                 bTop = true;
    2022             :             }
    2023           0 :             if ( nY==nRefEndY )
    2024             :             {
    2025           0 :                 nMaxY = nPosY + pRowInfo[nArrY].nHeight - 2;
    2026           0 :                 bBottom = true;
    2027             :             }
    2028           0 :             if ( nY>nRefEndY && bNoEndY )
    2029             :             {
    2030           0 :                 nMaxY = nPosY-2;
    2031           0 :                 bBottom = true;
    2032             :             }
    2033           0 :             bNoStartY = ( nY < nRefStartY );
    2034           0 :             bNoEndY   = ( nY < nRefEndY );
    2035           0 :             nPosY += pRowInfo[nArrY].nHeight;
    2036             :         }
    2037             : 
    2038           0 :         long nPosX = nScrX;
    2039           0 :         if ( bLayoutRTL )
    2040           0 :             nPosX += nMirrorW - 1;      // always in pixels
    2041             : 
    2042           0 :         for (SCCOL nX=nX1; nX<=nX2; nX++)
    2043             :         {
    2044           0 :             if ( nX==nRefStartX )
    2045             :             {
    2046           0 :                 nMinX = nPosX;
    2047           0 :                 bLeft = true;
    2048             :             }
    2049           0 :             if ( nX==nRefEndX )
    2050             :             {
    2051           0 :                 nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 2 ) * nLayoutSign;
    2052           0 :                 bRight = true;
    2053             :             }
    2054           0 :             nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
    2055             :         }
    2056             : 
    2057           0 :         if ( nMaxX * nLayoutSign >= nMinX * nLayoutSign &&
    2058             :              nMaxY >= nMinY )
    2059             :         {
    2060           0 :             mpDev->SetLineColor( rColor );
    2061           0 :             if (bTop && bBottom && bLeft && bRight)
    2062             :             {
    2063           0 :                 mpDev->SetFillColor();
    2064           0 :                 mpDev->DrawRect( Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
    2065             :             }
    2066             :             else
    2067             :             {
    2068           0 :                 if (bTop)
    2069           0 :                     mpDev->DrawLine( Point( nMinX, nMinY ), Point( nMaxX, nMinY ) );
    2070           0 :                 if (bBottom)
    2071           0 :                     mpDev->DrawLine( Point( nMinX, nMaxY ), Point( nMaxX, nMaxY ) );
    2072           0 :                 if (bLeft)
    2073           0 :                     mpDev->DrawLine( Point( nMinX, nMinY ), Point( nMinX, nMaxY ) );
    2074           0 :                 if (bRight)
    2075           0 :                     mpDev->DrawLine( Point( nMaxX, nMinY ), Point( nMaxX, nMaxY ) );
    2076             :             }
    2077           0 :             if ( bHandle && bRight && bBottom )
    2078             :             {
    2079           0 :                 mpDev->SetLineColor( rColor );
    2080           0 :                 mpDev->SetFillColor( rColor );
    2081             : 
    2082           0 :                 const sal_Int32 aRadius = 4;
    2083             : 
    2084           0 :                 sal_Int32 aRectMaxX1 = nMaxX - nLayoutSign * aRadius;
    2085           0 :                 sal_Int32 aRectMaxX2 = nMaxX + nLayoutSign;
    2086           0 :                 sal_Int32 aRectMinX1 = nMinX - nLayoutSign;
    2087           0 :                 sal_Int32 aRectMinX2 = nMinX + nLayoutSign * aRadius;
    2088             : 
    2089           0 :                 sal_Int32 aRectMaxY1 = nMaxY - aRadius;
    2090           0 :                 sal_Int32 aRectMaxY2 = nMaxY + 1;
    2091           0 :                 sal_Int32 aRectMinY1 = nMinY - 1;
    2092           0 :                 sal_Int32 aRectMinY2 = nMinY + aRadius;
    2093             : 
    2094             :                 // Draw corner rectangles
    2095           0 :                 Rectangle aLowerRight( aRectMaxX1, aRectMaxY1, aRectMaxX2, aRectMaxY2 );
    2096           0 :                 Rectangle aUpperLeft ( aRectMinX1, aRectMinY1, aRectMinX2, aRectMinY2 );
    2097           0 :                 Rectangle aLowerLeft ( aRectMinX1, aRectMaxY1, aRectMinX2, aRectMaxY2 );
    2098           0 :                 Rectangle aUpperRight( aRectMaxX1, aRectMinY1, aRectMaxX2, aRectMinY2 );
    2099             : 
    2100           0 :                 mpDev->DrawTransparent( tools::PolyPolygon( Polygon( aLowerRight ) ), lclCornerRectTransparency );
    2101           0 :                 mpDev->DrawTransparent( tools::PolyPolygon( Polygon( aUpperLeft  ) ), lclCornerRectTransparency );
    2102           0 :                 mpDev->DrawTransparent( tools::PolyPolygon( Polygon( aLowerLeft  ) ), lclCornerRectTransparency );
    2103           0 :                 mpDev->DrawTransparent( tools::PolyPolygon( Polygon( aUpperRight ) ), lclCornerRectTransparency );
    2104             :             }
    2105             :         }
    2106             :     }
    2107           0 : }
    2108             : 
    2109           0 : void ScOutputData::DrawOneChange( SCCOL nRefStartX, SCROW nRefStartY,
    2110             :                                 SCCOL nRefEndX, SCROW nRefEndY,
    2111             :                                 const Color& rColor, sal_uInt16 nType )
    2112             : {
    2113           0 :     PutInOrder( nRefStartX, nRefEndX );
    2114           0 :     PutInOrder( nRefStartY, nRefEndY );
    2115             : 
    2116           0 :     if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
    2117           0 :         mpDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
    2118             : 
    2119           0 :     if ( nRefStartX <= nVisX2 + 1 && nRefEndX >= nVisX1 &&
    2120           0 :          nRefStartY <= nVisY2 + 1 && nRefEndY >= nVisY1 )       // +1 because it touches next cells left/top
    2121             :     {
    2122           0 :         long nMinX = nScrX;
    2123           0 :         long nMinY = nScrY;
    2124           0 :         long nMaxX = nScrX+nScrW-1;
    2125           0 :         long nMaxY = nScrY+nScrH-1;
    2126           0 :         if ( bLayoutRTL )
    2127             :         {
    2128           0 :             long nTemp = nMinX;
    2129           0 :             nMinX = nMaxX;
    2130           0 :             nMaxX = nTemp;
    2131             :         }
    2132           0 :         long nLayoutSign = bLayoutRTL ? -1 : 1;
    2133             : 
    2134           0 :         bool bTop    = false;
    2135           0 :         bool bBottom = false;
    2136           0 :         bool bLeft   = false;
    2137           0 :         bool bRight  = false;
    2138             : 
    2139           0 :         long nPosY = nScrY;
    2140           0 :         bool bNoStartY = ( nY1 < nRefStartY );
    2141           0 :         bool bNoEndY   = false;
    2142           0 :         for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)      // loop to end for bNoEndY check
    2143             :         {
    2144           0 :             SCROW nY = pRowInfo[nArrY].nRowNo;
    2145             : 
    2146           0 :             if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
    2147             :             {
    2148           0 :                 nMinY = nPosY - 1;
    2149           0 :                 bTop = true;
    2150             :             }
    2151           0 :             if ( nY==nRefEndY )
    2152             :             {
    2153           0 :                 nMaxY = nPosY + pRowInfo[nArrY].nHeight - 1;
    2154           0 :                 bBottom = true;
    2155             :             }
    2156           0 :             if ( nY>nRefEndY && bNoEndY )
    2157             :             {
    2158           0 :                 nMaxY = nPosY - 1;
    2159           0 :                 bBottom = true;
    2160             :             }
    2161           0 :             bNoStartY = ( nY < nRefStartY );
    2162           0 :             bNoEndY   = ( nY < nRefEndY );
    2163           0 :             nPosY += pRowInfo[nArrY].nHeight;
    2164             :         }
    2165             : 
    2166           0 :         long nPosX = nScrX;
    2167           0 :         if ( bLayoutRTL )
    2168           0 :             nPosX += nMirrorW - 1;      // always in pixels
    2169             : 
    2170           0 :         for (SCCOL nX=nX1; nX<=nX2+1; nX++)
    2171             :         {
    2172           0 :             if ( nX==nRefStartX )
    2173             :             {
    2174           0 :                 nMinX = nPosX - nLayoutSign;
    2175           0 :                 bLeft = true;
    2176             :             }
    2177           0 :             if ( nX==nRefEndX )
    2178             :             {
    2179           0 :                 nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 1 ) * nLayoutSign;
    2180           0 :                 bRight = true;
    2181             :             }
    2182           0 :             nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
    2183             :         }
    2184             : 
    2185           0 :         if ( nMaxX * nLayoutSign >= nMinX * nLayoutSign &&
    2186             :              nMaxY >= nMinY )
    2187             :         {
    2188           0 :             if ( nType == SC_CAT_DELETE_ROWS )
    2189           0 :                 bLeft = bRight = bBottom = false;       //! thick lines???
    2190           0 :             else if ( nType == SC_CAT_DELETE_COLS )
    2191           0 :                 bTop = bBottom = bRight = false;        //! thick lines???
    2192             : 
    2193           0 :             mpDev->SetLineColor( rColor );
    2194           0 :             if (bTop && bBottom && bLeft && bRight)
    2195             :             {
    2196           0 :                 mpDev->SetFillColor();
    2197           0 :                 mpDev->DrawRect( Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
    2198             :             }
    2199             :             else
    2200             :             {
    2201           0 :                 if (bTop)
    2202             :                 {
    2203           0 :                     mpDev->DrawLine( Point( nMinX,nMinY ), Point( nMaxX,nMinY ) );
    2204           0 :                     if ( nType == SC_CAT_DELETE_ROWS )
    2205           0 :                         mpDev->DrawLine( Point( nMinX,nMinY+1 ), Point( nMaxX,nMinY+1 ) );
    2206             :                 }
    2207           0 :                 if (bBottom)
    2208           0 :                     mpDev->DrawLine( Point( nMinX,nMaxY ), Point( nMaxX,nMaxY ) );
    2209           0 :                 if (bLeft)
    2210             :                 {
    2211           0 :                     mpDev->DrawLine( Point( nMinX,nMinY ), Point( nMinX,nMaxY ) );
    2212           0 :                     if ( nType == SC_CAT_DELETE_COLS )
    2213           0 :                         mpDev->DrawLine( Point( nMinX+nLayoutSign,nMinY ), Point( nMinX+nLayoutSign,nMaxY ) );
    2214             :                 }
    2215           0 :                 if (bRight)
    2216           0 :                     mpDev->DrawLine( Point( nMaxX,nMinY ), Point( nMaxX,nMaxY ) );
    2217             :             }
    2218           0 :             if ( bLeft && bTop )
    2219             :             {
    2220           0 :                 mpDev->SetLineColor();
    2221           0 :                 mpDev->SetFillColor( rColor );
    2222           0 :                 mpDev->DrawRect( Rectangle( nMinX+nLayoutSign, nMinY+1, nMinX+3*nLayoutSign, nMinY+3 ) );
    2223             :             }
    2224             :         }
    2225             :     }
    2226           0 : }
    2227             : 
    2228          15 : void ScOutputData::DrawChangeTrack()
    2229             : {
    2230          15 :     ScChangeTrack* pTrack = mpDoc->GetChangeTrack();
    2231          15 :     ScChangeViewSettings* pSettings = mpDoc->GetChangeViewSettings();
    2232          15 :     if ( !pTrack || !pTrack->GetFirst() || !pSettings || !pSettings->ShowChanges() )
    2233          30 :         return;         // nix da oder abgeschaltet
    2234             : 
    2235           0 :     ScActionColorChanger aColorChanger(*pTrack);
    2236             : 
    2237             :     //  Clipping passiert von aussen
    2238             :     //! ohne Clipping, nur betroffene Zeilen painten ??!??!?
    2239             : 
    2240           0 :     SCCOL nEndX = nX2;
    2241           0 :     SCROW nEndY = nY2;
    2242           0 :     if ( nEndX < MAXCOL ) ++nEndX;      // auch noch von der naechsten Zelle, weil die Markierung
    2243           0 :     if ( nEndY < MAXROW ) ++nEndY;      // in die jeweils vorhergehende Zelle hineinragt
    2244           0 :     ScRange aViewRange( nX1, nY1, nTab, nEndX, nEndY, nTab );
    2245           0 :     const ScChangeAction* pAction = pTrack->GetFirst();
    2246           0 :     while (pAction)
    2247             :     {
    2248             :         ScChangeActionType eActionType;
    2249           0 :         if ( pAction->IsVisible() )
    2250             :         {
    2251           0 :             eActionType = pAction->GetType();
    2252           0 :             const ScBigRange& rBig = pAction->GetBigRange();
    2253           0 :             if ( rBig.aStart.Tab() == nTab )
    2254             :             {
    2255           0 :                 ScRange aRange = rBig.MakeRange();
    2256             : 
    2257           0 :                 if ( eActionType == SC_CAT_DELETE_ROWS )
    2258           0 :                     aRange.aEnd.SetRow( aRange.aStart.Row() );
    2259           0 :                 else if ( eActionType == SC_CAT_DELETE_COLS )
    2260           0 :                     aRange.aEnd.SetCol( aRange.aStart.Col() );
    2261             : 
    2262           0 :                 if ( aRange.Intersects( aViewRange ) &&
    2263           0 :                      ScViewUtil::IsActionShown( *pAction, *pSettings, *mpDoc ) )
    2264             :                 {
    2265           0 :                     aColorChanger.Update( *pAction );
    2266           0 :                     Color aColor( aColorChanger.GetColor() );
    2267           0 :                     DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
    2268           0 :                                     aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
    2269             : 
    2270             :                 }
    2271             :             }
    2272           0 :             if ( eActionType == SC_CAT_MOVE &&
    2273             :                     static_cast<const ScChangeActionMove*>(pAction)->
    2274           0 :                         GetFromRange().aStart.Tab() == nTab )
    2275             :             {
    2276             :                 ScRange aRange = static_cast<const ScChangeActionMove*>(pAction)->
    2277           0 :                         GetFromRange().MakeRange();
    2278           0 :                 if ( aRange.Intersects( aViewRange ) &&
    2279           0 :                      ScViewUtil::IsActionShown( *pAction, *pSettings, *mpDoc ) )
    2280             :                 {
    2281           0 :                     aColorChanger.Update( *pAction );
    2282           0 :                     Color aColor( aColorChanger.GetColor() );
    2283           0 :                     DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
    2284           0 :                                     aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
    2285             :                 }
    2286             :             }
    2287             :         }
    2288             : 
    2289           0 :         pAction = pAction->GetNext();
    2290           0 :     }
    2291             : }
    2292             : 
    2293             : //TODO: moggi Need to check if this can't be written simpler
    2294        2964 : void ScOutputData::DrawNoteMarks()
    2295             : {
    2296             : 
    2297        2964 :     bool bFirst = true;
    2298             : 
    2299        2964 :     long nInitPosX = nScrX;
    2300        2964 :     if ( bLayoutRTL )
    2301           1 :         nInitPosX += nMirrorW - 1;              // always in pixels
    2302        2964 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
    2303             : 
    2304        2964 :     long nPosY = nScrY;
    2305       25913 :     for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
    2306             :     {
    2307       22949 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
    2308       22949 :         if ( pThisRowInfo->bChanged )
    2309             :         {
    2310       22949 :             long nPosX = nInitPosX;
    2311      228977 :             for (SCCOL nX=nX1; nX<=nX2; nX++)
    2312             :             {
    2313      206028 :                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
    2314      206028 :                 bool bIsMerged = false;
    2315             : 
    2316      206028 :                 if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
    2317             :                 {
    2318             :                     // find start of merged cell
    2319           0 :                     bIsMerged = true;
    2320           0 :                     SCROW nY = pRowInfo[nArrY].nRowNo;
    2321           0 :                     SCCOL nMergeX = nX;
    2322           0 :                     SCROW nMergeY = nY;
    2323           0 :                     mpDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
    2324             :                     // use origin's pCell for NotePtr test below
    2325             :                 }
    2326             : 
    2327      206038 :                 if ( mpDoc->GetNote(nX, pRowInfo[nArrY].nRowNo, nTab) && ( bIsMerged ||
    2328          10 :                         ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
    2329             :                 {
    2330           5 :                     if (bFirst)
    2331             :                     {
    2332           4 :                         mpDev->SetLineColor(COL_WHITE);
    2333             : 
    2334           4 :                         const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    2335           4 :                         if ( mbUseStyleColor && rStyleSettings.GetHighContrastMode() )
    2336           0 :                             mpDev->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
    2337             :                         else
    2338           4 :                             mpDev->SetFillColor(COL_LIGHTRED);
    2339             : 
    2340           4 :                         bFirst = false;
    2341             :                     }
    2342             : 
    2343           5 :                     long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 4 ) * nLayoutSign;
    2344           5 :                     if ( bIsMerged || pInfo->bMerged )
    2345             :                     {
    2346             :                         //  if merged, add widths of all cells
    2347           0 :                         SCCOL nNextX = nX + 1;
    2348           0 :                         while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
    2349             :                         {
    2350           0 :                             nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
    2351           0 :                             ++nNextX;
    2352             :                         }
    2353             :                     }
    2354           5 :                     if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
    2355           5 :                         mpDev->DrawRect( Rectangle( nMarkX-5*nLayoutSign,nPosY,nMarkX+1*nLayoutSign,nPosY+6 ) );
    2356             :                 }
    2357             : 
    2358      206028 :                 nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
    2359             :             }
    2360             :         }
    2361       22949 :         nPosY += pThisRowInfo->nHeight;
    2362             :     }
    2363        2964 : }
    2364             : 
    2365          22 : void ScOutputData::AddPDFNotes()
    2366             : {
    2367          22 :     vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, mpDev->GetExtOutDevData() );
    2368          22 :     if ( !pPDFData || !pPDFData->GetIsExportNotes() )
    2369          44 :         return;
    2370             : 
    2371           0 :     long nInitPosX = nScrX;
    2372           0 :     if ( bLayoutRTL )
    2373             :     {
    2374           0 :         Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
    2375           0 :         long nOneX = aOnePixel.Width();
    2376           0 :         nInitPosX += nMirrorW - nOneX;
    2377             :     }
    2378           0 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
    2379             : 
    2380           0 :     long nPosY = nScrY;
    2381           0 :     for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
    2382             :     {
    2383           0 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
    2384           0 :         if ( pThisRowInfo->bChanged )
    2385             :         {
    2386           0 :             long nPosX = nInitPosX;
    2387           0 :             for (SCCOL nX=nX1; nX<=nX2; nX++)
    2388             :             {
    2389           0 :                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
    2390           0 :                 bool bIsMerged = false;
    2391           0 :                 SCROW nY = pRowInfo[nArrY].nRowNo;
    2392           0 :                 SCCOL nMergeX = nX;
    2393           0 :                 SCROW nMergeY = nY;
    2394             : 
    2395           0 :                 if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
    2396             :                 {
    2397             :                     // find start of merged cell
    2398           0 :                     bIsMerged = true;
    2399           0 :                     mpDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
    2400             :                     // use origin's pCell for NotePtr test below
    2401             :                 }
    2402             : 
    2403           0 :                 if ( mpDoc->GetNote(nMergeX, nMergeY, nTab) && ( bIsMerged ||
    2404           0 :                         ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
    2405             :                 {
    2406           0 :                     long nNoteWidth = (long)( SC_CLIPMARK_SIZE * mnPPTX );
    2407           0 :                     long nNoteHeight = (long)( SC_CLIPMARK_SIZE * mnPPTY );
    2408             : 
    2409           0 :                     long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - nNoteWidth ) * nLayoutSign;
    2410           0 :                     if ( bIsMerged || pInfo->bMerged )
    2411             :                     {
    2412             :                         //  if merged, add widths of all cells
    2413           0 :                         SCCOL nNextX = nX + 1;
    2414           0 :                         while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
    2415             :                         {
    2416           0 :                             nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
    2417           0 :                             ++nNextX;
    2418             :                         }
    2419             :                     }
    2420           0 :                     if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
    2421             :                     {
    2422           0 :                         Rectangle aNoteRect( nMarkX, nPosY, nMarkX+nNoteWidth*nLayoutSign, nPosY+nNoteHeight );
    2423           0 :                         const ScPostIt* pNote = mpDoc->GetNote(nMergeX, nMergeY, nTab);
    2424             : 
    2425             :                         // Note title is the cell address (as on printed note pages)
    2426           0 :                         ScAddress aAddress( nMergeX, nMergeY, nTab );
    2427           0 :                         OUString aTitle(aAddress.Format(SCA_VALID, mpDoc, mpDoc->GetAddressConvention()));
    2428             : 
    2429             :                         // Content has to be a simple string without line breaks
    2430           0 :                         OUString aContent = pNote->GetText();
    2431           0 :                         aContent = aContent.replaceAll("\n", " ");
    2432             : 
    2433           0 :                         vcl::PDFNote aNote;
    2434           0 :                         aNote.Title = aTitle;
    2435           0 :                         aNote.Contents = aContent;
    2436           0 :                         pPDFData->CreateNote( aNoteRect, aNote );
    2437             :                     }
    2438             :                 }
    2439             : 
    2440           0 :                 nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
    2441             :             }
    2442             :         }
    2443           0 :         nPosY += pThisRowInfo->nHeight;
    2444             :     }
    2445             : }
    2446             : 
    2447        2964 : void ScOutputData::DrawClipMarks()
    2448             : {
    2449        2964 :     if (!bAnyClipped)
    2450        5819 :         return;
    2451             : 
    2452         109 :     Color aArrowFillCol( COL_LIGHTRED );
    2453             : 
    2454         109 :     DrawModeFlags nOldDrawMode = mpDev->GetDrawMode();
    2455         109 :     const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    2456         109 :     if ( mbUseStyleColor && rStyleSettings.GetHighContrastMode() )
    2457             :     {
    2458             :         //  use DrawMode to change the arrow's outline color
    2459           0 :         mpDev->SetDrawMode( nOldDrawMode | DrawModeFlags::SettingsLine );
    2460             :         //  use text color also for the fill color
    2461           0 :         aArrowFillCol.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
    2462             :     }
    2463             : 
    2464         109 :     long nInitPosX = nScrX;
    2465         109 :     if ( bLayoutRTL )
    2466           0 :         nInitPosX += nMirrorW - 1;              // always in pixels
    2467         109 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
    2468             : 
    2469         109 :     Rectangle aCellRect;
    2470         109 :     long nPosY = nScrY;
    2471         637 :     for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
    2472             :     {
    2473         528 :         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
    2474         528 :         if ( pThisRowInfo->bChanged )
    2475             :         {
    2476         528 :             SCROW nY = pThisRowInfo->nRowNo;
    2477         528 :             long nPosX = nInitPosX;
    2478        6022 :             for (SCCOL nX=nX1; nX<=nX2; nX++)
    2479             :             {
    2480        5494 :                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
    2481        5494 :                 if (pInfo->nClipMark)
    2482             :                 {
    2483         461 :                     if (pInfo->bHOverlapped || pInfo->bVOverlapped)
    2484             :                     {
    2485             :                         //  merge origin may be outside of visible area - use document functions
    2486             : 
    2487           0 :                         SCCOL nOverX = nX;
    2488           0 :                         SCROW nOverY = nY;
    2489           0 :                         long nStartPosX = nPosX;
    2490           0 :                         long nStartPosY = nPosY;
    2491             : 
    2492           0 :                         while ( nOverX > 0 && ( static_cast<const ScMergeFlagAttr*>(mpDoc->GetAttr(
    2493           0 :                                 nOverX, nOverY, nTab, ATTR_MERGE_FLAG ))->GetValue() & SC_MF_HOR ) )
    2494             :                         {
    2495           0 :                             --nOverX;
    2496           0 :                             nStartPosX -= nLayoutSign * (long) ( mpDoc->GetColWidth(nOverX,nTab) * mnPPTX );
    2497             :                         }
    2498             : 
    2499           0 :                         while ( nOverY > 0 && ( static_cast<const ScMergeFlagAttr*>(mpDoc->GetAttr(
    2500           0 :                                 nOverX, nOverY, nTab, ATTR_MERGE_FLAG ))->GetValue() & SC_MF_VER ) )
    2501             :                         {
    2502           0 :                             --nOverY;
    2503           0 :                             nStartPosY -= nLayoutSign * (long) ( mpDoc->GetRowHeight(nOverY,nTab) * mnPPTY );
    2504             :                         }
    2505             : 
    2506           0 :                         long nOutWidth = (long) ( mpDoc->GetColWidth(nOverX,nTab) * mnPPTX );
    2507           0 :                         long nOutHeight = (long) ( mpDoc->GetRowHeight(nOverY,nTab) * mnPPTY );
    2508             : 
    2509             :                         const ScMergeAttr* pMerge = static_cast<const ScMergeAttr*>(
    2510           0 :                                     mpDoc->GetAttr( nOverX, nOverY, nTab, ATTR_MERGE ));
    2511           0 :                         SCCOL nCountX = pMerge->GetColMerge();
    2512           0 :                         for (SCCOL i=1; i<nCountX; i++)
    2513           0 :                             nOutWidth += (long) ( mpDoc->GetColWidth(nOverX+i,nTab) * mnPPTX );
    2514           0 :                         SCROW nCountY = pMerge->GetRowMerge();
    2515           0 :                         nOutHeight += (long) mpDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, mnPPTY);
    2516             : 
    2517           0 :                         if ( bLayoutRTL )
    2518           0 :                             nStartPosX -= nOutWidth - 1;
    2519           0 :                         aCellRect = Rectangle( Point( nStartPosX, nStartPosY ), Size( nOutWidth, nOutHeight ) );
    2520             :                     }
    2521             :                     else
    2522             :                     {
    2523         461 :                         long nOutWidth = pRowInfo[0].pCellInfo[nX+1].nWidth;
    2524         461 :                         long nOutHeight = pThisRowInfo->nHeight;
    2525             : 
    2526         461 :                         if ( pInfo->bMerged && pInfo->pPatternAttr )
    2527             :                         {
    2528           0 :                             SCCOL nOverX = nX;
    2529           0 :                             SCROW nOverY = nY;
    2530             :                             const ScMergeAttr* pMerge =
    2531           0 :                                     static_cast<const ScMergeAttr*>(&pInfo->pPatternAttr->GetItem(ATTR_MERGE));
    2532           0 :                             SCCOL nCountX = pMerge->GetColMerge();
    2533           0 :                             for (SCCOL i=1; i<nCountX; i++)
    2534           0 :                                 nOutWidth += (long) ( mpDoc->GetColWidth(nOverX+i,nTab) * mnPPTX );
    2535           0 :                             SCROW nCountY = pMerge->GetRowMerge();
    2536           0 :                             nOutHeight += (long) mpDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, mnPPTY);
    2537             :                         }
    2538             : 
    2539         461 :                         long nStartPosX = nPosX;
    2540         461 :                         if ( bLayoutRTL )
    2541           0 :                             nStartPosX -= nOutWidth - 1;
    2542             :                         // #i80447# create aCellRect from two points in case nOutWidth is 0
    2543             :                         aCellRect = Rectangle( Point( nStartPosX, nPosY ),
    2544         461 :                                                Point( nStartPosX+nOutWidth-1, nPosY+nOutHeight-1 ) );
    2545             :                     }
    2546             : 
    2547         461 :                     aCellRect.Bottom() -= 1;    // don't paint over the cell grid
    2548         461 :                     if ( bLayoutRTL )
    2549           0 :                         aCellRect.Left() += 1;
    2550             :                     else
    2551         461 :                         aCellRect.Right() -= 1;
    2552             : 
    2553         461 :                     long nMarkPixel = (long)( SC_CLIPMARK_SIZE * mnPPTX );
    2554         461 :                     Size aMarkSize( nMarkPixel, (nMarkPixel-1)*2 );
    2555             : 
    2556         461 :                     if ( pInfo->nClipMark & ( bLayoutRTL ? SC_CLIPMARK_RIGHT : SC_CLIPMARK_LEFT ) )
    2557             :                     {
    2558             :                         //  visually left
    2559         179 :                         Rectangle aMarkRect = aCellRect;
    2560         179 :                         aMarkRect.Right() = aCellRect.Left()+nMarkPixel-1;
    2561         179 :                         SvxFont::DrawArrow( *mpDev, aMarkRect, aMarkSize, aArrowFillCol, true );
    2562             :                     }
    2563         461 :                     if ( pInfo->nClipMark & ( bLayoutRTL ? SC_CLIPMARK_LEFT : SC_CLIPMARK_RIGHT ) )
    2564             :                     {
    2565             :                         //  visually right
    2566         282 :                         Rectangle aMarkRect = aCellRect;
    2567         282 :                         aMarkRect.Left() = aCellRect.Right()-nMarkPixel+1;
    2568         282 :                         SvxFont::DrawArrow( *mpDev, aMarkRect, aMarkSize, aArrowFillCol, false );
    2569             :                     }
    2570             :                 }
    2571        5494 :                 nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
    2572             :             }
    2573             :         }
    2574         528 :         nPosY += pThisRowInfo->nHeight;
    2575             :     }
    2576             : 
    2577         109 :     mpDev->SetDrawMode(nOldDrawMode);
    2578         156 : }
    2579             : 
    2580             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11