LCOV - code coverage report
Current view: top level - sc/source/core/data - fillinfo.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 451 586 77.0 %
Date: 2014-11-03 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             : //  aehnlich wie in output.cxx
      56             : 
      57        3933 : 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        3933 :     CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
      63             : 
      64        3933 :     rStartX = nX;
      65        3933 :     rStartY = nY;
      66        3933 :     bool bHOver = pInfo->bHOverlapped;
      67        3933 :     bool bVOver = pInfo->bVOverlapped;
      68             :     SCCOL nLastCol;
      69             :     SCROW nLastRow;
      70             : 
      71        9573 :     while (bHOver)              // nY konstant
      72             :     {
      73        1707 :         --rStartX;
      74        1707 :         if (rStartX >= (SCsCOL) nX1 && !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol))
      75             :         {
      76        1707 :             bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
      77        1707 :             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       11341 :     while (bVOver)
      89             :     {
      90        3475 :         --rStartY;
      91             : 
      92        3475 :         if (nArrY>0)
      93        3469 :             --nArrY;                        // lokale Kopie !
      94             : 
      95       13884 :         if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
      96        6918 :             !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
      97       10371 :             !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
      98        3437 :             (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
      99             :         {
     100        3437 :             bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
     101             :         }
     102             :         else
     103             :         {
     104             :             sal_uInt16 nOverlap = static_cast<const ScMergeFlagAttr*>(pDoc->GetAttr(
     105          38 :                                 rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
     106          38 :             bVOver = ((nOverlap & SC_MF_VER) != 0);
     107             :         }
     108             :     }
     109             : 
     110             :     const ScMergeAttr* pMerge;
     111       15704 :     if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
     112        7810 :         !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
     113       11727 :         !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
     114        3889 :         (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
     115             :     {
     116        3889 :         pMerge = static_cast<const ScMergeAttr*>( &pRowInfo[nArrY].pCellInfo[rStartX+1].pPatternAttr->
     117        3889 :                                         GetItem(ATTR_MERGE));
     118             :     }
     119             :     else
     120          44 :         pMerge = static_cast<const ScMergeAttr*>( pDoc->GetAttr(rStartX,rStartY,nTab,ATTR_MERGE) );
     121             : 
     122        3933 :     rEndX = rStartX + pMerge->GetColMerge() - 1;
     123        3933 :     rEndY = rStartY + pMerge->GetRowMerge() - 1;
     124        3933 : }
     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      798769 :     bool isHidden(size_t nRow)
     139             :     {
     140      798769 :         SCROW nThisRow = static_cast<SCROW>(nRow);
     141      798769 :         if (nThisRow > mnHiddenEndRow)
     142      124316 :             mbHiddenRow = mrDoc.RowHidden(nThisRow, mnTab, NULL, &mnHiddenEndRow);
     143      798769 :         return mbHiddenRow;
     144             :     }
     145             : 
     146      797873 :     void alignArray(size_t nRow)
     147             :     {
     148     2947533 :         while (mpRowInfo[mrArrY].nRowNo < static_cast<SCROW>(nRow))
     149     1351787 :             ++mrArrY;
     150      797873 :     }
     151             : 
     152      797873 :     void setInfo(size_t nRow, const ScRefCellValue& rCell)
     153             :     {
     154      797873 :         alignArray(nRow);
     155             : 
     156      797873 :         RowInfo* pThisRowInfo = &mpRowInfo[mrArrY];
     157      797873 :         CellInfo* pInfo = &pThisRowInfo->pCellInfo[mnArrX];
     158      797873 :         pInfo->maCell = rCell;
     159      797873 :         pThisRowInfo->bEmptyText = false;
     160      797873 :         pInfo->bEmptyCellText = false;
     161      797873 :         ++mrArrY;
     162      797873 :     }
     163             : 
     164             : public:
     165      194482 :     RowInfoFiller(ScDocument& rDoc, SCTAB nTab, RowInfo* pRowInfo, SCCOL nArrX, SCSIZE& rArrY) :
     166             :         mrDoc(rDoc), mnTab(nTab), mpRowInfo(pRowInfo), mnArrX(nArrX), mrArrY(rArrY),
     167      194482 :         mnHiddenEndRow(-1), mbHiddenRow(false) {}
     168             : 
     169      605914 :     void operator() (size_t nRow, double fVal)
     170             :     {
     171      605914 :         if (!isHidden(nRow))
     172      605504 :             setInfo(nRow, ScRefCellValue(fVal));
     173      605914 :     }
     174             : 
     175      182820 :     void operator() (size_t nRow, const svl::SharedString& rStr)
     176             :     {
     177      182820 :         if (!isHidden(nRow))
     178      182350 :             setInfo(nRow, ScRefCellValue(&rStr));
     179      182820 :     }
     180             : 
     181        1600 :     void operator() (size_t nRow, const EditTextObject* p)
     182             :     {
     183        1600 :         if (!isHidden(nRow))
     184        1600 :             setInfo(nRow, ScRefCellValue(p));
     185        1600 :     }
     186             : 
     187        8435 :     void operator() (size_t nRow, const ScFormulaCell* p)
     188             :     {
     189        8435 :         if (!isHidden(nRow))
     190        8419 :             setInfo(nRow, ScRefCellValue(const_cast<ScFormulaCell*>(p)));
     191        8435 :     }
     192             : };
     193             : 
     194             : }
     195             : 
     196       16360 : 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       16360 :     bool bLayoutRTL = IsLayoutRTL( nTab );
     204             : 
     205       16360 :     ScDocumentPool* pPool = xPoolHelper->GetDocPool();
     206       16360 :     ScStyleSheetPool* pStlPool = xPoolHelper->GetStylePool();
     207             : 
     208       16360 :     RowInfo* pRowInfo = rTabInfo.mpRowInfo;
     209             : 
     210             :     const SvxBrushItem* pDefBackground =
     211       16360 :             static_cast<const SvxBrushItem*>( &pPool->GetDefaultItem( ATTR_BACKGROUND ) );
     212             :     const ScMergeAttr* pDefMerge =
     213       16360 :             static_cast<const ScMergeAttr*>( &pPool->GetDefaultItem( ATTR_MERGE ) );
     214             :     const SvxShadowItem* pDefShadow =
     215       16360 :             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       16360 :     bool bAnyMerged = false;
     225       16360 :     bool bAnyShadow = false;
     226       16360 :     bool bAnyCondition = false;
     227       16360 :     bool bAnyPreview = false;
     228             : 
     229       16360 :     bool bTabProtect = IsTabProtected(nTab);
     230             : 
     231             :                                                 // fuer Blockmarken von zusammengefassten Zellen mit
     232             :                                                 // versteckter erster Zeile / Spalte
     233       16360 :     bool bPaintMarks = false;
     234       16360 :     bool bSkipMarks = false;
     235       16360 :     SCCOL nBlockStartX = 0, nBlockEndX = 0;
     236       16360 :     SCROW nBlockEndY = 0, nBlockStartY = 0;
     237       16360 :     if (pMarkData && pMarkData->IsMarked())
     238             :     {
     239         116 :         ScRange aTmpRange;
     240         116 :         pMarkData->GetMarkArea(aTmpRange);
     241         116 :         if ( nTab >= aTmpRange.aStart.Tab() && nTab <= aTmpRange.aEnd.Tab() )
     242             :         {
     243         116 :             nBlockStartX = aTmpRange.aStart.Col();
     244         116 :             nBlockStartY = aTmpRange.aStart.Row();
     245         116 :             nBlockEndX = aTmpRange.aEnd.Col();
     246         116 :             nBlockEndY = aTmpRange.aEnd.Row();
     247         116 :             ExtendHidden( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY, nTab );   //? noetig ?
     248         116 :             if (pMarkData->IsMarkNegative())
     249           0 :                 bSkipMarks = true;
     250             :             else
     251         116 :                 bPaintMarks = true;
     252             :         }
     253             :     }
     254             : 
     255             :     //  zuerst nur die Eintraege fuer die ganze Spalte
     256             : 
     257       16360 :     nArrRow=0;
     258       16360 :     SCROW nYExtra = nRow2+1;
     259       16360 :     sal_uInt16 nDocHeight = ScGlobal::nStdRowHeight;
     260       16360 :     SCROW nDocHeightEndRow = -1;
     261      447835 :     for (nSignedY=((SCsROW)nRow1)-1; nSignedY<=(SCsROW)nYExtra; nSignedY++)
     262             :     {
     263      431475 :         if (nSignedY >= 0)
     264      416324 :             nY = (SCROW) nSignedY;
     265             :         else
     266       15151 :             nY = MAXROW+1;          // ungueltig
     267             : 
     268      431475 :         if (nY > nDocHeightEndRow)
     269             :         {
     270       38940 :             if (ValidRow(nY))
     271       23789 :                 nDocHeight = GetRowHeight( nY, nTab, NULL, &nDocHeightEndRow );
     272             :             else
     273       15151 :                 nDocHeight = ScGlobal::nStdRowHeight;
     274             :         }
     275             : 
     276      431475 :         if ( nArrRow==0 || nDocHeight || nY > MAXROW )
     277             :         {
     278      430880 :             RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     279      430880 :             pThisRowInfo->pCellInfo = NULL;                 // wird unten belegt
     280             : 
     281      430880 :             sal_uInt16 nHeight = (sal_uInt16) ( nDocHeight * fRowScale );
     282      430880 :             if (!nHeight)
     283           0 :                 nHeight = 1;
     284             : 
     285      430880 :             pThisRowInfo->nRowNo        = nY;               //! Fall < 0 ?
     286      430880 :             pThisRowInfo->nHeight       = nHeight;
     287      430880 :             pThisRowInfo->bEmptyBack    = true;
     288      430880 :             pThisRowInfo->bEmptyText    = true;
     289      430880 :             pThisRowInfo->bChanged      = true;
     290      430880 :             pThisRowInfo->bAutoFilter   = false;
     291      430880 :             pThisRowInfo->bPivotButton  = false;
     292      430880 :             pThisRowInfo->nRotMaxCol    = SC_ROTMAX_NONE;
     293             : 
     294      430880 :             ++nArrRow;
     295      430880 :             if (nArrRow >= ROWINFO_MAX)
     296             :             {
     297             :                 OSL_FAIL("FillInfo: Range too big" );
     298           0 :                 nYExtra = nSignedY;                                 // Ende
     299           0 :                 nRow2 = nYExtra - 1;                                  // Bereich anpassen
     300      430880 :             }
     301             :         }
     302             :         else
     303         595 :             if (nSignedY==(SCsROW) nYExtra)                         // zusaetzliche Zeile verdeckt ?
     304           0 :                 ++nYExtra;
     305             :     }
     306       16360 :     nArrCount = nArrRow;                                      // incl. Dummys
     307             : 
     308             :     //  rotierter Text...
     309             : 
     310             :     //  Attribut im Dokument ueberhaupt verwendet?
     311       16360 :     bool bAnyItem = false;
     312       16360 :     sal_uInt32 nRotCount = pPool->GetItemCount2( ATTR_ROTATE_VALUE );
     313       16360 :     for (sal_uInt32 nItem=0; nItem<nRotCount; nItem++)
     314       16360 :         if (pPool->GetItem2( ATTR_ROTATE_VALUE, nItem ))
     315             :         {
     316       16360 :             bAnyItem = true;
     317       16360 :             break;
     318             :         }
     319             : 
     320       16360 :     SCCOL nRotMax = nCol2;
     321       32720 :     if ( bAnyItem && HasAttrib( 0,nRow1,nTab, MAXCOL,nRow2+1,nTab,
     322       16360 :                                 HASATTR_ROTATE | HASATTR_CONDITIONAL ) )
     323             :     {
     324             :         //! Conditionals auch bei HASATTR_ROTATE abfragen ????
     325             : 
     326             :         OSL_ENSURE( nArrCount>2, "nArrCount too small" );
     327         583 :         FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-1, nCol1, nCol2 );
     328             :         //  FindMaxRotCol setzt nRotMaxCol
     329             : 
     330       11361 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     331       10778 :             if (pRowInfo[nArrRow].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nArrRow].nRotMaxCol > nRotMax)
     332           0 :                 nRotMax = pRowInfo[nArrRow].nRotMaxCol;
     333             :     }
     334             : 
     335             :     //  Zell-Infos erst nach dem Test auf gedrehte allozieren
     336             :     //  bis nRotMax wegen nRotateDir Flag
     337             : 
     338      447240 :     for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     339             :     {
     340      430880 :         RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     341      430880 :         nY = pThisRowInfo->nRowNo;
     342      430880 :         pThisRowInfo->pCellInfo = new CellInfo[ nRotMax+1+2 ];  // vom Aufrufer zu loeschen !
     343             : 
     344     6048045 :         for (nArrCol=0; nArrCol<=nRotMax+2; nArrCol++)                // Zell-Infos vorbelegen
     345             :         {
     346     5617165 :             if (nArrCol>0)
     347     5186285 :                 nX = nArrCol-1;
     348             :             else
     349      430880 :                 nX = MAXCOL+1;      // ungueltig
     350             : 
     351     5617165 :             CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     352     5617165 :             pInfo->bEmptyCellText = true;
     353     5617165 :             pInfo->maCell.clear();
     354     5617165 :             if (bPaintMarks)
     355      151199 :                 pInfo->bMarked = ( nX >= nBlockStartX && nX <= nBlockEndX
     356       83936 :                                 && nY >= nBlockStartY && nY <= nBlockEndY );
     357             :             else
     358     5539550 :                 pInfo->bMarked = false;
     359     5617165 :             pInfo->nWidth = 0;
     360             : 
     361     5617165 :             pInfo->nClipMark    = SC_CLIPMARK_NONE;
     362     5617165 :             pInfo->bMerged      = false;
     363     5617165 :             pInfo->bHOverlapped = false;
     364     5617165 :             pInfo->bVOverlapped = false;
     365     5617165 :             pInfo->bAutoFilter  = false;
     366     5617165 :             pInfo->bPivotButton  = false;
     367     5617165 :             pInfo->bPivotPopupButton = false;
     368     5617165 :             pInfo->bFilterActive = false;
     369     5617165 :             pInfo->nRotateDir   = SC_ROTDIR_NONE;
     370             : 
     371     5617165 :             pInfo->bPrinted     = false;                    //  view-intern
     372     5617165 :             pInfo->bHideGrid    = false;                    //  view-intern
     373     5617165 :             pInfo->bEditEngine  = false;                    //  view-intern
     374             : 
     375     5617165 :             pInfo->pBackground  = NULL;                     //! weglassen?
     376     5617165 :             pInfo->pPatternAttr = NULL;
     377     5617165 :             pInfo->pConditionSet= NULL;
     378             : 
     379     5617165 :             pInfo->pLinesAttr   = NULL;
     380     5617165 :             pInfo->mpTLBRLine   = NULL;
     381     5617165 :             pInfo->mpBLTRLine   = NULL;
     382             : 
     383     5617165 :             pInfo->pShadowAttr    = pDefShadow;
     384     5617165 :             pInfo->pHShadowOrigin = NULL;
     385     5617165 :             pInfo->pVShadowOrigin = NULL;
     386             :         }
     387             :     }
     388             : 
     389       16360 :     for (nArrCol=nCol2+3; nArrCol<=nRotMax+2; nArrCol++)            // restliche Breiten eintragen
     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       16360 :     ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
     406       16360 :     if(pCondFormList)
     407       16360 :         pCondFormList->startRendering();
     408             : 
     409      228802 :     for (nArrCol=0; nArrCol<=nCol2+2; nArrCol++)                    // links & rechts + 1
     410             :     {
     411      212442 :         nX = (nArrCol>0) ? nArrCol-1 : MAXCOL+1;                    // negativ -> ungueltig
     412             : 
     413      212442 :         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      196080 :             if (!ColHidden(nX, nTab))
     420             :             {
     421      194482 :                 sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * fColScale);
     422      194482 :                 if (!nThisWidth)
     423           0 :                     nThisWidth = 1;
     424             : 
     425      194482 :                 pRowInfo[0].pCellInfo[nArrCol].nWidth = nThisWidth;           //! dies sollte reichen
     426             : 
     427      194482 :                 ScColumn* pThisCol = &maTabs[nTab]->aCol[nX];                   // Spalten-Daten
     428             : 
     429      194482 :                 nArrRow = 1;
     430             :                 // Iterate between rows nY1 and nY2 and pick up non-empty
     431             :                 // cells that are not hidden.
     432      194482 :                 RowInfoFiller aFunc(*this, nTab, pRowInfo, nArrCol, nArrRow);
     433             :                 sc::ParseAllNonEmpty(
     434      194482 :                     pThisCol->maCells.begin(), pThisCol->maCells, nRow1, nRow2, aFunc);
     435             : 
     436      194482 :                 if (nX+1 >= nCol1)                                // Attribute/Blockmarken ab nX1-1
     437             :                 {
     438      191136 :                     ScAttrArray* pThisAttrArr = pThisCol->pAttrArray;       // Attribute
     439             : 
     440      191136 :                     nArrRow = 0;
     441             :                     const ScPatternAttr* pPattern;
     442      191136 :                     SCROW nCurRow=nRow1;                  // einzelne Zeile
     443      191136 :                     if (nCurRow>0)
     444       15831 :                         --nCurRow;                      // oben 1 mehr
     445             :                     else
     446      175305 :                         nArrRow = 1;
     447      191136 :                     nThisRow=nCurRow;                   // Ende des Bereichs
     448             :                     SCSIZE  nIndex;
     449      191136 :                     (void) pThisAttrArr->Search( nCurRow, nIndex );
     450             : 
     451      349119 :                     do
     452             :                     {
     453      349119 :                         nThisRow=pThisAttrArr->pData[nIndex].nRow;              // Ende des Bereichs
     454      349119 :                         pPattern=pThisAttrArr->pData[nIndex].pPattern;
     455             : 
     456             :                         const SvxBrushItem* pBackground = static_cast<const SvxBrushItem*>(
     457      349119 :                                                         &pPattern->GetItem(ATTR_BACKGROUND));
     458             :                         const SvxBoxItem* pLinesAttr = static_cast<const SvxBoxItem*>(
     459      349119 :                                                         &pPattern->GetItem(ATTR_BORDER));
     460             : 
     461             :                         const SvxLineItem* pTLBRLine = static_cast< const SvxLineItem* >(
     462      349119 :                             &pPattern->GetItem( ATTR_BORDER_TLBR ) );
     463             :                         const SvxLineItem* pBLTRLine = static_cast< const SvxLineItem* >(
     464      349119 :                             &pPattern->GetItem( ATTR_BORDER_BLTR ) );
     465             : 
     466             :                         const SvxShadowItem* pShadowAttr = static_cast<const SvxShadowItem*>(
     467      349119 :                                                         &pPattern->GetItem(ATTR_SHADOW));
     468      349119 :                         if (pShadowAttr != pDefShadow)
     469        1786 :                             bAnyShadow = true;
     470             : 
     471             :                         const ScMergeAttr* pMergeAttr = static_cast<const ScMergeAttr*>(
     472      349119 :                                                 &pPattern->GetItem(ATTR_MERGE));
     473      349119 :                         bool bMerged = ( pMergeAttr != pDefMerge && *pMergeAttr != *pDefMerge );
     474      349119 :                         sal_uInt16 nOverlap = static_cast<const ScMergeFlagAttr*>( &pPattern->GetItemSet().
     475      349119 :                                                         Get(ATTR_MERGE_FLAG))->GetValue();
     476      349119 :                         bool bHOverlapped = ((nOverlap & SC_MF_HOR) != 0);
     477      349119 :                         bool bVOverlapped = ((nOverlap & SC_MF_VER) != 0);
     478      349119 :                         bool bAutoFilter  = ((nOverlap & SC_MF_AUTO) != 0);
     479      349119 :                         bool bPivotButton  = ((nOverlap & SC_MF_BUTTON) != 0);
     480      349119 :                         bool bScenario    = ((nOverlap & SC_MF_SCENARIO) != 0);
     481      349119 :                         bool bPivotPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0);
     482      349119 :                         bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0);
     483      349119 :                         if (bMerged||bHOverlapped||bVOverlapped)
     484        3319 :                             bAnyMerged = true;                              // intern
     485             : 
     486             :                         bool bHidden, bHideFormula;
     487      349119 :                         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      349119 :                             bHidden = bHideFormula = false;
     496             : 
     497      349119 :                         const std::vector<sal_uInt32>& rCondFormats = static_cast<const ScCondFormatItem&>(pPattern->GetItem(ATTR_CONDITIONAL)).GetCondFormatData();
     498      349119 :                         bool bContainsCondFormat = !rCondFormats.empty();
     499             : 
     500     4891059 :                         do
     501             :                         {
     502     4891059 :                             SCROW nLastHiddenRow = -1;
     503     4891059 :                             bool bRowHidden = RowHidden(nCurRow, nTab, NULL, &nLastHiddenRow);
     504     4891059 :                             if ( nArrRow==0 || !bRowHidden )
     505             :                             {
     506     4888206 :                                 if ( GetPreviewCellStyle( nX, nCurRow, nTab  ) != NULL )
     507           0 :                                     bAnyPreview = true;
     508     4888206 :                                 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     509     4888206 :                                 if (pBackground != pDefBackground)          // Spalten-HG == Standard ?
     510      531927 :                                     pThisRowInfo->bEmptyBack = false;
     511     4888206 :                                 if (bContainsCondFormat)
     512       12820 :                                     pThisRowInfo->bEmptyBack = false;
     513     4888206 :                                 if (bAutoFilter)
     514         261 :                                     pThisRowInfo->bAutoFilter = true;
     515     4888206 :                                 if (bPivotButton || bPivotPopupButton)
     516         914 :                                     pThisRowInfo->bPivotButton = true;
     517             : 
     518     4888206 :                                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     519     4888206 :                                 pInfo->pBackground  = pBackground;
     520     4888206 :                                 pInfo->pPatternAttr = pPattern;
     521     4888206 :                                 pInfo->bMerged      = bMerged;
     522     4888206 :                                 pInfo->bHOverlapped = bHOverlapped;
     523     4888206 :                                 pInfo->bVOverlapped = bVOverlapped;
     524     4888206 :                                 pInfo->bAutoFilter  = bAutoFilter;
     525     4888206 :                                 pInfo->bPivotButton  = bPivotButton;
     526     4888206 :                                 pInfo->bPivotPopupButton = bPivotPopupButton;
     527     4888206 :                                 pInfo->bFilterActive = bFilterActive;
     528     4888206 :                                 pInfo->pLinesAttr   = pLinesAttr;
     529     4888206 :                                 pInfo->mpTLBRLine   = pTLBRLine;
     530     4888206 :                                 pInfo->mpBLTRLine   = pBLTRLine;
     531     4888206 :                                 pInfo->pShadowAttr  = pShadowAttr;
     532             :                                 //  nWidth wird nicht mehr einzeln gesetzt
     533             : 
     534     4888206 :                                 if (bScenario)
     535             :                                 {
     536           0 :                                     pInfo->pBackground = ScGlobal::GetButtonBrushItem();
     537           0 :                                     pThisRowInfo->bEmptyBack = false;
     538             :                                 }
     539             : 
     540     4888206 :                                 if ( bContainsCondFormat )
     541             :                                 {
     542       12820 :                                     bool bFound = false;
     543      130650 :                                     for(std::vector<sal_uInt32>::const_iterator itr = rCondFormats.begin();
     544      130650 :                                             itr != rCondFormats.end() && !bFound; ++itr)
     545             :                                     {
     546       30730 :                                         ScConditionalFormat* pCondForm = pCondFormList->GetFormat(*itr);
     547       30730 :                                         if(!pCondForm)
     548           0 :                                             continue;
     549             : 
     550             :                                         ScCondFormatData aData = pCondForm->GetData(
     551       30730 :                                             pInfo->maCell, ScAddress(nX, nCurRow, nTab));
     552       30730 :                                         if (!aData.aStyleName.isEmpty())
     553             :                                         {
     554             :                                             SfxStyleSheetBase* pStyleSheet =
     555         160 :                                                 pStlPool->Find( aData.aStyleName, SFX_STYLE_FAMILY_PARA );
     556         160 :                                             if ( pStyleSheet )
     557             :                                             {
     558             :                                                 //! Style-Sets cachen !!!
     559         160 :                                                 pInfo->pConditionSet = &pStyleSheet->GetItemSet();
     560         160 :                                                 bAnyCondition = true;
     561             : 
     562             :                                                 // we need to check already here for protected cells
     563             :                                                 const SfxPoolItem* pItem;
     564         160 :                                                 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         160 :                                                 bFound = true;
     572             : 
     573             :                                             }
     574             :                                             // if style is not there, treat like no condition
     575             :                                         }
     576       30730 :                                         if(aData.pColorScale)
     577             :                                         {
     578           0 :                                             pInfo->pColorScale.reset(aData.pColorScale);
     579           0 :                                             bFound = true;
     580             :                                         }
     581             : 
     582       30730 :                                         if(aData.pDataBar)
     583             :                                         {
     584           0 :                                             pInfo->pDataBar.reset(aData.pDataBar);
     585           0 :                                             bFound = true;
     586             :                                         }
     587       30730 :                                         if(aData.pIconSet)
     588             :                                         {
     589           0 :                                             pInfo->pIconSet.reset(aData.pIconSet);
     590           0 :                                             bFound = true;
     591             :                                         }
     592       30730 :                                     }
     593             :                                 }
     594             : 
     595     4888206 :                                 if (bHidden || (bFormulaMode && bHideFormula && pInfo->maCell.meType == CELLTYPE_FORMULA))
     596           0 :                                     pInfo->bEmptyCellText = true;
     597             : 
     598     4888206 :                                 ++nArrRow;
     599             :                             }
     600        2853 :                             else if (bRowHidden && nLastHiddenRow >= 0)
     601             :                             {
     602        2853 :                                 nCurRow = nLastHiddenRow;
     603        2853 :                                 if (nCurRow > nThisRow)
     604          93 :                                     nCurRow = nThisRow;
     605             :                             }
     606     4891059 :                             ++nCurRow;
     607             :                         }
     608     4712737 :                         while (nCurRow <= nThisRow && nCurRow <= nYExtra);
     609      349119 :                         ++nIndex;
     610             :                     }
     611      592571 :                     while ( nIndex < pThisAttrArr->nCount && nThisRow < nYExtra );
     612             : 
     613      191136 :                     if (pMarkData && pMarkData->IsMultiMarked())
     614             :                     {
     615             :                         //  Blockmarken
     616         446 :                         const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nX;
     617         446 :                         nArrRow = 1;
     618         446 :                         nCurRow = nRow1;                                      // einzelne Zeile
     619         446 :                         nThisRow = nRow1;                                     // Ende des Bereichs
     620             : 
     621         446 :                         if ( pThisMarkArr->Search( nRow1, nIndex ) )
     622             :                         {
     623             :                             bool bThisMarked;
     624         530 :                             do
     625             :                             {
     626         530 :                                 nThisRow=pThisMarkArr->pData[nIndex].nRow;      // Ende des Bereichs
     627         530 :                                 bThisMarked=pThisMarkArr->pData[nIndex].bMarked;
     628             : 
     629        4052 :                                 do
     630             :                                 {
     631        4052 :                                     if ( !RowHidden( nCurRow,nTab ) )
     632             :                                     {
     633        4052 :                                         if ( bThisMarked )
     634             :                                         {
     635           0 :                                             bool bSkip = bSkipMarks &&
     636           0 :                                                         nX      >= nBlockStartX &&
     637           0 :                                                         nX      <= nBlockEndX   &&
     638        1516 :                                                         nCurRow >= nBlockStartY &&
     639        1516 :                                                         nCurRow <= nBlockEndY;
     640        1516 :                                             if (!bSkip)
     641             :                                             {
     642        1516 :                                                 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     643        1516 :                                                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     644        1516 :                                                 pInfo->bMarked = true;
     645             :                                             }
     646             :                                         }
     647        4052 :                                         ++nArrRow;
     648             :                                     }
     649        4052 :                                     ++nCurRow;
     650             :                                 }
     651        3688 :                                 while (nCurRow <= nThisRow && nCurRow <= nRow2);
     652         530 :                                 ++nIndex;
     653             :                             }
     654         910 :                             while ( nIndex < pThisMarkArr->nCount && nThisRow < nRow2 );
     655             :                         }
     656             :                     }
     657             :                 }
     658             :                 else                                    // vordere Spalten
     659             :                 {
     660       77934 :                     for (nArrRow=1; nArrRow+1<nArrCount; nArrRow++)
     661             :                     {
     662       74588 :                         RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     663       74588 :                         CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     664             : 
     665       74588 :                         pInfo->nWidth       = nThisWidth;           //! oder nur 0 abfragen ??
     666             :                     }
     667             :                 }
     668             :             }
     669             :         }
     670             :         else
     671       16362 :             pRowInfo[0].pCellInfo[nArrCol].nWidth = STD_COL_WIDTH;
     672             :         // STD_COL_WIDTH ganz links und rechts wird fuer DrawExtraShadow gebraucht
     673             :     }
     674             : 
     675       16360 :     if(pCondFormList)
     676       16360 :         pCondFormList->endRendering();
     677             : 
     678             :     //  bedingte Formatierung auswerten
     679       16360 :     ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
     680             :     // favour preview over condition
     681       16360 :     if (bAnyCondition || bAnyPreview)
     682             :     {
     683        2436 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     684             :         {
     685       34720 :             for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)                  // links und rechts einer mehr
     686             :             {
     687       32368 :                 CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
     688       32368 :                 SCCOL nCol = (nArrCol>0) ? nArrCol-1 : MAXCOL+1;
     689       32368 :                 ScPatternAttr* pModifiedPatt = NULL;
     690             : 
     691       32368 :                 if ( ValidCol(nCol) && pRowInfo[nArrRow].nRowNo <= MAXROW )
     692             :                 {
     693       28944 :                     if ( ScStyleSheet* pPreviewStyle = GetPreviewCellStyle( nCol, pRowInfo[nArrRow].nRowNo, nTab ) )
     694             :                     {
     695           0 :                         aAltPatterns.push_back( new ScPatternAttr( *pInfo->pPatternAttr ) );
     696           0 :                         pModifiedPatt = &aAltPatterns.back();
     697           0 :                         pModifiedPatt->SetStyleSheet( pPreviewStyle );
     698             :                     }
     699             :                 }
     700             :                 // favour preview over condition
     701       32368 :                 const SfxItemSet* pCondSet = pModifiedPatt ? &pModifiedPatt->GetItemSet() : pInfo->pConditionSet;
     702             : 
     703       32368 :                 if (pCondSet)
     704             :                 {
     705             :                     const SfxPoolItem* pItem;
     706             : 
     707             :                             //  Hintergrund
     708         160 :                     if ( pCondSet->GetItemState( ATTR_BACKGROUND, true, &pItem ) == SfxItemState::SET )
     709             :                     {
     710           0 :                         pInfo->pBackground = static_cast<const SvxBrushItem*>(pItem);
     711           0 :                         pRowInfo[nArrRow].bEmptyBack = false;
     712             :                     }
     713             : 
     714             :                             //  Umrandung
     715         160 :                     if ( pCondSet->GetItemState( ATTR_BORDER, true, &pItem ) == SfxItemState::SET )
     716           0 :                         pInfo->pLinesAttr = static_cast<const SvxBoxItem*>(pItem);
     717             : 
     718         160 :                     if ( pCondSet->GetItemState( ATTR_BORDER_TLBR, true, &pItem ) == SfxItemState::SET )
     719           0 :                         pInfo->mpTLBRLine = static_cast< const SvxLineItem* >( pItem );
     720         160 :                     if ( pCondSet->GetItemState( ATTR_BORDER_BLTR, true, &pItem ) == SfxItemState::SET )
     721           0 :                         pInfo->mpBLTRLine = static_cast< const SvxLineItem* >( pItem );
     722             : 
     723             :                             //  Schatten
     724         160 :                     if ( pCondSet->GetItemState( ATTR_SHADOW, true, &pItem ) == SfxItemState::SET )
     725             :                     {
     726           0 :                         pInfo->pShadowAttr = static_cast<const SvxShadowItem*>(pItem);
     727           0 :                         bAnyShadow = true;
     728             :                     }
     729             :                 }
     730       32368 :                 if( bAnyCondition && pInfo->pColorScale)
     731             :                 {
     732           0 :                     pRowInfo[nArrRow].bEmptyBack = false;
     733           0 :                     pInfo->pBackground = new SvxBrushItem(*pInfo->pColorScale, ATTR_BACKGROUND);
     734             :                 }
     735             :             }
     736             :         }
     737             :     }
     738             : 
     739             :     //  bedingte Formatierung Ende
     740             : 
     741             :                 //      Daten von zusammengefassten Zellen anpassen
     742             : 
     743       16360 :     if (bAnyMerged)
     744             :     {
     745       14562 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     746             :         {
     747       14000 :             RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
     748       14000 :             nSignedY = nArrRow ? pThisRowInfo->nRowNo : ((SCsROW)nRow1)-1;
     749             : 
     750      248448 :             for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)                  // links und rechts einer mehr
     751             :             {
     752      234448 :                 SCsCOL nSignedX = ((SCsCOL) nArrCol) - 1;
     753      234448 :                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
     754             : 
     755      234448 :                 if (pInfo->bMerged || pInfo->bHOverlapped || pInfo->bVOverlapped)
     756             :                 {
     757             :                     SCsCOL nStartX;
     758             :                     SCsROW nStartY;
     759             :                     SCsCOL nEndX;
     760             :                     SCsROW nEndY;
     761             :                     lcl_GetMergeRange( nSignedX,nSignedY, nArrRow, this,pRowInfo, nCol1,nRow1,nCol2,nRow2,nTab,
     762        3361 :                                         nStartX,nStartY, nEndX,nEndY );
     763        3361 :                     const ScPatternAttr* pStartPattern = GetPattern( nStartX,nStartY,nTab );
     764        3361 :                     const SfxItemSet* pStartCond = GetCondResult( nStartX,nStartY,nTab );
     765             :                     const SfxPoolItem* pItem;
     766             : 
     767             :                     // Hintergrund kopieren (oder in output.cxx)
     768             : 
     769        3361 :                     if ( !pStartCond || pStartCond->
     770           0 :                                     GetItemState(ATTR_BACKGROUND,true,&pItem) != SfxItemState::SET )
     771        3361 :                         pItem = &pStartPattern->GetItem(ATTR_BACKGROUND);
     772        3361 :                     pInfo->pBackground = static_cast<const SvxBrushItem*>(pItem);
     773        3361 :                     pRowInfo[nArrRow].bEmptyBack = false;
     774             : 
     775             :                     // Schatten
     776             : 
     777        3361 :                     if ( !pStartCond || pStartCond->
     778           0 :                                     GetItemState(ATTR_SHADOW,true,&pItem) != SfxItemState::SET )
     779        3361 :                         pItem = &pStartPattern->GetItem(ATTR_SHADOW);
     780        3361 :                     pInfo->pShadowAttr = static_cast<const SvxShadowItem*>(pItem);
     781        3361 :                     if (pInfo->pShadowAttr != pDefShadow)
     782           0 :                         bAnyShadow = true;
     783             : 
     784             :                     // Blockmarken - wieder mit Original-Merge-Werten
     785             : 
     786        3361 :                     bool bCellMarked = false;
     787        3361 :                     if (bPaintMarks)
     788          36 :                         bCellMarked = ( nStartX >= (SCsCOL) nBlockStartX
     789          36 :                                     && nStartX <= (SCsCOL) nBlockEndX
     790           0 :                                     && nStartY >= (SCsROW) nBlockStartY
     791          36 :                                     && nStartY <= (SCsROW) nBlockEndY );
     792        3361 :                     if (pMarkData && pMarkData->IsMultiMarked() && !bCellMarked)
     793             :                     {
     794         105 :                         const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nStartX;
     795             :                         SCSIZE nIndex;
     796         105 :                         if ( pThisMarkArr->Search( nStartY, nIndex ) )
     797           0 :                             bCellMarked=pThisMarkArr->pData[nIndex].bMarked;
     798             :                     }
     799             : 
     800        3361 :                     pInfo->bMarked = bCellMarked;
     801             :                 }
     802             :             }
     803             :         }
     804             :     }
     805             : 
     806       16360 :     if (bAnyShadow)                             // Schatten verteilen
     807             :     {
     808        7633 :         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
     809             :         {
     810        7182 :             bool bTop = ( nArrRow == 0 );
     811        7182 :             bool bBottom = ( nArrRow+1 == nArrCount );
     812             : 
     813       93366 :             for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)                  // links und rechts einer mehr
     814             :             {
     815       86184 :                 bool bLeft = ( nArrCol == nCol1 );
     816       86184 :                 bool bRight = ( nArrCol == nCol2+2 );
     817             : 
     818       86184 :                 CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
     819       86184 :                 const SvxShadowItem* pThisAttr = pInfo->pShadowAttr;
     820       86184 :                 SvxShadowLocation eLoc = pThisAttr ? pThisAttr->GetLocation() : SVX_SHADOW_NONE;
     821       86184 :                 if (eLoc != SVX_SHADOW_NONE)
     822             :                 {
     823             :                     //  oder Test auf != eLoc
     824             : 
     825           0 :                     SCsCOL nDxPos = 1;
     826           0 :                     SCsCOL nDxNeg = -1;
     827             : 
     828           0 :                     while ( nArrCol+nDxPos < nCol2+2 && pRowInfo[0].pCellInfo[nArrCol+nDxPos].nWidth == 0 )
     829           0 :                         ++nDxPos;
     830           0 :                     while ( nArrCol+nDxNeg > nCol1 && pRowInfo[0].pCellInfo[nArrCol+nDxNeg].nWidth == 0 )
     831           0 :                         --nDxNeg;
     832             : 
     833           0 :                     bool bLeftDiff = !bLeft &&
     834           0 :                             pRowInfo[nArrRow].pCellInfo[nArrCol+nDxNeg].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     835           0 :                     bool bRightDiff = !bRight &&
     836           0 :                             pRowInfo[nArrRow].pCellInfo[nArrCol+nDxPos].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     837           0 :                     bool bTopDiff = !bTop &&
     838           0 :                             pRowInfo[nArrRow-1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     839           0 :                     bool bBottomDiff = !bBottom &&
     840           0 :                             pRowInfo[nArrRow+1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
     841             : 
     842           0 :                     if ( bLayoutRTL )
     843             :                     {
     844           0 :                         switch (eLoc)
     845             :                         {
     846           0 :                             case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT;  break;
     847           0 :                             case SVX_SHADOW_BOTTOMLEFT:  eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
     848           0 :                             case SVX_SHADOW_TOPRIGHT:    eLoc = SVX_SHADOW_TOPLEFT;     break;
     849           0 :                             case SVX_SHADOW_TOPLEFT:     eLoc = SVX_SHADOW_TOPRIGHT;    break;
     850             :                             default:
     851             :                             {
     852             :                                 // added to avoid warnings
     853             :                             }
     854             :                         }
     855             :                     }
     856             : 
     857           0 :                     switch (eLoc)
     858             :                     {
     859             :                         case SVX_SHADOW_BOTTOMRIGHT:
     860           0 :                             if (bBottomDiff)
     861             :                             {
     862           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     863           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
     864           0 :                                                 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     865             :                             }
     866           0 :                             if (bRightDiff)
     867             :                             {
     868           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
     869           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
     870           0 :                                                 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     871             :                             }
     872           0 :                             if (bBottomDiff && bRightDiff)
     873             :                             {
     874           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
     875           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
     876             :                             }
     877           0 :                             break;
     878             : 
     879             :                         case SVX_SHADOW_BOTTOMLEFT:
     880           0 :                             if (bBottomDiff)
     881             :                             {
     882           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     883           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
     884           0 :                                                 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     885             :                             }
     886           0 :                             if (bLeftDiff)
     887             :                             {
     888           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
     889           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
     890           0 :                                                 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     891             :                             }
     892           0 :                             if (bBottomDiff && bLeftDiff)
     893             :                             {
     894           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
     895           0 :                                 pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
     896             :                             }
     897           0 :                             break;
     898             : 
     899             :                         case SVX_SHADOW_TOPRIGHT:
     900           0 :                             if (bTopDiff)
     901             :                             {
     902           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     903           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
     904           0 :                                                 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     905             :                             }
     906           0 :                             if (bRightDiff)
     907             :                             {
     908           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
     909           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
     910           0 :                                                 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     911             :                             }
     912           0 :                             if (bTopDiff && bRightDiff)
     913             :                             {
     914           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
     915           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
     916             :                             }
     917           0 :                             break;
     918             : 
     919             :                         case SVX_SHADOW_TOPLEFT:
     920           0 :                             if (bTopDiff)
     921             :                             {
     922           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
     923           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
     924           0 :                                                 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
     925             :                             }
     926           0 :                             if (bLeftDiff)
     927             :                             {
     928           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
     929           0 :                                 pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
     930           0 :                                                 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
     931             :                             }
     932           0 :                             if (bTopDiff && bLeftDiff)
     933             :                             {
     934           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
     935           0 :                                 pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
     936             :                             }
     937           0 :                             break;
     938             : 
     939             :                         default:
     940             :                             OSL_FAIL("wrong Shadow-Enum");
     941             :                     }
     942             :                 }
     943             :             }
     944             :         }
     945             :     }
     946             : 
     947       16360 :     rTabInfo.mnArrCount = sal::static_int_cast<sal_uInt16>(nArrCount);
     948       16360 :     rTabInfo.mbPageMode = bPageMode;
     949             : 
     950             :     // *** create the frame border array ***
     951             : 
     952             :     // RowInfo structs are filled in the range [ 0 , nArrCount-1 ]
     953             :     // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ]
     954             : 
     955       16360 :     size_t nColCount = nCol2 - nCol1 + 3;
     956       16360 :     size_t nRowCount = nArrCount;
     957             : 
     958       16360 :     svx::frame::Array& rArray = rTabInfo.maArray;
     959       16360 :     rArray.Initialize( nColCount, nRowCount );
     960       16360 :     rArray.SetUseDiagDoubleClipping( false );
     961             : 
     962      447240 :     for( size_t nRow = 0; nRow < nRowCount; ++nRow )
     963             :     {
     964      430880 :         sal_uInt16 nCellInfoY = static_cast< sal_uInt16 >( nRow );
     965      430880 :         RowInfo& rThisRowInfo = pRowInfo[ nCellInfoY ];
     966             : 
     967     5962253 :         for( size_t nCol = 0; nCol < nColCount; ++nCol )
     968             :         {
     969     5531373 :             sal_uInt16 nCellInfoX = static_cast< sal_uInt16 >( nCol + nCol1 );
     970     5531373 :             const CellInfo& rInfo = rThisRowInfo.pCellInfo[ nCellInfoX ];
     971             : 
     972     5531373 :             const SvxBoxItem* pBox = rInfo.pLinesAttr;
     973     5531373 :             const SvxLineItem* pTLBR = rInfo.mpTLBRLine;
     974     5531373 :             const SvxLineItem* pBLTR = rInfo.mpBLTRLine;
     975             : 
     976     5531373 :             size_t nFirstCol = nCol;
     977     5531373 :             size_t nFirstRow = nRow;
     978             : 
     979             :             // *** merged cells *** -------------------------------------------
     980             : 
     981     5531373 :             if( !rArray.IsMerged( nCol, nRow ) && (rInfo.bMerged || rInfo.bHOverlapped || rInfo.bVOverlapped) )
     982             :             {
     983             :                 // *** insert merged range in svx::frame::Array ***
     984             : 
     985             :                 /*  #i69369# top-left cell of a merged range may be located in
     986             :                     a hidden column or row. Use lcl_GetMergeRange() to find the
     987             :                     complete merged range, then calculate dimensions and
     988             :                     document position of the visible range. */
     989             : 
     990             :                 // note: document columns are always one less than CellInfoX coords
     991             :                 // note: document rows must be looked up in RowInfo structs
     992             : 
     993             :                 // current column and row in document coordinates
     994         572 :                 SCCOL nCurrDocCol = static_cast< SCCOL >( nCellInfoX - 1 );
     995         572 :                 SCROW nCurrDocRow = static_cast< SCROW >( (nCellInfoY > 0) ? rThisRowInfo.nRowNo : (nRow1 - 1) );
     996             : 
     997             :                 // find entire merged range in document, returns signed document coordinates
     998             :                 SCsCOL nFirstRealDocColS, nLastRealDocColS;
     999             :                 SCsROW nFirstRealDocRowS, nLastRealDocRowS;
    1000             :                 lcl_GetMergeRange( static_cast< SCsCOL >( nCurrDocCol ), static_cast< SCsROW >( nCurrDocRow ),
    1001             :                     nCellInfoY, this, pRowInfo, nCol1,nRow1,nCol2,nRow2,nTab,
    1002         572 :                     nFirstRealDocColS, nFirstRealDocRowS, nLastRealDocColS, nLastRealDocRowS );
    1003             : 
    1004             :                 // *complete* merged range in document coordinates
    1005         572 :                 SCCOL nFirstRealDocCol = static_cast< SCCOL >( nFirstRealDocColS );
    1006         572 :                 SCROW nFirstRealDocRow = static_cast< SCROW >( nFirstRealDocRowS );
    1007         572 :                 SCCOL nLastRealDocCol  = static_cast< SCCOL >( nLastRealDocColS );
    1008         572 :                 SCROW nLastRealDocRow  = static_cast< SCROW >( nLastRealDocRowS );
    1009             : 
    1010             :                 // first visible column (nX1-1 is first processed document column)
    1011         572 :                 SCCOL nFirstDocCol = (nCol1 > 0) ? ::std::max< SCCOL >( nFirstRealDocCol, nCol1 - 1 ) : nFirstRealDocCol;
    1012         572 :                 sal_uInt16 nFirstCellInfoX = static_cast< sal_uInt16 >( nFirstDocCol + 1 );
    1013         572 :                 nFirstCol = static_cast< size_t >( nFirstCellInfoX - nCol1 );
    1014             : 
    1015             :                 // last visible column (nX2+1 is last processed document column)
    1016         572 :                 SCCOL nLastDocCol = (nCol2 < MAXCOL) ? ::std::min< SCCOL >( nLastRealDocCol, nCol2 + 1 ) : nLastRealDocCol;
    1017         572 :                 sal_uInt16 nLastCellInfoX = static_cast< sal_uInt16 >( nLastDocCol + 1 );
    1018         572 :                 size_t nLastCol = static_cast< size_t >( nLastCellInfoX - nCol1 );
    1019             : 
    1020             :                 // first visible row
    1021         572 :                 sal_uInt16 nFirstCellInfoY = nCellInfoY;
    1022        1144 :                 while( ((nFirstCellInfoY > 1) && (pRowInfo[ nFirstCellInfoY - 1 ].nRowNo >= nFirstRealDocRow)) ||
    1023         558 :                        ((nFirstCellInfoY == 1) && (static_cast< SCROW >( nRow1 - 1 ) >= nFirstRealDocRow)) )
    1024           0 :                     --nFirstCellInfoY;
    1025         572 :                 SCROW nFirstDocRow = (nFirstCellInfoY > 0) ? pRowInfo[ nFirstCellInfoY ].nRowNo : static_cast< SCROW >( nRow1 - 1 );
    1026         572 :                 nFirstRow = static_cast< size_t >( nFirstCellInfoY );
    1027             : 
    1028             :                 // last visible row
    1029         572 :                 sal_uInt16 nLastCellInfoY = nCellInfoY;
    1030        4020 :                 while( (sal::static_int_cast<SCSIZE>(nLastCellInfoY + 1) < nArrCount) &&
    1031        1724 :                             (pRowInfo[ nLastCellInfoY + 1 ].nRowNo <= nLastRealDocRow) )
    1032        1152 :                     ++nLastCellInfoY;
    1033         572 :                 SCROW nLastDocRow = (nLastCellInfoY > 0) ? pRowInfo[ nLastCellInfoY ].nRowNo : static_cast< SCROW >( nRow1 - 1 );
    1034         572 :                 size_t nLastRow = static_cast< size_t >( nLastCellInfoY );
    1035             : 
    1036             :                 // insert merged range
    1037         572 :                 rArray.SetMergedRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
    1038             : 
    1039             :                 // *** find additional size not included in svx::frame::Array ***
    1040             : 
    1041             :                 // additional space before first column
    1042         572 :                 if( nFirstCol == 0 )
    1043             :                 {
    1044           0 :                     long nSize = 0;
    1045           0 :                     for( SCCOL nDocCol = nFirstRealDocCol; nDocCol < nFirstDocCol; ++nDocCol )
    1046           0 :                         nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * fColScale ), 1L );
    1047           0 :                     rArray.SetAddMergedLeftSize( nCol, nRow, nSize );
    1048             :                 }
    1049             :                 // additional space after last column
    1050         572 :                 if( nLastCol + 1 == nColCount )
    1051             :                 {
    1052          54 :                     long nSize = 0;
    1053          98 :                     for( SCCOL nDocCol = nLastDocCol + 1; nDocCol <= nLastRealDocCol; ++nDocCol )
    1054          44 :                         nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * fColScale ), 1L );
    1055          54 :                     rArray.SetAddMergedRightSize( nCol, nRow, nSize );
    1056             :                 }
    1057             :                 // additional space above first row
    1058         572 :                 if( nFirstRow == 0 )
    1059             :                 {
    1060           4 :                     long nSize = 0;
    1061           4 :                     for( SCROW nDocRow = nFirstRealDocRow; nDocRow < nFirstDocRow; ++nDocRow )
    1062           0 :                         nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * fRowScale ), 1L );
    1063           4 :                     rArray.SetAddMergedTopSize( nCol, nRow, nSize );
    1064             :                 }
    1065             :                 // additional space beyond last row
    1066         572 :                 if( nLastRow + 1 == nRowCount )
    1067             :                 {
    1068           0 :                     long nSize = 0;
    1069           0 :                     for( SCROW nDocRow = nLastDocRow + 1; nDocRow <= nLastRealDocRow; ++nDocRow )
    1070           0 :                         nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * fRowScale ), 1L );
    1071           0 :                     rArray.SetAddMergedBottomSize( nCol, nRow, nSize );
    1072             :                 }
    1073             : 
    1074             :                 // *** use line attributes from real origin cell ***
    1075             : 
    1076         572 :                 if( (nFirstRealDocCol != nCurrDocCol) || (nFirstRealDocRow != nCurrDocRow) )
    1077             :                 {
    1078           4 :                     if( const ScPatternAttr* pPattern = GetPattern( nFirstRealDocCol, nFirstRealDocRow, nTab ) )
    1079             :                     {
    1080           4 :                         const SfxItemSet* pCond = GetCondResult( nFirstRealDocCol, nFirstRealDocRow, nTab );
    1081           4 :                         pBox = static_cast< const SvxBoxItem* >( &pPattern->GetItem( ATTR_BORDER, pCond ) );
    1082           4 :                         pTLBR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_TLBR, pCond ) );
    1083           4 :                         pBLTR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_BLTR, pCond ) );
    1084             :                     }
    1085             :                     else
    1086             :                     {
    1087           0 :                         pBox = 0;
    1088           0 :                         pTLBR = pBLTR = 0;
    1089             :                     }
    1090             :                 }
    1091             :             }
    1092             : 
    1093             :             // *** borders *** ------------------------------------------------
    1094             : 
    1095     5531373 :             if( pBox )
    1096             :             {
    1097     4888206 :                 rArray.SetCellStyleLeft(   nFirstCol, nFirstRow, svx::frame::Style( pBox->GetLeft(),   fColScale ) );
    1098     4888206 :                 rArray.SetCellStyleRight(  nFirstCol, nFirstRow, svx::frame::Style( pBox->GetRight(),  fColScale ) );
    1099     4888206 :                 rArray.SetCellStyleTop(    nFirstCol, nFirstRow, svx::frame::Style( pBox->GetTop(),    fRowScale ) );
    1100     4888206 :                 rArray.SetCellStyleBottom( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetBottom(), fRowScale ) );
    1101             :             }
    1102             : 
    1103     5531373 :             if( pTLBR )
    1104     4888206 :                 rArray.SetCellStyleTLBR( nFirstCol, nFirstRow, svx::frame::Style( pTLBR->GetLine(), fRowScale ) );
    1105     5531373 :             if( pBLTR )
    1106     4888206 :                 rArray.SetCellStyleBLTR( nFirstCol, nFirstRow, svx::frame::Style( pBLTR->GetLine(), fRowScale ) );
    1107             :         }
    1108             :     }
    1109             : 
    1110             :     /*  Mirror the entire frame array.
    1111             :         1st param = Mirror the vertical double line styles as well.
    1112             :         2nd param = Do not swap diagonal lines.
    1113             :      */
    1114       16360 :     if( bLayoutRTL )
    1115           3 :         rArray.MirrorSelfX( true, false );
    1116       16360 : }
    1117             : 
    1118       16360 : ScTableInfo::ScTableInfo()
    1119       16360 :     : mpRowInfo(new RowInfo[ROWINFO_MAX])
    1120             :     , mnArrCount(0)
    1121       32720 :     , mbPageMode(false)
    1122             : {
    1123       16360 : }
    1124             : 
    1125       32720 : ScTableInfo::~ScTableInfo()
    1126             : {
    1127    16769000 :     for( sal_uInt16 nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx )
    1128    16752640 :         delete [] mpRowInfo[ nIdx ].pCellInfo;
    1129       16360 :     delete [] mpRowInfo;
    1130       16588 : }
    1131             : 
    1132             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10