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

Generated by: LCOV version 1.10