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