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

Generated by: LCOV version 1.10