LCOV - code coverage report
Current view: top level - sc/source/core/data - fillinfo.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 453 588 77.0 %
Date: 2014-04-11 Functions: 14 14 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : 
       3             : /*
       4             :  * This file is part of the LibreOffice project.
       5             :  *
       6             :  * This Source Code Form is subject to the terms of the Mozilla Public
       7             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       8             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       9             :  *
      10             :  * This file incorporates work covered by the following license notice:
      11             :  *
      12             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      13             :  *   contributor license agreements. See the NOTICE file distributed
      14             :  *   with this work for additional information regarding copyright
      15             :  *   ownership. The ASF licenses this file to you under the Apache
      16             :  *   License, Version 2.0 (the "License"); you may not use this file
      17             :  *   except in compliance with the License. You may obtain a copy of
      18             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      19             :  */
      20             : 
      21             : #include "scitems.hxx"
      22             : #include <editeng/boxitem.hxx>
      23             : #include <editeng/lineitem.hxx>
      24             : #include <editeng/editdata.hxx>
      25             : #include <editeng/shaditem.hxx>
      26             : #include <editeng/brushitem.hxx>
      27             : 
      28             : #include "fillinfo.hxx"
      29             : #include "document.hxx"
      30             : #include "formulacell.hxx"
      31             : #include "table.hxx"
      32             : #include "attrib.hxx"
      33             : #include "attarray.hxx"
      34             : #include "markarr.hxx"
      35             : #include "markdata.hxx"
      36             : #include "patattr.hxx"
      37             : #include "poolhelp.hxx"
      38             : #include "docpool.hxx"
      39             : #include "conditio.hxx"
      40             : #include "colorscale.hxx"
      41             : #include "stlpool.hxx"
      42             : #include "cellvalue.hxx"
      43             : #include "mtvcellfunc.hxx"
      44             : 
      45             : const sal_uInt16 ROWINFO_MAX = 1024;
      46             : 
      47             : 
      48             : enum FillInfoLinePos
      49             :     {
      50             :         FILP_TOP,
      51             :         FILP_BOTTOM,
      52             :         FILP_LEFT,
      53             :         FILP_RIGHT
      54             :     };
      55             : 
      56             : 
      57             : //  aehnlich wie in output.cxx
      58             : 
      59        2009 : static void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY,
      60             :                             ScDocument* pDoc, RowInfo* pRowInfo,
      61             :                             SCCOL nX1, SCROW nY1, SCCOL /* nX2 */, SCROW /* nY2 */, SCTAB nTab,
      62             :                             SCsCOL& rStartX, SCsROW& rStartY, SCsCOL& rEndX, SCsROW& rEndY )
      63             : {
      64        2009 :     CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
      65             : 
      66        2009 :     rStartX = nX;
      67        2009 :     rStartY = nY;
      68        2009 :     bool bHOver = pInfo->bHOverlapped;
      69        2009 :     bool bVOver = pInfo->bVOverlapped;
      70             :     SCCOL nLastCol;
      71             :     SCROW nLastRow;
      72             : 
      73        4897 :     while (bHOver)              // nY konstant
      74             :     {
      75         879 :         --rStartX;
      76         879 :         if (rStartX >= (SCsCOL) nX1 && !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol))
      77             :         {
      78         879 :             bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
      79         879 :             bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
      80             :         }
      81             :         else
      82             :         {
      83             :             sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
      84           0 :                                 rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
      85           0 :             bHOver = ((nOverlap & SC_MF_HOR) != 0);
      86           0 :             bVOver = ((nOverlap & SC_MF_VER) != 0);
      87             :         }
      88             :     }
      89             : 
      90        5799 :     while (bVOver)
      91             :     {
      92        1781 :         --rStartY;
      93             : 
      94        1781 :         if (nArrY>0)
      95        1778 :             --nArrY;                        // lokale Kopie !
      96             : 
      97        7116 :         if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
      98        3546 :             !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
      99        5316 :             !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
     100        1762 :             (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
     101             :         {
     102        1762 :             bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
     103             :         }
     104             :         else
     105             :         {
     106             :             sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
     107          19 :                                 rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
     108          19 :             bVOver = ((nOverlap & SC_MF_VER) != 0);
     109             :         }
     110             :     }
     111             : 
     112             :     const ScMergeAttr* pMerge;
     113        8022 :     if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
     114        3990 :         !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
     115        5991 :         !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
     116        1987 :         (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
     117             :     {
     118        1987 :         pMerge = (const ScMergeAttr*) &pRowInfo[nArrY].pCellInfo[rStartX+1].pPatternAttr->
     119        1987 :                                         GetItem(ATTR_MERGE);
     120             :     }
     121             :     else
     122          22 :         pMerge = (const ScMergeAttr*) pDoc->GetAttr(rStartX,rStartY,nTab,ATTR_MERGE);
     123             : 
     124        2009 :     rEndX = rStartX + pMerge->GetColMerge() - 1;
     125        2009 :     rEndY = rStartY + pMerge->GetRowMerge() - 1;
     126        2009 : }
     127             : 
     128             : namespace {
     129             : 
     130             : class RowInfoFiller
     131             : {
     132             :     ScDocument& mrDoc;
     133             :     SCTAB mnTab;
     134             :     RowInfo* mpRowInfo;
     135             :     SCCOL mnArrX;
     136             :     SCSIZE& mrArrY;
     137             :     SCROW mnHiddenEndRow;
     138             :     bool mbHiddenRow;
     139             : 
     140      440207 :     bool isHidden(size_t nRow)
     141             :     {
     142      440207 :         SCROW nThisRow = static_cast<SCROW>(nRow);
     143      440207 :         if (nThisRow > mnHiddenEndRow)
     144       65003 :             mbHiddenRow = mrDoc.RowHidden(nThisRow, mnTab, NULL, &mnHiddenEndRow);
     145      440207 :         return mbHiddenRow;
     146             :     }
     147             : 
     148      439689 :     void alignArray(size_t nRow)
     149             :     {
     150     1556576 :         while (mpRowInfo[mrArrY].nRowNo < static_cast<SCROW>(nRow))
     151      677198 :             ++mrArrY;
     152      439689 :     }
     153             : 
     154      439689 :     void setInfo(size_t nRow, const ScRefCellValue& rCell)
     155             :     {
     156      439689 :         alignArray(nRow);
     157             : 
     158      439689 :         RowInfo* pThisRowInfo = &mpRowInfo[mrArrY];
     159      439689 :         CellInfo* pInfo = &pThisRowInfo->pCellInfo[mnArrX];
     160      439689 :         pInfo->maCell = rCell;
     161      439689 :         pThisRowInfo->bEmptyText = false;
     162      439689 :         pInfo->bEmptyCellText = false;
     163      439689 :         ++mrArrY;
     164      439689 :     }
     165             : 
     166             : public:
     167      104882 :     RowInfoFiller(ScDocument& rDoc, SCTAB nTab, RowInfo* pRowInfo, SCCOL nArrX, SCSIZE& rArrY) :
     168             :         mrDoc(rDoc), mnTab(nTab), mpRowInfo(pRowInfo), mnArrX(nArrX), mrArrY(rArrY),
     169      104882 :         mnHiddenEndRow(-1), mbHiddenRow(false) {}
     170             : 
     171      339468 :     void operator() (size_t nRow, double fVal)
     172             :     {
     173      339468 :         if (!isHidden(nRow))
     174      339237 :             setInfo(nRow, ScRefCellValue(fVal));
     175      339468 :     }
     176             : 
     177       95967 :     void operator() (size_t nRow, const svl::SharedString& rStr)
     178             :     {
     179       95967 :         if (!isHidden(nRow))
     180       95690 :             setInfo(nRow, ScRefCellValue(&rStr));
     181       95967 :     }
     182             : 
     183         508 :     void operator() (size_t nRow, const EditTextObject* p)
     184             :     {
     185         508 :         if (!isHidden(nRow))
     186         508 :             setInfo(nRow, ScRefCellValue(p));
     187         508 :     }
     188             : 
     189        4264 :     void operator() (size_t nRow, const ScFormulaCell* p)
     190             :     {
     191        4264 :         if (!isHidden(nRow))
     192        4254 :             setInfo(nRow, ScRefCellValue(const_cast<ScFormulaCell*>(p)));
     193        4264 :     }
     194             : };
     195             : 
     196             : }
     197             : 
     198        8985 : void ScDocument::FillInfo(
     199             :     ScTableInfo& rTabInfo, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     200             :     SCTAB nTab, double fColScale, double fRowScale, bool bPageMode, bool bFormulaMode,
     201             :     const ScMarkData* pMarkData )
     202             : {
     203             :     OSL_ENSURE( maTabs[nTab], "Table does not exist" );
     204             : 
     205        8985 :     bool bLayoutRTL = IsLayoutRTL( nTab );
     206             : 
     207        8985 :     ScDocumentPool* pPool = xPoolHelper->GetDocPool();
     208        8985 :     ScStyleSheetPool* pStlPool = xPoolHelper->GetStylePool();
     209             : 
     210        8985 :     RowInfo* pRowInfo = rTabInfo.mpRowInfo;
     211             : 
     212             :     const SvxBrushItem* pDefBackground =
     213        8985 :             (const SvxBrushItem*) &pPool->GetDefaultItem( ATTR_BACKGROUND );
     214             :     const ScMergeAttr* pDefMerge =
     215        8985 :             (const ScMergeAttr*) &pPool->GetDefaultItem( ATTR_MERGE );
     216             :     const SvxShadowItem* pDefShadow =
     217        8985 :             (const SvxShadowItem*) &pPool->GetDefaultItem( ATTR_SHADOW );
     218             : 
     219             :     SCROW nThisRow;
     220             :     SCCOL nX;
     221             :     SCROW nY;
     222             :     SCsROW nSignedY;
     223             :     SCCOL nArrCol;
     224             :     SCSIZE nArrRow;
     225             :     SCSIZE nArrCount;
     226        8985 :     bool bAnyMerged = false;
     227        8985 :     bool bAnyShadow = false;
     228        8985 :     bool bAnyCondition = false;
     229        8985 :     bool bAnyPreview = false;
     230             : 
     231        8985 :     bool bTabProtect = IsTabProtected(nTab);
     232             : 
     233             :                                                 // fuer Blockmarken von zusammengefassten Zellen mit
     234             :                                                 // versteckter erster Zeile / Spalte
     235        8985 :     bool bPaintMarks = false;
     236        8985 :     bool bSkipMarks = false;
     237        8985 :     SCCOL nBlockStartX = 0, nBlockEndX = 0;
     238        8985 :     SCROW nBlockEndY = 0, nBlockStartY = 0;
     239        8985 :     if (pMarkData && pMarkData->IsMarked())
     240             :     {
     241          99 :         ScRange aTmpRange;
     242          99 :         pMarkData->GetMarkArea(aTmpRange);
     243          99 :         if ( nTab >= aTmpRange.aStart.Tab() && nTab <= aTmpRange.aEnd.Tab() )
     244             :         {
     245          99 :             nBlockStartX = aTmpRange.aStart.Col();
     246          99 :             nBlockStartY = aTmpRange.aStart.Row();
     247          99 :             nBlockEndX = aTmpRange.aEnd.Col();
     248          99 :             nBlockEndY = aTmpRange.aEnd.Row();
     249          99 :             ExtendHidden( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY, nTab );   //? noetig ?
     250          99 :             if (pMarkData->IsMarkNegative())
     251           0 :                 bSkipMarks = true;
     252             :             else
     253          99 :                 bPaintMarks = true;
     254             :         }
     255             :     }
     256             : 
     257             :     //  zuerst nur die Eintraege fuer die ganze Spalte
     258             : 
     259        8985 :     nArrRow=0;
     260        8985 :     SCROW nYExtra = nRow2+1;
     261        8985 :     sal_uInt16 nDocHeight = ScGlobal::nStdRowHeight;
     262        8985 :     SCROW nDocHeightEndRow = -1;
     263      235909 :     for (nSignedY=((SCsROW)nRow1)-1; nSignedY<=(SCsROW)nYExtra; nSignedY++)
     264             :     {
     265      226924 :         if (nSignedY >= 0)
     266      218806 :             nY = (SCROW) nSignedY;
     267             :         else
     268        8118 :             nY = MAXROW+1;          // ungueltig
     269             : 
     270      226924 :         if (nY > nDocHeightEndRow)
     271             :         {
     272       21341 :             if (ValidRow(nY))
     273       13223 :                 nDocHeight = GetRowHeight( nY, nTab, NULL, &nDocHeightEndRow );
     274             :             else
     275        8118 :                 nDocHeight = ScGlobal::nStdRowHeight;
     276             :         }
     277             : 
     278      226924 :         if ( nArrRow==0 || nDocHeight || nY > MAXROW )
     279             :         {
     280      226581 :             RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     281      226581 :             pThisRowInfo->pCellInfo = NULL;                 // wird unten belegt
     282             : 
     283      226581 :             sal_uInt16 nHeight = (sal_uInt16) ( nDocHeight * fRowScale );
     284      226581 :             if (!nHeight)
     285           0 :                 nHeight = 1;
     286             : 
     287      226581 :             pThisRowInfo->nRowNo        = nY;               //! Fall < 0 ?
     288      226581 :             pThisRowInfo->nHeight       = nHeight;
     289      226581 :             pThisRowInfo->bEmptyBack    = true;
     290      226581 :             pThisRowInfo->bEmptyText    = true;
     291      226581 :             pThisRowInfo->bChanged      = true;
     292      226581 :             pThisRowInfo->bAutoFilter   = false;
     293      226581 :             pThisRowInfo->bPivotButton  = false;
     294      226581 :             pThisRowInfo->nRotMaxCol    = SC_ROTMAX_NONE;
     295             : 
     296      226581 :             ++nArrRow;
     297      226581 :             if (nArrRow >= ROWINFO_MAX)
     298             :             {
     299             :                 OSL_FAIL("FillInfo: Range too big" );
     300           0 :                 nYExtra = nSignedY;                                 // Ende
     301           0 :                 nRow2 = nYExtra - 1;                                  // Bereich anpassen
     302      226581 :             }
     303             :         }
     304             :         else
     305         343 :             if (nSignedY==(SCsROW) nYExtra)                         // zusaetzliche Zeile verdeckt ?
     306           0 :                 ++nYExtra;
     307             :     }
     308        8985 :     nArrCount = nArrRow;                                      // incl. Dummys
     309             : 
     310             :     //  rotierter Text...
     311             : 
     312             :     //  Attribut im Dokument ueberhaupt verwendet?
     313        8985 :     bool bAnyItem = false;
     314        8985 :     sal_uInt32 nRotCount = pPool->GetItemCount2( ATTR_ROTATE_VALUE );
     315        8985 :     for (sal_uInt32 nItem=0; nItem<nRotCount; nItem++)
     316        8985 :         if (pPool->GetItem2( ATTR_ROTATE_VALUE, nItem ))
     317             :         {
     318        8985 :             bAnyItem = true;
     319        8985 :             break;
     320             :         }
     321             : 
     322        8985 :     SCCOL nRotMax = nCol2;
     323       17970 :     if ( bAnyItem && HasAttrib( 0,nRow1,nTab, MAXCOL,nRow2+1,nTab,
     324        8985 :                                 HASATTR_ROTATE | HASATTR_CONDITIONAL ) )
     325             :     {
     326             :         //! Conditionals auch bei HASATTR_ROTATE abfragen ????
     327             : 
     328             :         OSL_ENSURE( nArrCount>2, "nArrCount too small" );
     329         352 :         FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-1, nCol1, nCol2 );
     330             :         //  FindMaxRotCol setzt nRotMaxCol
     331             : 
     332        4175 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     333        3823 :             if (pRowInfo[nArrRow].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nArrRow].nRotMaxCol > nRotMax)
     334           0 :                 nRotMax = pRowInfo[nArrRow].nRotMaxCol;
     335             :     }
     336             : 
     337             :     //  Zell-Infos erst nach dem Test auf gedrehte allozieren
     338             :     //  bis nRotMax wegen nRotateDir Flag
     339             : 
     340      235566 :     for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     341             :     {
     342      226581 :         RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     343      226581 :         nY = pThisRowInfo->nRowNo;
     344      226581 :         pThisRowInfo->pCellInfo = new CellInfo[ nRotMax+1+2 ];  // vom Aufrufer zu loeschen !
     345             : 
     346     3142119 :         for (nArrCol=0; nArrCol<=nRotMax+2; nArrCol++)                // Zell-Infos vorbelegen
     347             :         {
     348     2915538 :             if (nArrCol>0)
     349     2688957 :                 nX = nArrCol-1;
     350             :             else
     351      226581 :                 nX = MAXCOL+1;      // ungueltig
     352             : 
     353     2915538 :             CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     354     2915538 :             pInfo->bEmptyCellText = true;
     355     2915538 :             pInfo->maCell.clear();
     356     2915538 :             if (bPaintMarks)
     357       40441 :                 pInfo->bMarked = ( nX >= nBlockStartX && nX <= nBlockEndX
     358       26928 :                                 && nY >= nBlockStartY && nY <= nBlockEndY );
     359             :             else
     360     2892662 :                 pInfo->bMarked = false;
     361     2915538 :             pInfo->nWidth = 0;
     362             : 
     363     2915538 :             pInfo->nClipMark    = SC_CLIPMARK_NONE;
     364     2915538 :             pInfo->bMerged      = false;
     365     2915538 :             pInfo->bHOverlapped = false;
     366     2915538 :             pInfo->bVOverlapped = false;
     367     2915538 :             pInfo->bAutoFilter  = false;
     368     2915538 :             pInfo->bPivotButton  = false;
     369     2915538 :             pInfo->bPivotPopupButton = false;
     370     2915538 :             pInfo->bFilterActive = false;
     371     2915538 :             pInfo->nRotateDir   = SC_ROTDIR_NONE;
     372             : 
     373     2915538 :             pInfo->bPrinted     = false;                    //  view-intern
     374     2915538 :             pInfo->bHideGrid    = false;                    //  view-intern
     375     2915538 :             pInfo->bEditEngine  = false;                    //  view-intern
     376             : 
     377     2915538 :             pInfo->pBackground  = NULL;                     //! weglassen?
     378     2915538 :             pInfo->pPatternAttr = NULL;
     379     2915538 :             pInfo->pConditionSet= NULL;
     380             : 
     381     2915538 :             pInfo->pLinesAttr   = NULL;
     382     2915538 :             pInfo->mpTLBRLine   = NULL;
     383     2915538 :             pInfo->mpBLTRLine   = NULL;
     384             : 
     385     2915538 :             pInfo->pShadowAttr    = pDefShadow;
     386     2915538 :             pInfo->pHShadowOrigin = NULL;
     387     2915538 :             pInfo->pVShadowOrigin = NULL;
     388             :         }
     389             :     }
     390             : 
     391        8985 :     for (nArrCol=nCol2+3; nArrCol<=nRotMax+2; nArrCol++)            // restliche Breiten eintragen
     392             :     {
     393           0 :         nX = nArrCol-1;
     394           0 :         if ( ValidCol(nX) )
     395             :         {
     396           0 :             if (!ColHidden(nX, nTab))
     397             :             {
     398           0 :                 sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * fColScale);
     399           0 :                 if (!nThisWidth)
     400           0 :                     nThisWidth = 1;
     401             : 
     402           0 :                 pRowInfo[0].pCellInfo[nArrCol].nWidth = nThisWidth;
     403             :             }
     404             :         }
     405             :     }
     406             : 
     407        8985 :     ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
     408        8985 :     if(pCondFormList)
     409        8985 :         pCondFormList->startRendering();
     410             : 
     411      123650 :     for (nArrCol=0; nArrCol<=nCol2+2; nArrCol++)                    // links & rechts + 1
     412             :     {
     413      114665 :         nX = (nArrCol>0) ? nArrCol-1 : MAXCOL+1;                    // negativ -> ungueltig
     414             : 
     415      114665 :         if ( ValidCol(nX) )
     416             :         {
     417             :             // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes
     418             :             // will disturb the output
     419             : 
     420             :             // TODO: Optimize this loop.
     421      105680 :             if (!ColHidden(nX, nTab))
     422             :             {
     423      104882 :                 sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * fColScale);
     424      104882 :                 if (!nThisWidth)
     425           0 :                     nThisWidth = 1;
     426             : 
     427      104882 :                 pRowInfo[0].pCellInfo[nArrCol].nWidth = nThisWidth;           //! dies sollte reichen
     428             : 
     429      104882 :                 ScColumn* pThisCol = &maTabs[nTab]->aCol[nX];                   // Spalten-Daten
     430             : 
     431      104882 :                 nArrRow = 1;
     432             :                 // Iterate between rows nY1 and nY2 and pick up non-empty
     433             :                 // cells that are not hidden.
     434      104882 :                 RowInfoFiller aFunc(*this, nTab, pRowInfo, nArrCol, nArrRow);
     435             :                 sc::ParseAllNonEmpty(
     436      104882 :                     pThisCol->maCells.begin(), pThisCol->maCells, nRow1, nRow2, aFunc);
     437             : 
     438      104882 :                 if (nX+1 >= nCol1)                                // Attribute/Blockmarken ab nX1-1
     439             :                 {
     440      103585 :                     ScAttrArray* pThisAttrArr = pThisCol->pAttrArray;       // Attribute
     441             : 
     442      103585 :                     nArrRow = 0;
     443             :                     const ScPatternAttr* pPattern;
     444      103585 :                     SCROW nCurRow=nRow1;                  // einzelne Zeile
     445      103585 :                     if (nCurRow>0)
     446       10321 :                         --nCurRow;                      // oben 1 mehr
     447             :                     else
     448       93264 :                         nArrRow = 1;
     449      103585 :                     nThisRow=nCurRow;                   // Ende des Bereichs
     450             :                     SCSIZE  nIndex;
     451      103585 :                     (void) pThisAttrArr->Search( nCurRow, nIndex );
     452             : 
     453             : 
     454      193932 :                     do
     455             :                     {
     456      193932 :                         nThisRow=pThisAttrArr->pData[nIndex].nRow;              // Ende des Bereichs
     457      193932 :                         pPattern=pThisAttrArr->pData[nIndex].pPattern;
     458             : 
     459             :                         const SvxBrushItem* pBackground = (const SvxBrushItem*)
     460      193932 :                                                         &pPattern->GetItem(ATTR_BACKGROUND);
     461             :                         const SvxBoxItem* pLinesAttr = (const SvxBoxItem*)
     462      193932 :                                                         &pPattern->GetItem(ATTR_BORDER);
     463             : 
     464             :                         const SvxLineItem* pTLBRLine = static_cast< const SvxLineItem* >(
     465      193932 :                             &pPattern->GetItem( ATTR_BORDER_TLBR ) );
     466             :                         const SvxLineItem* pBLTRLine = static_cast< const SvxLineItem* >(
     467      193932 :                             &pPattern->GetItem( ATTR_BORDER_BLTR ) );
     468             : 
     469             :                         const SvxShadowItem* pShadowAttr = (const SvxShadowItem*)
     470      193932 :                                                         &pPattern->GetItem(ATTR_SHADOW);
     471      193932 :                         if (pShadowAttr != pDefShadow)
     472        1080 :                             bAnyShadow = true;
     473             : 
     474             :                         const ScMergeAttr* pMergeAttr = (const ScMergeAttr*)
     475      193932 :                                                 &pPattern->GetItem(ATTR_MERGE);
     476      193932 :                         bool bMerged = ( pMergeAttr != pDefMerge && *pMergeAttr != *pDefMerge );
     477      193932 :                         sal_uInt16 nOverlap = ((const ScMergeFlagAttr*) &pPattern->GetItemSet().
     478      193932 :                                                         Get(ATTR_MERGE_FLAG))->GetValue();
     479      193932 :                         bool bHOverlapped = ((nOverlap & SC_MF_HOR) != 0);
     480      193932 :                         bool bVOverlapped = ((nOverlap & SC_MF_VER) != 0);
     481      193932 :                         bool bAutoFilter  = ((nOverlap & SC_MF_AUTO) != 0);
     482      193932 :                         bool bPivotButton  = ((nOverlap & SC_MF_BUTTON) != 0);
     483      193932 :                         bool bScenario    = ((nOverlap & SC_MF_SCENARIO) != 0);
     484      193932 :                         bool bPivotPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0);
     485      193932 :                         bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0);
     486      193932 :                         if (bMerged||bHOverlapped||bVOverlapped)
     487        1694 :                             bAnyMerged = true;                              // intern
     488             : 
     489             :                         bool bHidden, bHideFormula;
     490      193932 :                         if (bTabProtect)
     491             :                         {
     492             :                             const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)
     493           0 :                                                         pPattern->GetItem(ATTR_PROTECTION);
     494           0 :                             bHidden = rProtAttr.GetHideCell();
     495           0 :                             bHideFormula = rProtAttr.GetHideFormula();
     496             :                         }
     497             :                         else
     498      193932 :                             bHidden = bHideFormula = false;
     499             : 
     500      193932 :                         const std::vector<sal_uInt32>& rCondFormats = static_cast<const ScCondFormatItem&>(pPattern->GetItem(ATTR_CONDITIONAL)).GetCondFormatData();
     501      193932 :                         bool bContainsCondFormat = !rCondFormats.empty();
     502             : 
     503     2562604 :                         do
     504             :                         {
     505     2562604 :                             SCROW nLastHiddenRow = -1;
     506     2562604 :                             bool bRowHidden = RowHidden(nCurRow, nTab, NULL, &nLastHiddenRow);
     507     2562604 :                             if ( nArrRow==0 || !bRowHidden )
     508             :                             {
     509     2560962 :                                 if ( GetPreviewCellStyle( nX, nCurRow, nTab  ) != NULL )
     510           0 :                                     bAnyPreview = true;
     511     2560962 :                                 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     512     2560962 :                                 if (pBackground != pDefBackground)          // Spalten-HG == Standard ?
     513      276084 :                                     pThisRowInfo->bEmptyBack = false;
     514     2560962 :                                 if (bContainsCondFormat)
     515        7195 :                                     pThisRowInfo->bEmptyBack = false;
     516     2560962 :                                 if (bAutoFilter)
     517         158 :                                     pThisRowInfo->bAutoFilter = true;
     518     2560962 :                                 if (bPivotButton || bPivotPopupButton)
     519         469 :                                     pThisRowInfo->bPivotButton = true;
     520             : 
     521     2560962 :                                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     522     2560962 :                                 pInfo->pBackground  = pBackground;
     523     2560962 :                                 pInfo->pPatternAttr = pPattern;
     524     2560962 :                                 pInfo->bMerged      = bMerged;
     525     2560962 :                                 pInfo->bHOverlapped = bHOverlapped;
     526     2560962 :                                 pInfo->bVOverlapped = bVOverlapped;
     527     2560962 :                                 pInfo->bAutoFilter  = bAutoFilter;
     528     2560962 :                                 pInfo->bPivotButton  = bPivotButton;
     529     2560962 :                                 pInfo->bPivotPopupButton = bPivotPopupButton;
     530     2560962 :                                 pInfo->bFilterActive = bFilterActive;
     531     2560962 :                                 pInfo->pLinesAttr   = pLinesAttr;
     532     2560962 :                                 pInfo->mpTLBRLine   = pTLBRLine;
     533     2560962 :                                 pInfo->mpBLTRLine   = pBLTRLine;
     534     2560962 :                                 pInfo->pShadowAttr  = pShadowAttr;
     535             :                                 //  nWidth wird nicht mehr einzeln gesetzt
     536             : 
     537     2560962 :                                 if (bScenario)
     538             :                                 {
     539           0 :                                     pInfo->pBackground = ScGlobal::GetButtonBrushItem();
     540           0 :                                     pThisRowInfo->bEmptyBack = false;
     541             :                                 }
     542             : 
     543     2560962 :                                 if ( bContainsCondFormat )
     544             :                                 {
     545        7195 :                                     bool bFound = false;
     546       74157 :                                     for(std::vector<sal_uInt32>::const_iterator itr = rCondFormats.begin();
     547       74157 :                                             itr != rCondFormats.end() && !bFound; ++itr)
     548             :                                     {
     549       17524 :                                         ScConditionalFormat* pCondForm = pCondFormList->GetFormat(*itr);
     550       17524 :                                         if(!pCondForm)
     551           0 :                                             continue;
     552             : 
     553             :                                         ScCondFormatData aData = pCondForm->GetData(
     554       17524 :                                             pInfo->maCell, ScAddress(nX, nCurRow, nTab));
     555       17524 :                                         if (!aData.aStyleName.isEmpty())
     556             :                                         {
     557             :                                             SfxStyleSheetBase* pStyleSheet =
     558          86 :                                                 pStlPool->Find( aData.aStyleName, SFX_STYLE_FAMILY_PARA );
     559          86 :                                             if ( pStyleSheet )
     560             :                                             {
     561             :                                                 //! Style-Sets cachen !!!
     562          86 :                                                 pInfo->pConditionSet = &pStyleSheet->GetItemSet();
     563          86 :                                                 bAnyCondition = true;
     564             : 
     565             :                                                 // we need to check already here for protected cells
     566             :                                                 const SfxPoolItem* pItem;
     567          86 :                                                 if ( bTabProtect && pInfo->pConditionSet->GetItemState( ATTR_PROTECTION, true, &pItem ) == SFX_ITEM_SET )
     568             :                                                 {
     569           0 :                                                     const ScProtectionAttr* pProtAttr = static_cast<const ScProtectionAttr*>(pItem);
     570           0 :                                                     bHidden = pProtAttr->GetHideCell();
     571           0 :                                                     bHideFormula = pProtAttr->GetHideFormula();
     572             : 
     573             :                                                 }
     574          86 :                                                 bFound = true;
     575             : 
     576             :                                             }
     577             :                                             // if style is not there, treat like no condition
     578             :                                         }
     579       17524 :                                         if(aData.pColorScale)
     580             :                                         {
     581           0 :                                             pInfo->pColorScale = aData.pColorScale;
     582           0 :                                             bFound = true;
     583             :                                         }
     584             : 
     585       17524 :                                         if(aData.pDataBar)
     586             :                                         {
     587           0 :                                             pInfo->pDataBar = aData.pDataBar;
     588           0 :                                             bFound = true;
     589             :                                         }
     590       17524 :                                         if(aData.pIconSet)
     591             :                                         {
     592           0 :                                             pInfo->pIconSet = aData.pIconSet;
     593           0 :                                             bFound = true;
     594             :                                         }
     595       17524 :                                     }
     596             :                                 }
     597             : 
     598     2560962 :                                 if (bHidden || (bFormulaMode && bHideFormula && pInfo->maCell.meType == CELLTYPE_FORMULA))
     599           0 :                                     pInfo->bEmptyCellText = true;
     600             : 
     601     2560962 :                                 ++nArrRow;
     602             :                             }
     603        1642 :                             else if (bRowHidden && nLastHiddenRow >= 0)
     604             :                             {
     605        1642 :                                 nCurRow = nLastHiddenRow;
     606        1642 :                                 if (nCurRow > nThisRow)
     607          58 :                                     nCurRow = nThisRow;
     608             :                             }
     609     2562604 :                             ++nCurRow;
     610             :                         }
     611     2471214 :                         while (nCurRow <= nThisRow && nCurRow <= nYExtra);
     612      193932 :                         ++nIndex;
     613             :                     }
     614      327933 :                     while ( nIndex < pThisAttrArr->nCount && nThisRow < nYExtra );
     615             : 
     616             : 
     617      103585 :                     if (pMarkData && pMarkData->IsMultiMarked())
     618             :                     {
     619             :                         //  Blockmarken
     620         313 :                         const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nX;
     621         313 :                         nArrRow = 1;
     622         313 :                         nCurRow = nRow1;                                      // einzelne Zeile
     623         313 :                         nThisRow = nRow1;                                     // Ende des Bereichs
     624             : 
     625         313 :                         if ( pThisMarkArr->Search( nRow1, nIndex ) )
     626             :                         {
     627             :                             bool bThisMarked;
     628         364 :                             do
     629             :                             {
     630         364 :                                 nThisRow=pThisMarkArr->pData[nIndex].nRow;      // Ende des Bereichs
     631         364 :                                 bThisMarked=pThisMarkArr->pData[nIndex].bMarked;
     632             : 
     633        2755 :                                 do
     634             :                                 {
     635        2755 :                                     if ( !RowHidden( nCurRow,nTab ) )
     636             :                                     {
     637        2755 :                                         if ( bThisMarked )
     638             :                                         {
     639           0 :                                             bool bSkip = bSkipMarks &&
     640           0 :                                                         nX      >= nBlockStartX &&
     641           0 :                                                         nX      <= nBlockEndX   &&
     642        1050 :                                                         nCurRow >= nBlockStartY &&
     643        1050 :                                                         nCurRow <= nBlockEndY;
     644        1050 :                                             if (!bSkip)
     645             :                                             {
     646        1050 :                                                 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     647        1050 :                                                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     648        1050 :                                                 pInfo->bMarked = true;
     649             :                                             }
     650             :                                         }
     651        2755 :                                         ++nArrRow;
     652             :                                     }
     653        2755 :                                     ++nCurRow;
     654             :                                 }
     655        2506 :                                 while (nCurRow <= nThisRow && nCurRow <= nRow2);
     656         364 :                                 ++nIndex;
     657             :                             }
     658         628 :                             while ( nIndex < pThisMarkArr->nCount && nThisRow < nRow2 );
     659             :                         }
     660             :                     }
     661             :                 }
     662             :                 else                                    // vordere Spalten
     663             :                 {
     664       11995 :                     for (nArrRow=1; nArrRow+1<nArrCount; nArrRow++)
     665             :                     {
     666       10698 :                         RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     667       10698 :                         CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     668             : 
     669       10698 :                         pInfo->nWidth       = nThisWidth;           //! oder nur 0 abfragen ??
     670             :                     }
     671             :                 }
     672             :             }
     673             :         }
     674             :         else
     675        8985 :             pRowInfo[0].pCellInfo[nArrCol].nWidth = STD_COL_WIDTH;
     676             :         // STD_COL_WIDTH ganz links und rechts wird fuer DrawExtraShadow gebraucht
     677             :     }
     678             : 
     679        8985 :     if(pCondFormList)
     680        8985 :         pCondFormList->endRendering();
     681             : 
     682             :     //  bedingte Formatierung auswerten
     683        8985 :     ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
     684             :     // favour preview over condition
     685        8985 :     if (bAnyCondition || bAnyPreview)
     686             :     {
     687        1350 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     688             :         {
     689       19285 :             for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)                  // links und rechts einer mehr
     690             :             {
     691       17980 :                 CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
     692       17980 :                 SCCOL nCol = (nArrCol>0) ? nArrCol-1 : MAXCOL+1;
     693       17980 :                 ScPatternAttr* pModifiedPatt = NULL;
     694             : 
     695       17980 :                 if ( ValidCol(nCol) && pRowInfo[nArrRow].nRowNo <= MAXROW )
     696             :                 {
     697       16100 :                     if ( ScStyleSheet* pPreviewStyle = GetPreviewCellStyle( nCol, pRowInfo[nArrRow].nRowNo, nTab ) )
     698             :                     {
     699           0 :                         aAltPatterns.push_back( new ScPatternAttr( *pInfo->pPatternAttr ) );
     700           0 :                         pModifiedPatt = &aAltPatterns.back();
     701           0 :                         pModifiedPatt->SetStyleSheet( pPreviewStyle );
     702             :                     }
     703             :                 }
     704             :                 // favour preview over condition
     705       17980 :                 const SfxItemSet* pCondSet = pModifiedPatt ? &pModifiedPatt->GetItemSet() : pInfo->pConditionSet;
     706             : 
     707       17980 :                 if (pCondSet)
     708             :                 {
     709             :                     const SfxPoolItem* pItem;
     710             : 
     711             :                             //  Hintergrund
     712          86 :                     if ( pCondSet->GetItemState( ATTR_BACKGROUND, true, &pItem ) == SFX_ITEM_SET )
     713             :                     {
     714           0 :                         pInfo->pBackground = (const SvxBrushItem*) pItem;
     715           0 :                         pRowInfo[nArrRow].bEmptyBack = false;
     716             :                     }
     717             : 
     718             :                             //  Umrandung
     719          86 :                     if ( pCondSet->GetItemState( ATTR_BORDER, true, &pItem ) == SFX_ITEM_SET )
     720           0 :                         pInfo->pLinesAttr = (const SvxBoxItem*) pItem;
     721             : 
     722          86 :                     if ( pCondSet->GetItemState( ATTR_BORDER_TLBR, true, &pItem ) == SFX_ITEM_SET )
     723           0 :                         pInfo->mpTLBRLine = static_cast< const SvxLineItem* >( pItem );
     724          86 :                     if ( pCondSet->GetItemState( ATTR_BORDER_BLTR, true, &pItem ) == SFX_ITEM_SET )
     725           0 :                         pInfo->mpBLTRLine = static_cast< const SvxLineItem* >( pItem );
     726             : 
     727             :                             //  Schatten
     728          86 :                     if ( pCondSet->GetItemState( ATTR_SHADOW, true, &pItem ) == SFX_ITEM_SET )
     729             :                     {
     730           0 :                         pInfo->pShadowAttr = (const SvxShadowItem*) pItem;
     731           0 :                         bAnyShadow = true;
     732             :                     }
     733             :                 }
     734       17980 :                 if( bAnyCondition && pInfo->pColorScale)
     735             :                 {
     736           0 :                     pRowInfo[nArrRow].bEmptyBack = false;
     737           0 :                     pInfo->pBackground = new SvxBrushItem(*pInfo->pColorScale, ATTR_BACKGROUND);
     738             :                 }
     739             :             }
     740             :         }
     741             :     }
     742             : 
     743             :     //  bedingte Formatierung Ende
     744             : 
     745             :                 //      Daten von zusammengefassten Zellen anpassen
     746             : 
     747             : 
     748        8985 :     if (bAnyMerged)
     749             :     {
     750        7442 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     751             :         {
     752        7157 :             RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     753        7157 :             nSignedY = nArrRow ? pThisRowInfo->nRowNo : ((SCsROW)nRow1)-1;
     754             : 
     755      126923 :             for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)                  // links und rechts einer mehr
     756             :             {
     757      119766 :                 SCsCOL nSignedX = ((SCsCOL) nArrCol) - 1;
     758      119766 :                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     759             : 
     760      119766 :                 if (pInfo->bMerged || pInfo->bHOverlapped || pInfo->bVOverlapped)
     761             :                 {
     762             :                     SCsCOL nStartX;
     763             :                     SCsROW nStartY;
     764             :                     SCsCOL nEndX;
     765             :                     SCsROW nEndY;
     766             :                     lcl_GetMergeRange( nSignedX,nSignedY, nArrRow, this,pRowInfo, nCol1,nRow1,nCol2,nRow2,nTab,
     767        1718 :                                         nStartX,nStartY, nEndX,nEndY );
     768        1718 :                     const ScPatternAttr* pStartPattern = GetPattern( nStartX,nStartY,nTab );
     769        1718 :                     const SfxItemSet* pStartCond = GetCondResult( nStartX,nStartY,nTab );
     770             :                     const SfxPoolItem* pItem;
     771             : 
     772             :                     // Hintergrund kopieren (oder in output.cxx)
     773             : 
     774        1718 :                     if ( !pStartCond || pStartCond->
     775           0 :                                     GetItemState(ATTR_BACKGROUND,true,&pItem) != SFX_ITEM_SET )
     776        1718 :                         pItem = &pStartPattern->GetItem(ATTR_BACKGROUND);
     777        1718 :                     pInfo->pBackground = (const SvxBrushItem*) pItem;
     778        1718 :                     pRowInfo[nArrRow].bEmptyBack = false;
     779             : 
     780             :                     // Schatten
     781             : 
     782        1718 :                     if ( !pStartCond || pStartCond->
     783           0 :                                     GetItemState(ATTR_SHADOW,true,&pItem) != SFX_ITEM_SET )
     784        1718 :                         pItem = &pStartPattern->GetItem(ATTR_SHADOW);
     785        1718 :                     pInfo->pShadowAttr = (const SvxShadowItem*) pItem;
     786        1718 :                     if (pInfo->pShadowAttr != pDefShadow)
     787           0 :                         bAnyShadow = true;
     788             : 
     789             :                     // Blockmarken - wieder mit Original-Merge-Werten
     790             : 
     791        1718 :                     bool bCellMarked = false;
     792        1718 :                     if (bPaintMarks)
     793          36 :                         bCellMarked = ( nStartX >= (SCsCOL) nBlockStartX
     794          36 :                                     && nStartX <= (SCsCOL) nBlockEndX
     795           0 :                                     && nStartY >= (SCsROW) nBlockStartY
     796          36 :                                     && nStartY <= (SCsROW) nBlockEndY );
     797        1718 :                     if (pMarkData && pMarkData->IsMultiMarked() && !bCellMarked)
     798             :                     {
     799          72 :                         const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nStartX;
     800             :                         SCSIZE nIndex;
     801          72 :                         if ( pThisMarkArr->Search( nStartY, nIndex ) )
     802           0 :                             bCellMarked=pThisMarkArr->pData[nIndex].bMarked;
     803             :                     }
     804             : 
     805        1718 :                     pInfo->bMarked = bCellMarked;
     806             :                 }
     807             :             }
     808             :         }
     809             :     }
     810             : 
     811        8985 :     if (bAnyShadow)                             // Schatten verteilen
     812             :     {
     813        2116 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     814             :         {
     815        1843 :             bool bTop = ( nArrRow == 0 );
     816        1843 :             bool bBottom = ( nArrRow+1 == nArrCount );
     817             : 
     818       23959 :             for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)                  // links und rechts einer mehr
     819             :             {
     820       22116 :                 bool bLeft = ( nArrCol == nCol1 );
     821       22116 :                 bool bRight = ( nArrCol == nCol2+2 );
     822             : 
     823       22116 :                 CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
     824       22116 :                 const SvxShadowItem* pThisAttr = pInfo->pShadowAttr;
     825       22116 :                 SvxShadowLocation eLoc = pThisAttr ? pThisAttr->GetLocation() : SVX_SHADOW_NONE;
     826       22116 :                 if (eLoc != SVX_SHADOW_NONE)
     827             :                 {
     828             :                     //  oder Test auf != eLoc
     829             : 
     830           0 :                     SCsCOL nDxPos = 1;
     831           0 :                     SCsCOL nDxNeg = -1;
     832             : 
     833           0 :                     while ( nArrCol+nDxPos < nCol2+2 && pRowInfo[0].pCellInfo[nArrCol+nDxPos].nWidth == 0 )
     834           0 :                         ++nDxPos;
     835           0 :                     while ( nArrCol+nDxNeg > nCol1 && pRowInfo[0].pCellInfo[nArrCol+nDxNeg].nWidth == 0 )
     836           0 :                         --nDxNeg;
     837             : 
     838           0 :                     bool bLeftDiff = !bLeft &&
     839           0 :                             pRowInfo[nArrRow].pCellInfo[nArrCol+nDxNeg].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     840           0 :                     bool bRightDiff = !bRight &&
     841           0 :                             pRowInfo[nArrRow].pCellInfo[nArrCol+nDxPos].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     842           0 :                     bool bTopDiff = !bTop &&
     843           0 :                             pRowInfo[nArrRow-1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     844           0 :                     bool bBottomDiff = !bBottom &&
     845           0 :                             pRowInfo[nArrRow+1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     846             : 
     847           0 :                     if ( bLayoutRTL )
     848             :                     {
     849           0 :                         switch (eLoc)
     850             :                         {
     851           0 :                             case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT;  break;
     852           0 :                             case SVX_SHADOW_BOTTOMLEFT:  eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
     853           0 :                             case SVX_SHADOW_TOPRIGHT:    eLoc = SVX_SHADOW_TOPLEFT;     break;
     854           0 :                             case SVX_SHADOW_TOPLEFT:     eLoc = SVX_SHADOW_TOPRIGHT;    break;
     855             :                             default:
     856             :                             {
     857             :                                 // added to avoid warnings
     858             :                             }
     859             :                         }
     860             :                     }
     861             : 
     862           0 :                     switch (eLoc)
     863             :                     {
     864             :                         case SVX_SHADOW_BOTTOMRIGHT:
     865           0 :                             if (bBottomDiff)
     866             :                             {
     867           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     868           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
     869           0 :                                                 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     870             :                             }
     871           0 :                             if (bRightDiff)
     872             :                             {
     873           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
     874           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
     875           0 :                                                 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     876             :                             }
     877           0 :                             if (bBottomDiff && bRightDiff)
     878             :                             {
     879           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
     880           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
     881             :                             }
     882           0 :                             break;
     883             : 
     884             :                         case SVX_SHADOW_BOTTOMLEFT:
     885           0 :                             if (bBottomDiff)
     886             :                             {
     887           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     888           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
     889           0 :                                                 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     890             :                             }
     891           0 :                             if (bLeftDiff)
     892             :                             {
     893           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
     894           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
     895           0 :                                                 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     896             :                             }
     897           0 :                             if (bBottomDiff && bLeftDiff)
     898             :                             {
     899           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
     900           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
     901             :                             }
     902           0 :                             break;
     903             : 
     904             :                         case SVX_SHADOW_TOPRIGHT:
     905           0 :                             if (bTopDiff)
     906             :                             {
     907           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     908           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
     909           0 :                                                 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     910             :                             }
     911           0 :                             if (bRightDiff)
     912             :                             {
     913           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
     914           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
     915           0 :                                                 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     916             :                             }
     917           0 :                             if (bTopDiff && bRightDiff)
     918             :                             {
     919           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
     920           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
     921             :                             }
     922           0 :                             break;
     923             : 
     924             :                         case SVX_SHADOW_TOPLEFT:
     925           0 :                             if (bTopDiff)
     926             :                             {
     927           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     928           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
     929           0 :                                                 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     930             :                             }
     931           0 :                             if (bLeftDiff)
     932             :                             {
     933           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
     934           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
     935           0 :                                                 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     936             :                             }
     937           0 :                             if (bTopDiff && bLeftDiff)
     938             :                             {
     939           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
     940           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
     941             :                             }
     942           0 :                             break;
     943             : 
     944             :                         default:
     945             :                             OSL_FAIL("wrong Shadow-Enum");
     946             :                     }
     947             :                 }
     948             :             }
     949             :         }
     950             :     }
     951             : 
     952        8985 :     rTabInfo.mnArrCount = sal::static_int_cast<sal_uInt16>(nArrCount);
     953        8985 :     rTabInfo.mbPageMode = bPageMode;
     954             : 
     955             : 
     956             :     // *** create the frame border array ***
     957             : 
     958             :     // RowInfo structs are filled in the range [ 0 , nArrCount-1 ]
     959             :     // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ]
     960             : 
     961        8985 :     size_t nColCount = nCol2 - nCol1 + 3;
     962        8985 :     size_t nRowCount = nArrCount;
     963             : 
     964        8985 :     svx::frame::Array& rArray = rTabInfo.maArray;
     965        8985 :     rArray.Initialize( nColCount, nRowCount );
     966        8985 :     rArray.SetUseDiagDoubleClipping( false );
     967             : 
     968      235566 :     for( size_t nRow = 0; nRow < nRowCount; ++nRow )
     969             :     {
     970      226581 :         sal_uInt16 nCellInfoY = static_cast< sal_uInt16 >( nRow );
     971      226581 :         RowInfo& rThisRowInfo = pRowInfo[ nCellInfoY ];
     972             : 
     973     3124490 :         for( size_t nCol = 0; nCol < nColCount; ++nCol )
     974             :         {
     975     2897909 :             sal_uInt16 nCellInfoX = static_cast< sal_uInt16 >( nCol + nCol1 );
     976     2897909 :             const CellInfo& rInfo = rThisRowInfo.pCellInfo[ nCellInfoX ];
     977             : 
     978     2897909 :             const SvxBoxItem* pBox = rInfo.pLinesAttr;
     979     2897909 :             const SvxLineItem* pTLBR = rInfo.mpTLBRLine;
     980     2897909 :             const SvxLineItem* pBLTR = rInfo.mpBLTRLine;
     981             : 
     982     2897909 :             size_t nFirstCol = nCol;
     983     2897909 :             size_t nFirstRow = nRow;
     984             : 
     985             :             // *** merged cells *** -------------------------------------------
     986             : 
     987     2897909 :             if( !rArray.IsMerged( nCol, nRow ) && (rInfo.bMerged || rInfo.bHOverlapped || rInfo.bVOverlapped) )
     988             :             {
     989             :                 // *** insert merged range in svx::frame::Array ***
     990             : 
     991             :                 /*  #i69369# top-left cell of a merged range may be located in
     992             :                     a hidden column or row. Use lcl_GetMergeRange() to find the
     993             :                     complete merged range, then calculate dimensions and
     994             :                     document position of the visible range. */
     995             : 
     996             :                 // note: document columns are always one less than CellInfoX coords
     997             :                 // note: document rows must be looked up in RowInfo structs
     998             : 
     999             :                 // current column and row in document coordinates
    1000         291 :                 SCCOL nCurrDocCol = static_cast< SCCOL >( nCellInfoX - 1 );
    1001         291 :                 SCROW nCurrDocRow = static_cast< SCROW >( (nCellInfoY > 0) ? rThisRowInfo.nRowNo : (nRow1 - 1) );
    1002             : 
    1003             :                 // find entire merged range in document, returns signed document coordinates
    1004             :                 SCsCOL nFirstRealDocColS, nLastRealDocColS;
    1005             :                 SCsROW nFirstRealDocRowS, nLastRealDocRowS;
    1006             :                 lcl_GetMergeRange( static_cast< SCsCOL >( nCurrDocCol ), static_cast< SCsROW >( nCurrDocRow ),
    1007             :                     nCellInfoY, this, pRowInfo, nCol1,nRow1,nCol2,nRow2,nTab,
    1008         291 :                     nFirstRealDocColS, nFirstRealDocRowS, nLastRealDocColS, nLastRealDocRowS );
    1009             : 
    1010             :                 // *complete* merged range in document coordinates
    1011         291 :                 SCCOL nFirstRealDocCol = static_cast< SCCOL >( nFirstRealDocColS );
    1012         291 :                 SCROW nFirstRealDocRow = static_cast< SCROW >( nFirstRealDocRowS );
    1013         291 :                 SCCOL nLastRealDocCol  = static_cast< SCCOL >( nLastRealDocColS );
    1014         291 :                 SCROW nLastRealDocRow  = static_cast< SCROW >( nLastRealDocRowS );
    1015             : 
    1016             :                 // first visible column (nX1-1 is first processed document column)
    1017         291 :                 SCCOL nFirstDocCol = (nCol1 > 0) ? ::std::max< SCCOL >( nFirstRealDocCol, nCol1 - 1 ) : nFirstRealDocCol;
    1018         291 :                 sal_uInt16 nFirstCellInfoX = static_cast< sal_uInt16 >( nFirstDocCol + 1 );
    1019         291 :                 nFirstCol = static_cast< size_t >( nFirstCellInfoX - nCol1 );
    1020             : 
    1021             :                 // last visible column (nX2+1 is last processed document column)
    1022         291 :                 SCCOL nLastDocCol = (nCol2 < MAXCOL) ? ::std::min< SCCOL >( nLastRealDocCol, nCol2 + 1 ) : nLastRealDocCol;
    1023         291 :                 sal_uInt16 nLastCellInfoX = static_cast< sal_uInt16 >( nLastDocCol + 1 );
    1024         291 :                 size_t nLastCol = static_cast< size_t >( nLastCellInfoX - nCol1 );
    1025             : 
    1026             :                 // first visible row
    1027         291 :                 sal_uInt16 nFirstCellInfoY = nCellInfoY;
    1028         582 :                 while( ((nFirstCellInfoY > 1) && (pRowInfo[ nFirstCellInfoY - 1 ].nRowNo >= nFirstRealDocRow)) ||
    1029         283 :                        ((nFirstCellInfoY == 1) && (static_cast< SCROW >( nRow1 - 1 ) >= nFirstRealDocRow)) )
    1030           0 :                     --nFirstCellInfoY;
    1031         291 :                 SCROW nFirstDocRow = (nFirstCellInfoY > 0) ? pRowInfo[ nFirstCellInfoY ].nRowNo : static_cast< SCROW >( nRow1 - 1 );
    1032         291 :                 nFirstRow = static_cast< size_t >( nFirstCellInfoY );
    1033             : 
    1034             :                 // last visible row
    1035         291 :                 sal_uInt16 nLastCellInfoY = nCellInfoY;
    1036        2047 :                 while( (sal::static_int_cast<SCSIZE>(nLastCellInfoY + 1) < nArrCount) &&
    1037         878 :                             (pRowInfo[ nLastCellInfoY + 1 ].nRowNo <= nLastRealDocRow) )
    1038         587 :                     ++nLastCellInfoY;
    1039         291 :                 SCROW nLastDocRow = (nLastCellInfoY > 0) ? pRowInfo[ nLastCellInfoY ].nRowNo : static_cast< SCROW >( nRow1 - 1 );
    1040         291 :                 size_t nLastRow = static_cast< size_t >( nLastCellInfoY );
    1041             : 
    1042             :                 // insert merged range
    1043         291 :                 rArray.SetMergedRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
    1044             : 
    1045             :                 // *** find additional size not included in svx::frame::Array ***
    1046             : 
    1047             :                 // additional space before first column
    1048         291 :                 if( nFirstCol == 0 )
    1049             :                 {
    1050           0 :                     long nSize = 0;
    1051           0 :                     for( SCCOL nDocCol = nFirstRealDocCol; nDocCol < nFirstDocCol; ++nDocCol )
    1052           0 :                         nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * fColScale ), 1L );
    1053           0 :                     rArray.SetAddMergedLeftSize( nCol, nRow, nSize );
    1054             :                 }
    1055             :                 // additional space after last column
    1056         291 :                 if( nLastCol + 1 == nColCount )
    1057             :                 {
    1058          28 :                     long nSize = 0;
    1059          50 :                     for( SCCOL nDocCol = nLastDocCol + 1; nDocCol <= nLastRealDocCol; ++nDocCol )
    1060          22 :                         nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * fColScale ), 1L );
    1061          28 :                     rArray.SetAddMergedRightSize( nCol, nRow, nSize );
    1062             :                 }
    1063             :                 // additional space above first row
    1064         291 :                 if( nFirstRow == 0 )
    1065             :                 {
    1066           2 :                     long nSize = 0;
    1067           2 :                     for( SCROW nDocRow = nFirstRealDocRow; nDocRow < nFirstDocRow; ++nDocRow )
    1068           0 :                         nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * fRowScale ), 1L );
    1069           2 :                     rArray.SetAddMergedTopSize( nCol, nRow, nSize );
    1070             :                 }
    1071             :                 // additional space beyond last row
    1072         291 :                 if( nLastRow + 1 == nRowCount )
    1073             :                 {
    1074           0 :                     long nSize = 0;
    1075           0 :                     for( SCROW nDocRow = nLastDocRow + 1; nDocRow <= nLastRealDocRow; ++nDocRow )
    1076           0 :                         nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * fRowScale ), 1L );
    1077           0 :                     rArray.SetAddMergedBottomSize( nCol, nRow, nSize );
    1078             :                 }
    1079             : 
    1080             :                 // *** use line attributes from real origin cell ***
    1081             : 
    1082         291 :                 if( (nFirstRealDocCol != nCurrDocCol) || (nFirstRealDocRow != nCurrDocRow) )
    1083             :                 {
    1084           2 :                     if( const ScPatternAttr* pPattern = GetPattern( nFirstRealDocCol, nFirstRealDocRow, nTab ) )
    1085             :                     {
    1086           2 :                         const SfxItemSet* pCond = GetCondResult( nFirstRealDocCol, nFirstRealDocRow, nTab );
    1087           2 :                         pBox = static_cast< const SvxBoxItem* >( &pPattern->GetItem( ATTR_BORDER, pCond ) );
    1088           2 :                         pTLBR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_TLBR, pCond ) );
    1089           2 :                         pBLTR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_BLTR, pCond ) );
    1090             :                     }
    1091             :                     else
    1092             :                     {
    1093           0 :                         pBox = 0;
    1094           0 :                         pTLBR = pBLTR = 0;
    1095             :                     }
    1096             :                 }
    1097             :             }
    1098             : 
    1099             :             // *** borders *** ------------------------------------------------
    1100             : 
    1101     2897909 :             if( pBox )
    1102             :             {
    1103     2560962 :                 rArray.SetCellStyleLeft(   nFirstCol, nFirstRow, svx::frame::Style( pBox->GetLeft(),   fColScale ) );
    1104     2560962 :                 rArray.SetCellStyleRight(  nFirstCol, nFirstRow, svx::frame::Style( pBox->GetRight(),  fColScale ) );
    1105     2560962 :                 rArray.SetCellStyleTop(    nFirstCol, nFirstRow, svx::frame::Style( pBox->GetTop(),    fRowScale ) );
    1106     2560962 :                 rArray.SetCellStyleBottom( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetBottom(), fRowScale ) );
    1107             :             }
    1108             : 
    1109     2897909 :             if( pTLBR )
    1110     2560962 :                 rArray.SetCellStyleTLBR( nFirstCol, nFirstRow, svx::frame::Style( pTLBR->GetLine(), fRowScale ) );
    1111     2897909 :             if( rInfo.mpBLTRLine )
    1112     2560962 :                 rArray.SetCellStyleBLTR( nFirstCol, nFirstRow, svx::frame::Style( pBLTR->GetLine(), fRowScale ) );
    1113             :         }
    1114             :     }
    1115             : 
    1116             :     /*  Mirror the entire frame array.
    1117             :         1st param = Mirror the vertical double line styles as well.
    1118             :         2nd param = Do not swap diagonal lines.
    1119             :      */
    1120        8985 :     if( bLayoutRTL )
    1121           2 :         rArray.MirrorSelfX( true, false );
    1122        8985 : }
    1123             : 
    1124        8985 : ScTableInfo::ScTableInfo()
    1125        8985 :     : mpRowInfo(new RowInfo[ROWINFO_MAX])
    1126             :     , mnArrCount(0)
    1127       17970 :     , mbPageMode(false)
    1128             : {
    1129     9209625 :     for( sal_uInt16 nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx )
    1130     9200640 :         mpRowInfo[ nIdx ].pCellInfo = 0;
    1131        8985 : }
    1132             : 
    1133       17970 : ScTableInfo::~ScTableInfo()
    1134             : {
    1135     9209625 :     for( sal_uInt16 nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx )
    1136     9200640 :         delete [] mpRowInfo[ nIdx ].pCellInfo;
    1137        8985 :     delete [] mpRowInfo;
    1138        9087 : }
    1139             : 
    1140             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10