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

Generated by: LCOV version 1.10