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

Generated by: LCOV version 1.10