LCOV - code coverage report
Current view: top level - sc/source/core/data - fillinfo.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 457 587 77.9 %
Date: 2015-06-13 12:38:46 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             : enum FillInfoLinePos
      48             :     {
      49             :         FILP_TOP,
      50             :         FILP_BOTTOM,
      51             :         FILP_LEFT,
      52             :         FILP_RIGHT
      53             :     };
      54             : 
      55             : // Similar as in output.cxx
      56             : 
      57        1953 : static void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY,
      58             :                             ScDocument* pDoc, RowInfo* pRowInfo,
      59             :                             SCCOL nX1, SCROW nY1, SCCOL /* nX2 */, SCROW /* nY2 */, SCTAB nTab,
      60             :                             SCsCOL& rStartX, SCsROW& rStartY, SCsCOL& rEndX, SCsROW& rEndY )
      61             : {
      62        1953 :     CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
      63             : 
      64        1953 :     rStartX = nX;
      65        1953 :     rStartY = nY;
      66        1953 :     bool bHOver = pInfo->bHOverlapped;
      67        1953 :     bool bVOver = pInfo->bVOverlapped;
      68             :     SCCOL nLastCol;
      69             :     SCROW nLastRow;
      70             : 
      71        4829 :     while (bHOver)              // nY constant
      72             :     {
      73         923 :         --rStartX;
      74         923 :         if (rStartX >= (SCsCOL) nX1 && !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol))
      75             :         {
      76         923 :             bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
      77         923 :             bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
      78             :         }
      79             :         else
      80             :         {
      81             :             sal_uInt16 nOverlap = static_cast<const ScMergeFlagAttr*>(pDoc->GetAttr(
      82           0 :                                 rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
      83           0 :             bHOver = ((nOverlap & SC_MF_HOR) != 0);
      84           0 :             bVOver = ((nOverlap & SC_MF_VER) != 0);
      85             :         }
      86             :     }
      87             : 
      88        5664 :     while (bVOver)
      89             :     {
      90        1758 :         --rStartY;
      91             : 
      92        1758 :         if (nArrY>0)
      93        1755 :             --nArrY;                        // local copy !
      94             : 
      95        7024 :         if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
      96        3500 :             !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
      97        5247 :             !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
      98        1739 :             (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
      99             :         {
     100        1739 :             bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
     101             :         }
     102             :         else
     103             :         {
     104             :             sal_uInt16 nOverlap = static_cast<const ScMergeFlagAttr*>(pDoc->GetAttr(
     105          19 :                                 rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
     106          19 :             bVOver = ((nOverlap & SC_MF_VER) != 0);
     107             :         }
     108             :     }
     109             : 
     110             :     const ScMergeAttr* pMerge;
     111        7798 :     if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
     112        3878 :         !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
     113        5823 :         !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
     114        1931 :         (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
     115             :     {
     116        1931 :         pMerge = static_cast<const ScMergeAttr*>( &pRowInfo[nArrY].pCellInfo[rStartX+1].pPatternAttr->
     117        1931 :                                         GetItem(ATTR_MERGE));
     118             :     }
     119             :     else
     120          22 :         pMerge = static_cast<const ScMergeAttr*>( pDoc->GetAttr(rStartX,rStartY,nTab,ATTR_MERGE) );
     121             : 
     122        1953 :     rEndX = rStartX + pMerge->GetColMerge() - 1;
     123        1953 :     rEndY = rStartY + pMerge->GetRowMerge() - 1;
     124        1953 : }
     125             : 
     126             : namespace {
     127             : 
     128             : class RowInfoFiller
     129             : {
     130             :     ScDocument& mrDoc;
     131             :     SCTAB mnTab;
     132             :     RowInfo* mpRowInfo;
     133             :     SCCOL mnArrX;
     134             :     SCSIZE& mrArrY;
     135             :     SCROW mnHiddenEndRow;
     136             :     bool mbHiddenRow;
     137             : 
     138      417070 :     bool isHidden(size_t nRow)
     139             :     {
     140      417070 :         SCROW nThisRow = static_cast<SCROW>(nRow);
     141      417070 :         if (nThisRow > mnHiddenEndRow)
     142       71733 :             mbHiddenRow = mrDoc.RowHidden(nThisRow, mnTab, NULL, &mnHiddenEndRow);
     143      417070 :         return mbHiddenRow;
     144             :     }
     145             : 
     146      416509 :     void alignArray(size_t nRow)
     147             :     {
     148     1447200 :         while (mpRowInfo[mrArrY].nRowNo < static_cast<SCROW>(nRow))
     149      614182 :             ++mrArrY;
     150      416509 :     }
     151             : 
     152      416509 :     void setInfo(size_t nRow, const ScRefCellValue& rCell)
     153             :     {
     154      416509 :         alignArray(nRow);
     155             : 
     156      416509 :         RowInfo* pThisRowInfo = &mpRowInfo[mrArrY];
     157      416509 :         CellInfo* pInfo = &pThisRowInfo->pCellInfo[mnArrX];
     158      416509 :         pInfo->maCell = rCell;
     159      416509 :         pThisRowInfo->bEmptyText = false;
     160      416509 :         pInfo->bEmptyCellText = false;
     161      416509 :         ++mrArrY;
     162      416509 :     }
     163             : 
     164             : public:
     165      119404 :     RowInfoFiller(ScDocument& rDoc, SCTAB nTab, RowInfo* pRowInfo, SCCOL nArrX, SCSIZE& rArrY) :
     166             :         mrDoc(rDoc), mnTab(nTab), mpRowInfo(pRowInfo), mnArrX(nArrX), mrArrY(rArrY),
     167      119404 :         mnHiddenEndRow(-1), mbHiddenRow(false) {}
     168             : 
     169      304860 :     void operator() (size_t nRow, double fVal)
     170             :     {
     171      304860 :         if (!isHidden(nRow))
     172      304614 :             setInfo(nRow, ScRefCellValue(fVal));
     173      304860 :     }
     174             : 
     175      106844 :     void operator() (size_t nRow, const svl::SharedString& rStr)
     176             :     {
     177      106844 :         if (!isHidden(nRow))
     178      106539 :             setInfo(nRow, ScRefCellValue(&rStr));
     179      106844 :     }
     180             : 
     181         930 :     void operator() (size_t nRow, const EditTextObject* p)
     182             :     {
     183         930 :         if (!isHidden(nRow))
     184         930 :             setInfo(nRow, ScRefCellValue(p));
     185         930 :     }
     186             : 
     187        4436 :     void operator() (size_t nRow, const ScFormulaCell* p)
     188             :     {
     189        4436 :         if (!isHidden(nRow))
     190        4426 :             setInfo(nRow, ScRefCellValue(const_cast<ScFormulaCell*>(p)));
     191        4436 :     }
     192             : };
     193             : 
     194             : }
     195             : 
     196       10483 : void ScDocument::FillInfo(
     197             :     ScTableInfo& rTabInfo, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     198             :     SCTAB nTab, double fColScale, double fRowScale, bool bPageMode, bool bFormulaMode,
     199             :     const ScMarkData* pMarkData )
     200             : {
     201             :     OSL_ENSURE( maTabs[nTab], "Table does not exist" );
     202             : 
     203       10483 :     bool bLayoutRTL = IsLayoutRTL( nTab );
     204             : 
     205       10483 :     ScDocumentPool* pPool = xPoolHelper->GetDocPool();
     206       10483 :     ScStyleSheetPool* pStlPool = xPoolHelper->GetStylePool();
     207             : 
     208       10483 :     RowInfo* pRowInfo = rTabInfo.mpRowInfo;
     209             : 
     210             :     const SvxBrushItem* pDefBackground =
     211       10483 :             static_cast<const SvxBrushItem*>( &pPool->GetDefaultItem( ATTR_BACKGROUND ) );
     212             :     const ScMergeAttr* pDefMerge =
     213       10483 :             static_cast<const ScMergeAttr*>( &pPool->GetDefaultItem( ATTR_MERGE ) );
     214             :     const SvxShadowItem* pDefShadow =
     215       10483 :             static_cast<const SvxShadowItem*>( &pPool->GetDefaultItem( ATTR_SHADOW ) );
     216             : 
     217             :     SCROW nThisRow;
     218             :     SCCOL nX;
     219             :     SCROW nY;
     220             :     SCsROW nSignedY;
     221             :     SCCOL nArrCol;
     222             :     SCSIZE nArrRow;
     223             :     SCSIZE nArrCount;
     224       10483 :     bool bAnyMerged = false;
     225       10483 :     bool bAnyShadow = false;
     226       10483 :     bool bAnyCondition = false;
     227       10483 :     bool bAnyPreview = false;
     228             : 
     229       10483 :     bool bTabProtect = IsTabProtected(nTab);
     230             : 
     231             :                                                 // for block marks of merged cells
     232             :                                                 // with hidden first row/column
     233       10483 :     bool bPaintMarks = false;
     234       10483 :     bool bSkipMarks = false;
     235       10483 :     SCCOL nBlockStartX = 0, nBlockEndX = 0;
     236       10483 :     SCROW nBlockEndY = 0, nBlockStartY = 0;
     237       10483 :     if (pMarkData && pMarkData->IsMarked())
     238             :     {
     239         172 :         ScRange aTmpRange;
     240         172 :         pMarkData->GetMarkArea(aTmpRange);
     241         172 :         if ( nTab >= aTmpRange.aStart.Tab() && nTab <= aTmpRange.aEnd.Tab() )
     242             :         {
     243         172 :             nBlockStartX = aTmpRange.aStart.Col();
     244         172 :             nBlockStartY = aTmpRange.aStart.Row();
     245         172 :             nBlockEndX = aTmpRange.aEnd.Col();
     246         172 :             nBlockEndY = aTmpRange.aEnd.Row();
     247         172 :             ExtendHidden( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY, nTab );   //? needed ?
     248         172 :             if (pMarkData->IsMarkNegative())
     249           0 :                 bSkipMarks = true;
     250             :             else
     251         172 :                 bPaintMarks = true;
     252             :         }
     253             :     }
     254             : 
     255             :     // first only the entries for the entire column
     256             : 
     257       10483 :     nArrRow=0;
     258       10483 :     SCROW nYExtra = nRow2+1;
     259       10483 :     sal_uInt16 nDocHeight = ScGlobal::nStdRowHeight;
     260       10483 :     SCROW nDocHeightEndRow = -1;
     261      242438 :     for (nSignedY=((SCsROW)nRow1)-1; nSignedY<=(SCsROW)nYExtra; nSignedY++)
     262             :     {
     263      231955 :         if (nSignedY >= 0)
     264      223293 :             nY = (SCROW) nSignedY;
     265             :         else
     266        8662 :             nY = MAXROW+1;          // invalid
     267             : 
     268      231955 :         if (nY > nDocHeightEndRow)
     269             :         {
     270       23828 :             if (ValidRow(nY))
     271       15158 :                 nDocHeight = GetRowHeight( nY, nTab, NULL, &nDocHeightEndRow );
     272             :             else
     273        8670 :                 nDocHeight = ScGlobal::nStdRowHeight;
     274             :         }
     275             : 
     276      231955 :         if ( nArrRow==0 || nDocHeight || nY > MAXROW )
     277             :         {
     278      231570 :             RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     279      231570 :             pThisRowInfo->pCellInfo = NULL;                 // is loaded below
     280             : 
     281      231570 :             sal_uInt16 nHeight = (sal_uInt16) ( nDocHeight * fRowScale );
     282      231570 :             if (!nHeight)
     283           0 :                 nHeight = 1;
     284             : 
     285      231570 :             pThisRowInfo->nRowNo        = nY;               //TODO: case < 0 ?
     286      231570 :             pThisRowInfo->nHeight       = nHeight;
     287      231570 :             pThisRowInfo->bEmptyBack    = true;
     288      231570 :             pThisRowInfo->bEmptyText    = true;
     289      231570 :             pThisRowInfo->bChanged      = true;
     290      231570 :             pThisRowInfo->bAutoFilter   = false;
     291      231570 :             pThisRowInfo->bPivotButton  = false;
     292      231570 :             pThisRowInfo->nRotMaxCol    = SC_ROTMAX_NONE;
     293             : 
     294      231570 :             ++nArrRow;
     295      231570 :             if (nArrRow >= ROWINFO_MAX)
     296             :             {
     297             :                 OSL_FAIL("FillInfo: Range too big" );
     298           0 :                 nYExtra = nSignedY;                         // End
     299           0 :                 nRow2 = nYExtra - 1;                        // Adjust range
     300      231570 :             }
     301             :         }
     302             :         else
     303         385 :             if (nSignedY==(SCsROW) nYExtra)                 // hidden additional line?
     304           0 :                 ++nYExtra;
     305             :     }
     306       10483 :     nArrCount = nArrRow;                                      // incl. Dummys
     307             : 
     308             :     // Rotated text...
     309             : 
     310             :     // Is Attribute really used in document?
     311       10483 :     bool bAnyItem = false;
     312       10483 :     sal_uInt32 nRotCount = pPool->GetItemCount2( ATTR_ROTATE_VALUE );
     313       10483 :     for (sal_uInt32 nItem=0; nItem<nRotCount; nItem++)
     314       10483 :         if (pPool->GetItem2( ATTR_ROTATE_VALUE, nItem ))
     315             :         {
     316       10483 :             bAnyItem = true;
     317       10483 :             break;
     318             :         }
     319             : 
     320       10483 :     SCCOL nRotMax = nCol2;
     321       20966 :     if ( bAnyItem && HasAttrib( 0,nRow1,nTab, MAXCOL,nRow2+1,nTab,
     322       10483 :                                 HASATTR_ROTATE | HASATTR_CONDITIONAL ) )
     323             :     {
     324             :         //TODO: check Conditionals also for HASATTR_ROTATE ????
     325             : 
     326             :         OSL_ENSURE( nArrCount>2, "nArrCount too small" );
     327         400 :         FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-1, nCol1, nCol2 );
     328             :         //  FindMaxRotCol setzt nRotMaxCol
     329             : 
     330        3810 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     331        3410 :             if (pRowInfo[nArrRow].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nArrRow].nRotMaxCol > nRotMax)
     332           0 :                 nRotMax = pRowInfo[nArrRow].nRotMaxCol;
     333             :     }
     334             : 
     335             :     //  Allocate cell information only after the test rotation
     336             :     //  to nRotMax due to nRotateDir Flag
     337             : 
     338      242053 :     for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     339             :     {
     340      231570 :         RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     341      231570 :         nY = pThisRowInfo->nRowNo;
     342      231570 :         pThisRowInfo->pCellInfo = new CellInfo[ nRotMax+1+2 ];  // to delete the caller!
     343             : 
     344     3193932 :         for (nArrCol=0; nArrCol<=nRotMax+2; nArrCol++)          // Preassign cell info
     345             :         {
     346     2962362 :             if (nArrCol>0)
     347     2730792 :                 nX = nArrCol-1;
     348             :             else
     349      231570 :                 nX = MAXCOL+1;      // invalid
     350             : 
     351     2962362 :             CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     352     2962362 :             pInfo->bEmptyCellText = true;
     353     2962362 :             pInfo->maCell.clear();
     354     2962362 :             if (bPaintMarks)
     355      451094 :                 pInfo->bMarked = ( nX >= nBlockStartX && nX <= nBlockEndX
     356      239118 :                                 && nY >= nBlockStartY && nY <= nBlockEndY );
     357             :             else
     358     2728926 :                 pInfo->bMarked = false;
     359     2962362 :             pInfo->nWidth = 0;
     360             : 
     361     2962362 :             pInfo->nClipMark    = SC_CLIPMARK_NONE;
     362     2962362 :             pInfo->bMerged      = false;
     363     2962362 :             pInfo->bHOverlapped = false;
     364     2962362 :             pInfo->bVOverlapped = false;
     365     2962362 :             pInfo->bAutoFilter  = false;
     366     2962362 :             pInfo->bPivotButton  = false;
     367     2962362 :             pInfo->bPivotPopupButton = false;
     368     2962362 :             pInfo->bFilterActive = false;
     369     2962362 :             pInfo->nRotateDir   = SC_ROTDIR_NONE;
     370             : 
     371     2962362 :             pInfo->bPrinted     = false;                    //  view-internal
     372     2962362 :             pInfo->bHideGrid    = false;                    //  view-internal
     373     2962362 :             pInfo->bEditEngine  = false;                    //  view-internal
     374             : 
     375     2962362 :             pInfo->pBackground  = NULL;                     //TODO: omit?
     376     2962362 :             pInfo->pPatternAttr = NULL;
     377     2962362 :             pInfo->pConditionSet= NULL;
     378             : 
     379     2962362 :             pInfo->pLinesAttr   = NULL;
     380     2962362 :             pInfo->mpTLBRLine   = NULL;
     381     2962362 :             pInfo->mpBLTRLine   = NULL;
     382             : 
     383     2962362 :             pInfo->pShadowAttr    = pDefShadow;
     384     2962362 :             pInfo->pHShadowOrigin = NULL;
     385     2962362 :             pInfo->pVShadowOrigin = NULL;
     386             :         }
     387             :     }
     388             : 
     389       10483 :     for (nArrCol=nCol2+3; nArrCol<=nRotMax+2; nArrCol++)    // Add remaining widths
     390             :     {
     391           0 :         nX = nArrCol-1;
     392           0 :         if ( ValidCol(nX) )
     393             :         {
     394           0 :             if (!ColHidden(nX, nTab))
     395             :             {
     396           0 :                 sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * fColScale);
     397           0 :                 if (!nThisWidth)
     398           0 :                     nThisWidth = 1;
     399             : 
     400           0 :                 pRowInfo[0].pCellInfo[nArrCol].nWidth = nThisWidth;
     401             :             }
     402             :         }
     403             :     }
     404             : 
     405       10483 :     ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
     406       10483 :     if(pCondFormList)
     407       10483 :         pCondFormList->startRendering();
     408             : 
     409      141173 :     for (nArrCol=0; nArrCol<=nCol2+2; nArrCol++)                    // left & right + 1
     410             :     {
     411      130690 :         nX = (nArrCol>0) ? nArrCol-1 : MAXCOL+1;                    // negative -> invalid
     412             : 
     413      130690 :         if ( ValidCol(nX) )
     414             :         {
     415             :             // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes
     416             :             // will disturb the output
     417             : 
     418             :             // TODO: Optimize this loop.
     419      120202 :             if (!ColHidden(nX, nTab))
     420             :             {
     421      119404 :                 sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * fColScale);
     422      119404 :                 if (!nThisWidth)
     423           0 :                     nThisWidth = 1;
     424             : 
     425      119404 :                 pRowInfo[0].pCellInfo[nArrCol].nWidth = nThisWidth;           //TODO: this should be enough
     426             : 
     427      119404 :                 ScColumn* pThisCol = &maTabs[nTab]->aCol[nX];                   // Column data
     428             : 
     429      119404 :                 nArrRow = 1;
     430             :                 // Iterate between rows nY1 and nY2 and pick up non-empty
     431             :                 // cells that are not hidden.
     432      119404 :                 RowInfoFiller aFunc(*this, nTab, pRowInfo, nArrCol, nArrRow);
     433             :                 sc::ParseAllNonEmpty(
     434      119404 :                     pThisCol->maCells.begin(), pThisCol->maCells, nRow1, nRow2, aFunc);
     435             : 
     436      119404 :                 if (nX+1 >= nCol1)                                // Attribute/Blockmark from nX1-1
     437             :                 {
     438      108196 :                     ScAttrArray* pThisAttrArr = pThisCol->pAttrArray;       // Attribute
     439             : 
     440      108196 :                     nArrRow = 0;
     441             :                     const ScPatternAttr* pPattern;
     442      108196 :                     SCROW nCurRow=nRow1;                  // single rows
     443      108196 :                     if (nCurRow>0)
     444       17263 :                         --nCurRow;                      // 1 more on top
     445             :                     else
     446       90933 :                         nArrRow = 1;
     447      108196 :                     nThisRow=nCurRow;                   // end of range
     448             :                     SCSIZE  nIndex;
     449      108196 :                     (void) pThisAttrArr->Search( nCurRow, nIndex );
     450             : 
     451      187685 :                     do
     452             :                     {
     453      187685 :                         nThisRow=pThisAttrArr->pData[nIndex].nRow;              // End of range
     454      187685 :                         pPattern=pThisAttrArr->pData[nIndex].pPattern;
     455             : 
     456             :                         const SvxBrushItem* pBackground = static_cast<const SvxBrushItem*>(
     457      187685 :                                                         &pPattern->GetItem(ATTR_BACKGROUND));
     458             :                         const SvxBoxItem* pLinesAttr = static_cast<const SvxBoxItem*>(
     459      187685 :                                                         &pPattern->GetItem(ATTR_BORDER));
     460             : 
     461             :                         const SvxLineItem* pTLBRLine = static_cast< const SvxLineItem* >(
     462      187685 :                             &pPattern->GetItem( ATTR_BORDER_TLBR ) );
     463             :                         const SvxLineItem* pBLTRLine = static_cast< const SvxLineItem* >(
     464      187685 :                             &pPattern->GetItem( ATTR_BORDER_BLTR ) );
     465             : 
     466             :                         const SvxShadowItem* pShadowAttr = static_cast<const SvxShadowItem*>(
     467      187685 :                                                         &pPattern->GetItem(ATTR_SHADOW));
     468      187685 :                         if (pShadowAttr != pDefShadow)
     469        1418 :                             bAnyShadow = true;
     470             : 
     471             :                         const ScMergeAttr* pMergeAttr = static_cast<const ScMergeAttr*>(
     472      187685 :                                                 &pPattern->GetItem(ATTR_MERGE));
     473      187685 :                         bool bMerged = ( pMergeAttr != pDefMerge && *pMergeAttr != *pDefMerge );
     474      187685 :                         sal_uInt16 nOverlap = static_cast<const ScMergeFlagAttr*>( &pPattern->GetItemSet().
     475      187685 :                                                         Get(ATTR_MERGE_FLAG))->GetValue();
     476      187685 :                         bool bHOverlapped = ((nOverlap & SC_MF_HOR) != 0);
     477      187685 :                         bool bVOverlapped = ((nOverlap & SC_MF_VER) != 0);
     478      187685 :                         bool bAutoFilter  = ((nOverlap & SC_MF_AUTO) != 0);
     479      187685 :                         bool bPivotButton  = ((nOverlap & SC_MF_BUTTON) != 0);
     480      187685 :                         bool bScenario    = ((nOverlap & SC_MF_SCENARIO) != 0);
     481      187685 :                         bool bPivotPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0);
     482      187685 :                         bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0);
     483      187685 :                         if (bMerged||bHOverlapped||bVOverlapped)
     484        1635 :                             bAnyMerged = true;                              // internal
     485             : 
     486             :                         bool bHidden, bHideFormula;
     487      187685 :                         if (bTabProtect)
     488             :                         {
     489             :                             const ScProtectionAttr& rProtAttr = static_cast<const ScProtectionAttr&>(
     490           0 :                                                         pPattern->GetItem(ATTR_PROTECTION));
     491           0 :                             bHidden = rProtAttr.GetHideCell();
     492           0 :                             bHideFormula = rProtAttr.GetHideFormula();
     493             :                         }
     494             :                         else
     495      187685 :                             bHidden = bHideFormula = false;
     496             : 
     497      187685 :                         const std::vector<sal_uInt32>& rCondFormats = static_cast<const ScCondFormatItem&>(pPattern->GetItem(ATTR_CONDITIONAL)).GetCondFormatData();
     498      187685 :                         bool bContainsCondFormat = !rCondFormats.empty();
     499             : 
     500     2398618 :                         do
     501             :                         {
     502     2398618 :                             SCROW nLastHiddenRow = -1;
     503     2398618 :                             bool bRowHidden = RowHidden(nCurRow, nTab, NULL, &nLastHiddenRow);
     504     2398618 :                             if ( nArrRow==0 || !bRowHidden )
     505             :                             {
     506     2396897 :                                 if ( GetPreviewCellStyle( nX, nCurRow, nTab  ) != NULL )
     507           0 :                                     bAnyPreview = true;
     508     2396897 :                                 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     509     2396897 :                                 if (pBackground != pDefBackground)          // Column background == Default ?
     510      270012 :                                     pThisRowInfo->bEmptyBack = false;
     511     2396897 :                                 if (bContainsCondFormat)
     512        2740 :                                     pThisRowInfo->bEmptyBack = false;
     513     2396897 :                                 if (bAutoFilter)
     514         141 :                                     pThisRowInfo->bAutoFilter = true;
     515     2396897 :                                 if (bPivotButton || bPivotPopupButton)
     516         471 :                                     pThisRowInfo->bPivotButton = true;
     517             : 
     518     2396897 :                                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     519     2396897 :                                 pInfo->pBackground  = pBackground;
     520     2396897 :                                 pInfo->pPatternAttr = pPattern;
     521     2396897 :                                 pInfo->bMerged      = bMerged;
     522     2396897 :                                 pInfo->bHOverlapped = bHOverlapped;
     523     2396897 :                                 pInfo->bVOverlapped = bVOverlapped;
     524     2396897 :                                 pInfo->bAutoFilter  = bAutoFilter;
     525     2396897 :                                 pInfo->bPivotButton  = bPivotButton;
     526     2396897 :                                 pInfo->bPivotPopupButton = bPivotPopupButton;
     527     2396897 :                                 pInfo->bFilterActive = bFilterActive;
     528     2396897 :                                 pInfo->pLinesAttr   = pLinesAttr;
     529     2396897 :                                 pInfo->mpTLBRLine   = pTLBRLine;
     530     2396897 :                                 pInfo->mpBLTRLine   = pBLTRLine;
     531     2396897 :                                 pInfo->pShadowAttr  = pShadowAttr;
     532             :                                 // nWidth is no longer set individually
     533             : 
     534     2396897 :                                 if (bScenario)
     535             :                                 {
     536           0 :                                     pInfo->pBackground = ScGlobal::GetButtonBrushItem();
     537           0 :                                     pThisRowInfo->bEmptyBack = false;
     538             :                                 }
     539             : 
     540     2396897 :                                 if ( bContainsCondFormat )
     541             :                                 {
     542        2740 :                                     bool bFound = false;
     543       16440 :                                     for(std::vector<sal_uInt32>::const_iterator itr = rCondFormats.begin();
     544       16440 :                                             itr != rCondFormats.end() && !bFound; ++itr)
     545             :                                     {
     546        2740 :                                         ScConditionalFormat* pCondForm = pCondFormList->GetFormat(*itr);
     547        2740 :                                         if(!pCondForm)
     548           0 :                                             continue;
     549             : 
     550             :                                         ScCondFormatData aData = pCondForm->GetData(
     551        2740 :                                             pInfo->maCell, ScAddress(nX, nCurRow, nTab));
     552        2740 :                                         if (!aData.aStyleName.isEmpty())
     553             :                                         {
     554             :                                             SfxStyleSheetBase* pStyleSheet =
     555         176 :                                                 pStlPool->Find( aData.aStyleName, SFX_STYLE_FAMILY_PARA );
     556         176 :                                             if ( pStyleSheet )
     557             :                                             {
     558             :                                                 //TODO: cache Style-Sets !!!
     559         176 :                                                 pInfo->pConditionSet = &pStyleSheet->GetItemSet();
     560         176 :                                                 bAnyCondition = true;
     561             : 
     562             :                                                 // we need to check already here for protected cells
     563             :                                                 const SfxPoolItem* pItem;
     564         176 :                                                 if ( bTabProtect && pInfo->pConditionSet->GetItemState( ATTR_PROTECTION, true, &pItem ) == SfxItemState::SET )
     565             :                                                 {
     566           0 :                                                     const ScProtectionAttr* pProtAttr = static_cast<const ScProtectionAttr*>(pItem);
     567           0 :                                                     bHidden = pProtAttr->GetHideCell();
     568           0 :                                                     bHideFormula = pProtAttr->GetHideFormula();
     569             : 
     570             :                                                 }
     571         176 :                                                 bFound = true;
     572             : 
     573             :                                             }
     574             :                                             // if style is not there, treat like no condition
     575             :                                         }
     576        2740 :                                         if(aData.pColorScale)
     577             :                                         {
     578           0 :                                             pInfo->pColorScale.reset(aData.pColorScale);
     579           0 :                                             bFound = true;
     580             :                                         }
     581             : 
     582        2740 :                                         if(aData.pDataBar)
     583             :                                         {
     584           0 :                                             pInfo->pDataBar.reset(aData.pDataBar);
     585           0 :                                             bFound = true;
     586             :                                         }
     587        2740 :                                         if(aData.pIconSet)
     588             :                                         {
     589           0 :                                             pInfo->pIconSet.reset(aData.pIconSet);
     590           0 :                                             bFound = true;
     591             :                                         }
     592        2740 :                                     }
     593             :                                 }
     594             : 
     595     2396897 :                                 if (bHidden || (bFormulaMode && bHideFormula && pInfo->maCell.meType == CELLTYPE_FORMULA))
     596           0 :                                     pInfo->bEmptyCellText = true;
     597             : 
     598     2396897 :                                 ++nArrRow;
     599             :                             }
     600        1721 :                             else if (bRowHidden && nLastHiddenRow >= 0)
     601             :                             {
     602        1721 :                                 nCurRow = nLastHiddenRow;
     603        1721 :                                 if (nCurRow > nThisRow)
     604          70 :                                     nCurRow = nThisRow;
     605             :                             }
     606     2398618 :                             ++nCurRow;
     607             :                         }
     608     2311930 :                         while (nCurRow <= nThisRow && nCurRow <= nYExtra);
     609      187685 :                         ++nIndex;
     610             :                     }
     611      308129 :                     while ( nIndex < pThisAttrArr->nCount && nThisRow < nYExtra );
     612             : 
     613      108196 :                     if (pMarkData && pMarkData->IsMultiMarked())
     614             :                     {
     615             :                         //  Block marks
     616         282 :                         const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nX;
     617         282 :                         nArrRow = 1;
     618         282 :                         nCurRow = nRow1;                                      // single rows
     619         282 :                         nThisRow = nRow1;                                     // End of range
     620             : 
     621         282 :                         if ( pThisMarkArr->Search( nRow1, nIndex ) )
     622             :                         {
     623         334 :                             do
     624             :                             {
     625         334 :                                 nThisRow=pThisMarkArr->pData[nIndex].nRow;      // End of range
     626         334 :                                 const bool bThisMarked=pThisMarkArr->pData[nIndex].bMarked;
     627             : 
     628        2506 :                                 do
     629             :                                 {
     630        2506 :                                     if ( !RowHidden( nCurRow,nTab ) )
     631             :                                     {
     632        2506 :                                         if ( bThisMarked )
     633             :                                         {
     634           0 :                                             bool bSkip = bSkipMarks &&
     635           0 :                                                         nX      >= nBlockStartX &&
     636           0 :                                                         nX      <= nBlockEndX   &&
     637         919 :                                                         nCurRow >= nBlockStartY &&
     638         919 :                                                         nCurRow <= nBlockEndY;
     639         919 :                                             if (!bSkip)
     640             :                                             {
     641         919 :                                                 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     642         919 :                                                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     643         919 :                                                 pInfo->bMarked = true;
     644             :                                             }
     645             :                                         }
     646        2506 :                                         ++nArrRow;
     647             :                                     }
     648        2506 :                                     ++nCurRow;
     649             :                                 }
     650        2279 :                                 while (nCurRow <= nThisRow && nCurRow <= nRow2);
     651         334 :                                 ++nIndex;
     652             :                             }
     653         576 :                             while ( nIndex < pThisMarkArr->nCount && nThisRow < nRow2 );
     654             :                         }
     655             :                     }
     656             :                 }
     657             :                 else                                    // columns in front
     658             :                 {
     659      210825 :                     for (nArrRow=1; nArrRow+1<nArrCount; nArrRow++)
     660             :                     {
     661      199617 :                         RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     662      199617 :                         CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     663             : 
     664      199617 :                         pInfo->nWidth       = nThisWidth;           //TODO: or check only 0 ??
     665             :                     }
     666             :                 }
     667             :             }
     668             :         }
     669             :         else
     670       10488 :             pRowInfo[0].pCellInfo[nArrCol].nWidth = STD_COL_WIDTH;
     671             :         // STD_COL_WIDTH farthest to the left and right is needed for DrawExtraShadow
     672             :     }
     673             : 
     674       10483 :     if(pCondFormList)
     675       10483 :         pCondFormList->endRendering();
     676             : 
     677             :     //  bedingte Formatierung auswerten
     678       10483 :     ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
     679             :     // favour preview over condition
     680       10483 :     if (bAnyCondition || bAnyPreview)
     681             :     {
     682        1409 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     683             :         {
     684       18560 :             for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)                  // 1 more left and right
     685             :             {
     686       17200 :                 CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
     687       17200 :                 SCCOL nCol = (nArrCol>0) ? nArrCol-1 : MAXCOL+1;
     688       17200 :                 ScPatternAttr* pModifiedPatt = NULL;
     689             : 
     690       17200 :                 if ( ValidCol(nCol) && pRowInfo[nArrRow].nRowNo <= MAXROW )
     691             :                 {
     692       15270 :                     if ( ScStyleSheet* pPreviewStyle = GetPreviewCellStyle( nCol, pRowInfo[nArrRow].nRowNo, nTab ) )
     693             :                     {
     694           0 :                         aAltPatterns.push_back( new ScPatternAttr( *pInfo->pPatternAttr ) );
     695           0 :                         pModifiedPatt = &aAltPatterns.back();
     696           0 :                         pModifiedPatt->SetStyleSheet( pPreviewStyle );
     697             :                     }
     698             :                 }
     699             :                 // favour preview over condition
     700       17200 :                 const SfxItemSet* pCondSet = pModifiedPatt ? &pModifiedPatt->GetItemSet() : pInfo->pConditionSet;
     701             : 
     702       17200 :                 if (pCondSet)
     703             :                 {
     704             :                     const SfxPoolItem* pItem;
     705             : 
     706             :                             // Background
     707         176 :                     if ( pCondSet->GetItemState( ATTR_BACKGROUND, true, &pItem ) == SfxItemState::SET )
     708             :                     {
     709          90 :                         pInfo->pBackground = static_cast<const SvxBrushItem*>(pItem);
     710          90 :                         pRowInfo[nArrRow].bEmptyBack = false;
     711             :                     }
     712             : 
     713             :                             // Border
     714         176 :                     if ( pCondSet->GetItemState( ATTR_BORDER, true, &pItem ) == SfxItemState::SET )
     715          90 :                         pInfo->pLinesAttr = static_cast<const SvxBoxItem*>(pItem);
     716             : 
     717         176 :                     if ( pCondSet->GetItemState( ATTR_BORDER_TLBR, true, &pItem ) == SfxItemState::SET )
     718          90 :                         pInfo->mpTLBRLine = static_cast< const SvxLineItem* >( pItem );
     719         176 :                     if ( pCondSet->GetItemState( ATTR_BORDER_BLTR, true, &pItem ) == SfxItemState::SET )
     720          90 :                         pInfo->mpBLTRLine = static_cast< const SvxLineItem* >( pItem );
     721             : 
     722             :                             //  Shadow
     723         176 :                     if ( pCondSet->GetItemState( ATTR_SHADOW, true, &pItem ) == SfxItemState::SET )
     724             :                     {
     725           0 :                         pInfo->pShadowAttr = static_cast<const SvxShadowItem*>(pItem);
     726           0 :                         bAnyShadow = true;
     727             :                     }
     728             :                 }
     729       17200 :                 if( bAnyCondition && pInfo->pColorScale)
     730             :                 {
     731           0 :                     pRowInfo[nArrRow].bEmptyBack = false;
     732           0 :                     pInfo->pBackground = new SvxBrushItem(*pInfo->pColorScale, ATTR_BACKGROUND);
     733             :                 }
     734             :             }
     735             :         }
     736             :     }
     737             : 
     738             :     // End conditional formatting
     739             : 
     740             :                 //      Adjust data from merged cells
     741             : 
     742       10483 :     if (bAnyMerged)
     743             :     {
     744        7082 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     745             :         {
     746        6816 :             RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     747        6816 :             nSignedY = nArrRow ? pThisRowInfo->nRowNo : ((SCsROW)nRow1)-1;
     748             : 
     749      121700 :             for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)                  // 1 more left and right
     750             :             {
     751      114884 :                 SCsCOL nSignedX = ((SCsCOL) nArrCol) - 1;
     752      114884 :                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     753             : 
     754      114884 :                 if (pInfo->bMerged || pInfo->bHOverlapped || pInfo->bVOverlapped)
     755             :                 {
     756             :                     SCsCOL nStartX;
     757             :                     SCsROW nStartY;
     758             :                     SCsCOL nEndX;
     759             :                     SCsROW nEndY;
     760             :                     lcl_GetMergeRange( nSignedX,nSignedY, nArrRow, this,pRowInfo, nCol1,nRow1,nCol2,nRow2,nTab,
     761        1679 :                                         nStartX,nStartY, nEndX,nEndY );
     762        1679 :                     const ScPatternAttr* pStartPattern = GetPattern( nStartX,nStartY,nTab );
     763        1679 :                     const SfxItemSet* pStartCond = GetCondResult( nStartX,nStartY,nTab );
     764             :                     const SfxPoolItem* pItem;
     765             : 
     766             :                     // Copy Background (or in output.cxx)
     767             : 
     768        1679 :                     if ( !pStartCond || pStartCond->
     769           0 :                                     GetItemState(ATTR_BACKGROUND,true,&pItem) != SfxItemState::SET )
     770        1679 :                         pItem = &pStartPattern->GetItem(ATTR_BACKGROUND);
     771        1679 :                     pInfo->pBackground = static_cast<const SvxBrushItem*>(pItem);
     772        1679 :                     pRowInfo[nArrRow].bEmptyBack = false;
     773             : 
     774             :                     // Shadow
     775             : 
     776        1679 :                     if ( !pStartCond || pStartCond->
     777           0 :                                     GetItemState(ATTR_SHADOW,true,&pItem) != SfxItemState::SET )
     778        1679 :                         pItem = &pStartPattern->GetItem(ATTR_SHADOW);
     779        1679 :                     pInfo->pShadowAttr = static_cast<const SvxShadowItem*>(pItem);
     780        1679 :                     if (pInfo->pShadowAttr != pDefShadow)
     781           0 :                         bAnyShadow = true;
     782             : 
     783             :                     // Block marks - again with the original merge values
     784             : 
     785        1679 :                     bool bCellMarked = false;
     786        1679 :                     if (bPaintMarks)
     787          18 :                         bCellMarked = ( nStartX >= (SCsCOL) nBlockStartX
     788          18 :                                     && nStartX <= (SCsCOL) nBlockEndX
     789           0 :                                     && nStartY >= (SCsROW) nBlockStartY
     790          18 :                                     && nStartY <= (SCsROW) nBlockEndY );
     791        1679 :                     if (pMarkData && pMarkData->IsMultiMarked() && !bCellMarked)
     792             :                     {
     793          72 :                         const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nStartX;
     794             :                         SCSIZE nIndex;
     795          72 :                         if ( pThisMarkArr->Search( nStartY, nIndex ) )
     796           0 :                             bCellMarked=pThisMarkArr->pData[nIndex].bMarked;
     797             :                     }
     798             : 
     799        1679 :                     pInfo->bMarked = bCellMarked;
     800             :                 }
     801             :             }
     802             :         }
     803             :     }
     804             : 
     805       10483 :     if (bAnyShadow)                             // distribute Shadow
     806             :     {
     807        2558 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     808             :         {
     809        2199 :             bool bTop = ( nArrRow == 0 );
     810        2199 :             bool bBottom = ( nArrRow+1 == nArrCount );
     811             : 
     812       26380 :             for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)                  // 1 more left and right
     813             :             {
     814       24181 :                 bool bLeft = ( nArrCol == nCol1 );
     815       24181 :                 bool bRight = ( nArrCol == nCol2+2 );
     816             : 
     817       24181 :                 CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
     818       24181 :                 const SvxShadowItem* pThisAttr = pInfo->pShadowAttr;
     819       24181 :                 SvxShadowLocation eLoc = pThisAttr ? pThisAttr->GetLocation() : SVX_SHADOW_NONE;
     820       24181 :                 if (eLoc != SVX_SHADOW_NONE)
     821             :                 {
     822             :                     //  or test on != eLoc
     823             : 
     824           0 :                     SCsCOL nDxPos = 1;
     825           0 :                     SCsCOL nDxNeg = -1;
     826             : 
     827           0 :                     while ( nArrCol+nDxPos < nCol2+2 && pRowInfo[0].pCellInfo[nArrCol+nDxPos].nWidth == 0 )
     828           0 :                         ++nDxPos;
     829           0 :                     while ( nArrCol+nDxNeg > nCol1 && pRowInfo[0].pCellInfo[nArrCol+nDxNeg].nWidth == 0 )
     830           0 :                         --nDxNeg;
     831             : 
     832           0 :                     bool bLeftDiff = !bLeft &&
     833           0 :                             pRowInfo[nArrRow].pCellInfo[nArrCol+nDxNeg].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     834           0 :                     bool bRightDiff = !bRight &&
     835           0 :                             pRowInfo[nArrRow].pCellInfo[nArrCol+nDxPos].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     836           0 :                     bool bTopDiff = !bTop &&
     837           0 :                             pRowInfo[nArrRow-1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     838           0 :                     bool bBottomDiff = !bBottom &&
     839           0 :                             pRowInfo[nArrRow+1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     840             : 
     841           0 :                     if ( bLayoutRTL )
     842             :                     {
     843           0 :                         switch (eLoc)
     844             :                         {
     845           0 :                             case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT;  break;
     846           0 :                             case SVX_SHADOW_BOTTOMLEFT:  eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
     847           0 :                             case SVX_SHADOW_TOPRIGHT:    eLoc = SVX_SHADOW_TOPLEFT;     break;
     848           0 :                             case SVX_SHADOW_TOPLEFT:     eLoc = SVX_SHADOW_TOPRIGHT;    break;
     849             :                             default:
     850             :                             {
     851             :                                 // added to avoid warnings
     852             :                             }
     853             :                         }
     854             :                     }
     855             : 
     856           0 :                     switch (eLoc)
     857             :                     {
     858             :                         case SVX_SHADOW_BOTTOMRIGHT:
     859           0 :                             if (bBottomDiff)
     860             :                             {
     861           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     862           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
     863           0 :                                                 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     864             :                             }
     865           0 :                             if (bRightDiff)
     866             :                             {
     867           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
     868           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
     869           0 :                                                 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     870             :                             }
     871           0 :                             if (bBottomDiff && bRightDiff)
     872             :                             {
     873           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
     874           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
     875             :                             }
     876           0 :                             break;
     877             : 
     878             :                         case SVX_SHADOW_BOTTOMLEFT:
     879           0 :                             if (bBottomDiff)
     880             :                             {
     881           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     882           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
     883           0 :                                                 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     884             :                             }
     885           0 :                             if (bLeftDiff)
     886             :                             {
     887           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
     888           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
     889           0 :                                                 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     890             :                             }
     891           0 :                             if (bBottomDiff && bLeftDiff)
     892             :                             {
     893           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
     894           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
     895             :                             }
     896           0 :                             break;
     897             : 
     898             :                         case SVX_SHADOW_TOPRIGHT:
     899           0 :                             if (bTopDiff)
     900             :                             {
     901           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     902           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
     903           0 :                                                 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     904             :                             }
     905           0 :                             if (bRightDiff)
     906             :                             {
     907           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
     908           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
     909           0 :                                                 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     910             :                             }
     911           0 :                             if (bTopDiff && bRightDiff)
     912             :                             {
     913           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
     914           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
     915             :                             }
     916           0 :                             break;
     917             : 
     918             :                         case SVX_SHADOW_TOPLEFT:
     919           0 :                             if (bTopDiff)
     920             :                             {
     921           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     922           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
     923           0 :                                                 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     924             :                             }
     925           0 :                             if (bLeftDiff)
     926             :                             {
     927           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
     928           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
     929           0 :                                                 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     930             :                             }
     931           0 :                             if (bTopDiff && bLeftDiff)
     932             :                             {
     933           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
     934           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
     935             :                             }
     936           0 :                             break;
     937             : 
     938             :                         default:
     939             :                             OSL_FAIL("wrong Shadow-Enum");
     940             :                     }
     941             :                 }
     942             :             }
     943             :         }
     944             :     }
     945             : 
     946       10483 :     rTabInfo.mnArrCount = sal::static_int_cast<sal_uInt16>(nArrCount);
     947       10483 :     rTabInfo.mbPageMode = bPageMode;
     948             : 
     949             :     // *** create the frame border array ***
     950             : 
     951             :     // RowInfo structs are filled in the range [ 0 , nArrCount-1 ]
     952             :     // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ]
     953             : 
     954       10483 :     size_t nColCount = nCol2 - nCol1 + 3;
     955       10483 :     size_t nRowCount = nArrCount;
     956             : 
     957       10483 :     svx::frame::Array& rArray = rTabInfo.maArray;
     958       10483 :     rArray.Initialize( nColCount, nRowCount );
     959       10483 :     rArray.SetUseDiagDoubleClipping( false );
     960             : 
     961      242053 :     for( size_t nRow = 0; nRow < nRowCount; ++nRow )
     962             :     {
     963      231570 :         sal_uInt16 nCellInfoY = static_cast< sal_uInt16 >( nRow );
     964      231570 :         RowInfo& rThisRowInfo = pRowInfo[ nCellInfoY ];
     965             : 
     966     2960977 :         for( size_t nCol = 0; nCol < nColCount; ++nCol )
     967             :         {
     968     2729407 :             sal_uInt16 nCellInfoX = static_cast< sal_uInt16 >( nCol + nCol1 );
     969     2729407 :             const CellInfo& rInfo = rThisRowInfo.pCellInfo[ nCellInfoX ];
     970             : 
     971     2729407 :             const SvxBoxItem* pBox = rInfo.pLinesAttr;
     972     2729407 :             const SvxLineItem* pTLBR = rInfo.mpTLBRLine;
     973     2729407 :             const SvxLineItem* pBLTR = rInfo.mpBLTRLine;
     974             : 
     975     2729407 :             size_t nFirstCol = nCol;
     976     2729407 :             size_t nFirstRow = nRow;
     977             : 
     978             :             // *** merged cells *** -------------------------------------------
     979             : 
     980     2729407 :             if( !rArray.IsMerged( nCol, nRow ) && (rInfo.bMerged || rInfo.bHOverlapped || rInfo.bVOverlapped) )
     981             :             {
     982             :                 // *** insert merged range in svx::frame::Array ***
     983             : 
     984             :                 /*  #i69369# top-left cell of a merged range may be located in
     985             :                     a hidden column or row. Use lcl_GetMergeRange() to find the
     986             :                     complete merged range, then calculate dimensions and
     987             :                     document position of the visible range. */
     988             : 
     989             :                 // note: document columns are always one less than CellInfoX coords
     990             :                 // note: document rows must be looked up in RowInfo structs
     991             : 
     992             :                 // current column and row in document coordinates
     993         274 :                 SCCOL nCurrDocCol = static_cast< SCCOL >( nCellInfoX - 1 );
     994         274 :                 SCROW nCurrDocRow = static_cast< SCROW >( (nCellInfoY > 0) ? rThisRowInfo.nRowNo : (nRow1 - 1) );
     995             : 
     996             :                 // find entire merged range in document, returns signed document coordinates
     997             :                 SCsCOL nFirstRealDocColS, nLastRealDocColS;
     998             :                 SCsROW nFirstRealDocRowS, nLastRealDocRowS;
     999             :                 lcl_GetMergeRange( static_cast< SCsCOL >( nCurrDocCol ), static_cast< SCsROW >( nCurrDocRow ),
    1000             :                     nCellInfoY, this, pRowInfo, nCol1,nRow1,nCol2,nRow2,nTab,
    1001         274 :                     nFirstRealDocColS, nFirstRealDocRowS, nLastRealDocColS, nLastRealDocRowS );
    1002             : 
    1003             :                 // *complete* merged range in document coordinates
    1004         274 :                 SCCOL nFirstRealDocCol = static_cast< SCCOL >( nFirstRealDocColS );
    1005         274 :                 SCROW nFirstRealDocRow = static_cast< SCROW >( nFirstRealDocRowS );
    1006         274 :                 SCCOL nLastRealDocCol  = static_cast< SCCOL >( nLastRealDocColS );
    1007         274 :                 SCROW nLastRealDocRow  = static_cast< SCROW >( nLastRealDocRowS );
    1008             : 
    1009             :                 // first visible column (nX1-1 is first processed document column)
    1010         274 :                 SCCOL nFirstDocCol = (nCol1 > 0) ? ::std::max< SCCOL >( nFirstRealDocCol, nCol1 - 1 ) : nFirstRealDocCol;
    1011         274 :                 sal_uInt16 nFirstCellInfoX = static_cast< sal_uInt16 >( nFirstDocCol + 1 );
    1012         274 :                 nFirstCol = static_cast< size_t >( nFirstCellInfoX - nCol1 );
    1013             : 
    1014             :                 // last visible column (nX2+1 is last processed document column)
    1015         274 :                 SCCOL nLastDocCol = (nCol2 < MAXCOL) ? ::std::min< SCCOL >( nLastRealDocCol, nCol2 + 1 ) : nLastRealDocCol;
    1016         274 :                 sal_uInt16 nLastCellInfoX = static_cast< sal_uInt16 >( nLastDocCol + 1 );
    1017         274 :                 size_t nLastCol = static_cast< size_t >( nLastCellInfoX - nCol1 );
    1018             : 
    1019             :                 // first visible row
    1020         274 :                 sal_uInt16 nFirstCellInfoY = nCellInfoY;
    1021         548 :                 while( ((nFirstCellInfoY > 1) && (pRowInfo[ nFirstCellInfoY - 1 ].nRowNo >= nFirstRealDocRow)) ||
    1022         263 :                        ((nFirstCellInfoY == 1) && (static_cast< SCROW >( nRow1 - 1 ) >= nFirstRealDocRow)) )
    1023           0 :                     --nFirstCellInfoY;
    1024         274 :                 SCROW nFirstDocRow = (nFirstCellInfoY > 0) ? pRowInfo[ nFirstCellInfoY ].nRowNo : static_cast< SCROW >( nRow1 - 1 );
    1025         274 :                 nFirstRow = static_cast< size_t >( nFirstCellInfoY );
    1026             : 
    1027             :                 // last visible row
    1028         274 :                 sal_uInt16 nLastCellInfoY = nCellInfoY;
    1029        1926 :                 while( (sal::static_int_cast<SCSIZE>(nLastCellInfoY + 1) < nArrCount) &&
    1030         826 :                             (pRowInfo[ nLastCellInfoY + 1 ].nRowNo <= nLastRealDocRow) )
    1031         552 :                     ++nLastCellInfoY;
    1032         274 :                 SCROW nLastDocRow = (nLastCellInfoY > 0) ? pRowInfo[ nLastCellInfoY ].nRowNo : static_cast< SCROW >( nRow1 - 1 );
    1033         274 :                 size_t nLastRow = static_cast< size_t >( nLastCellInfoY );
    1034             : 
    1035             :                 // insert merged range
    1036         274 :                 rArray.SetMergedRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
    1037             : 
    1038             :                 // *** find additional size not included in svx::frame::Array ***
    1039             : 
    1040             :                 // additional space before first column
    1041         274 :                 if( nFirstCol == 0 )
    1042             :                 {
    1043           0 :                     long nSize = 0;
    1044           0 :                     for( SCCOL nDocCol = nFirstRealDocCol; nDocCol < nFirstDocCol; ++nDocCol )
    1045           0 :                         nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * fColScale ), 1L );
    1046           0 :                     rArray.SetAddMergedLeftSize( nCol, nRow, nSize );
    1047             :                 }
    1048             :                 // additional space after last column
    1049         274 :                 if( nLastCol + 1 == nColCount )
    1050             :                 {
    1051           7 :                     long nSize = 0;
    1052          14 :                     for( SCCOL nDocCol = nLastDocCol + 1; nDocCol <= nLastRealDocCol; ++nDocCol )
    1053           7 :                         nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * fColScale ), 1L );
    1054           7 :                     rArray.SetAddMergedRightSize( nCol, nRow, nSize );
    1055             :                 }
    1056             :                 // additional space above first row
    1057         274 :                 if( nFirstRow == 0 )
    1058             :                 {
    1059           2 :                     long nSize = 0;
    1060           2 :                     for( SCROW nDocRow = nFirstRealDocRow; nDocRow < nFirstDocRow; ++nDocRow )
    1061           0 :                         nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * fRowScale ), 1L );
    1062           2 :                     rArray.SetAddMergedTopSize( nCol, nRow, nSize );
    1063             :                 }
    1064             :                 // additional space beyond last row
    1065         274 :                 if( nLastRow + 1 == nRowCount )
    1066             :                 {
    1067           0 :                     long nSize = 0;
    1068           0 :                     for( SCROW nDocRow = nLastDocRow + 1; nDocRow <= nLastRealDocRow; ++nDocRow )
    1069           0 :                         nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * fRowScale ), 1L );
    1070           0 :                     rArray.SetAddMergedBottomSize( nCol, nRow, nSize );
    1071             :                 }
    1072             : 
    1073             :                 // *** use line attributes from real origin cell ***
    1074             : 
    1075         274 :                 if( (nFirstRealDocCol != nCurrDocCol) || (nFirstRealDocRow != nCurrDocRow) )
    1076             :                 {
    1077           2 :                     if( const ScPatternAttr* pPattern = GetPattern( nFirstRealDocCol, nFirstRealDocRow, nTab ) )
    1078             :                     {
    1079           2 :                         const SfxItemSet* pCond = GetCondResult( nFirstRealDocCol, nFirstRealDocRow, nTab );
    1080           2 :                         pBox = static_cast< const SvxBoxItem* >( &pPattern->GetItem( ATTR_BORDER, pCond ) );
    1081           2 :                         pTLBR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_TLBR, pCond ) );
    1082           2 :                         pBLTR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_BLTR, pCond ) );
    1083             :                     }
    1084             :                     else
    1085             :                     {
    1086           0 :                         pBox = 0;
    1087           0 :                         pTLBR = pBLTR = 0;
    1088             :                     }
    1089             :                 }
    1090             :             }
    1091             : 
    1092             :             // *** borders *** ------------------------------------------------
    1093             : 
    1094     2729407 :             if( pBox )
    1095             :             {
    1096     2396897 :                 rArray.SetCellStyleLeft(   nFirstCol, nFirstRow, svx::frame::Style( pBox->GetLeft(),   fColScale ) );
    1097     2396897 :                 rArray.SetCellStyleRight(  nFirstCol, nFirstRow, svx::frame::Style( pBox->GetRight(),  fColScale ) );
    1098     2396897 :                 rArray.SetCellStyleTop(    nFirstCol, nFirstRow, svx::frame::Style( pBox->GetTop(),    fRowScale ) );
    1099     2396897 :                 rArray.SetCellStyleBottom( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetBottom(), fRowScale ) );
    1100             :             }
    1101             : 
    1102     2729407 :             if( pTLBR )
    1103     2396897 :                 rArray.SetCellStyleTLBR( nFirstCol, nFirstRow, svx::frame::Style( pTLBR->GetLine(), fRowScale ) );
    1104     2729407 :             if( pBLTR )
    1105     2396897 :                 rArray.SetCellStyleBLTR( nFirstCol, nFirstRow, svx::frame::Style( pBLTR->GetLine(), fRowScale ) );
    1106             :         }
    1107             :     }
    1108             : 
    1109             :     /*  Mirror the entire frame array.
    1110             :         1st param = Mirror the vertical double line styles as well.
    1111             :         2nd param = Do not swap diagonal lines.
    1112             :      */
    1113       10483 :     if( bLayoutRTL )
    1114           2 :         rArray.MirrorSelfX( true, false );
    1115       10483 : }
    1116             : 
    1117       10483 : ScTableInfo::ScTableInfo()
    1118       10483 :     : mpRowInfo(new RowInfo[ROWINFO_MAX])
    1119             :     , mnArrCount(0)
    1120       20966 :     , mbPageMode(false)
    1121             : {
    1122       10483 :     memset(mpRowInfo, 0, ROWINFO_MAX*sizeof(RowInfo));
    1123       10483 : }
    1124             : 
    1125       20966 : ScTableInfo::~ScTableInfo()
    1126             : {
    1127    10745075 :     for( sal_uInt16 nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx )
    1128    10734592 :         delete [] mpRowInfo[ nIdx ].pCellInfo;
    1129       10483 :     delete [] mpRowInfo;
    1130       10639 : }
    1131             : 
    1132             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11