fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / data / fillinfo.cxx
blobe0e2623bc7c0cdce07f279dcfad33e373f9152db
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4 * This file is part of the LibreOffice project.
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/.
10 * This file incorporates work covered by the following license notice:
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 .
21 #include "scitems.hxx"
22 #include <editeng/boxitem.hxx>
23 #include <editeng/lineitem.hxx>
24 #include <editeng/editdata.hxx>
25 #include <editeng/shaditem.hxx>
26 #include <editeng/brushitem.hxx>
28 #include "fillinfo.hxx"
29 #include "document.hxx"
30 #include "formulacell.hxx"
31 #include "table.hxx"
32 #include "attrib.hxx"
33 #include "attarray.hxx"
34 #include "markarr.hxx"
35 #include "markdata.hxx"
36 #include "patattr.hxx"
37 #include "poolhelp.hxx"
38 #include "docpool.hxx"
39 #include "conditio.hxx"
40 #include "colorscale.hxx"
41 #include "stlpool.hxx"
42 #include "cellvalue.hxx"
43 #include "mtvcellfunc.hxx"
45 const sal_uInt16 ROWINFO_MAX = 1024;
47 enum FillInfoLinePos
49 FILP_TOP,
50 FILP_BOTTOM,
51 FILP_LEFT,
52 FILP_RIGHT
55 // Similar as in output.cxx
57 static void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY,
58 ScDocument* pDoc, RowInfo* pRowInfo,
59 SCCOL nX1, SCROW nY1, SCCOL /* nX2 */, SCROW /* nY2 */, SCTAB nTab,
60 SCsCOL& rStartX, SCsROW& rStartY, SCsCOL& rEndX, SCsROW& rEndY )
62 CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
64 rStartX = nX;
65 rStartY = nY;
66 bool bHOver = pInfo->bHOverlapped;
67 bool bVOver = pInfo->bVOverlapped;
68 SCCOL nLastCol;
69 SCROW nLastRow;
71 while (bHOver) // nY constant
73 --rStartX;
74 if (rStartX >= (SCsCOL) nX1 && !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol))
76 bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
77 bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
79 else
81 sal_uInt16 nOverlap = static_cast<const ScMergeFlagAttr*>(pDoc->GetAttr(
82 rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
83 bHOver = ((nOverlap & SC_MF_HOR) != 0);
84 bVOver = ((nOverlap & SC_MF_VER) != 0);
88 while (bVOver)
90 --rStartY;
92 if (nArrY>0)
93 --nArrY; // local copy !
95 if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
96 !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
97 !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
98 (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
100 bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
102 else
104 sal_uInt16 nOverlap = static_cast<const ScMergeFlagAttr*>(pDoc->GetAttr(
105 rStartX, rStartY, nTab, ATTR_MERGE_FLAG ))->GetValue();
106 bVOver = ((nOverlap & SC_MF_VER) != 0);
110 const ScMergeAttr* pMerge;
111 if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 &&
112 !pDoc->ColHidden(rStartX, nTab, NULL, &nLastCol) &&
113 !pDoc->RowHidden(rStartY, nTab, NULL, &nLastRow) &&
114 (SCsROW) pRowInfo[nArrY].nRowNo == rStartY)
116 pMerge = static_cast<const ScMergeAttr*>( &pRowInfo[nArrY].pCellInfo[rStartX+1].pPatternAttr->
117 GetItem(ATTR_MERGE));
119 else
120 pMerge = static_cast<const ScMergeAttr*>( pDoc->GetAttr(rStartX,rStartY,nTab,ATTR_MERGE) );
122 rEndX = rStartX + pMerge->GetColMerge() - 1;
123 rEndY = rStartY + pMerge->GetRowMerge() - 1;
126 namespace {
128 class RowInfoFiller
130 ScDocument& mrDoc;
131 SCTAB mnTab;
132 RowInfo* mpRowInfo;
133 SCCOL mnArrX;
134 SCSIZE& mrArrY;
135 SCROW mnHiddenEndRow;
136 bool mbHiddenRow;
138 bool isHidden(size_t nRow)
140 SCROW nThisRow = static_cast<SCROW>(nRow);
141 if (nThisRow > mnHiddenEndRow)
142 mbHiddenRow = mrDoc.RowHidden(nThisRow, mnTab, NULL, &mnHiddenEndRow);
143 return mbHiddenRow;
146 void alignArray(size_t nRow)
148 while (mpRowInfo[mrArrY].nRowNo < static_cast<SCROW>(nRow))
149 ++mrArrY;
152 void setInfo(size_t nRow, const ScRefCellValue& rCell)
154 alignArray(nRow);
156 RowInfo* pThisRowInfo = &mpRowInfo[mrArrY];
157 CellInfo* pInfo = &pThisRowInfo->pCellInfo[mnArrX];
158 pInfo->maCell = rCell;
159 pThisRowInfo->bEmptyText = false;
160 pInfo->bEmptyCellText = false;
161 ++mrArrY;
164 public:
165 RowInfoFiller(ScDocument& rDoc, SCTAB nTab, RowInfo* pRowInfo, SCCOL nArrX, SCSIZE& rArrY) :
166 mrDoc(rDoc), mnTab(nTab), mpRowInfo(pRowInfo), mnArrX(nArrX), mrArrY(rArrY),
167 mnHiddenEndRow(-1), mbHiddenRow(false) {}
169 void operator() (size_t nRow, double fVal)
171 if (!isHidden(nRow))
172 setInfo(nRow, ScRefCellValue(fVal));
175 void operator() (size_t nRow, const svl::SharedString& rStr)
177 if (!isHidden(nRow))
178 setInfo(nRow, ScRefCellValue(&rStr));
181 void operator() (size_t nRow, const EditTextObject* p)
183 if (!isHidden(nRow))
184 setInfo(nRow, ScRefCellValue(p));
187 void operator() (size_t nRow, const ScFormulaCell* p)
189 if (!isHidden(nRow))
190 setInfo(nRow, ScRefCellValue(const_cast<ScFormulaCell*>(p)));
196 void ScDocument::FillInfo(
197 ScTableInfo& rTabInfo, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
198 SCTAB nTab, double fColScale, double fRowScale, bool bPageMode, bool bFormulaMode,
199 const ScMarkData* pMarkData )
201 OSL_ENSURE( maTabs[nTab], "Table does not exist" );
203 bool bLayoutRTL = IsLayoutRTL( nTab );
205 ScDocumentPool* pPool = xPoolHelper->GetDocPool();
206 ScStyleSheetPool* pStlPool = xPoolHelper->GetStylePool();
208 RowInfo* pRowInfo = rTabInfo.mpRowInfo;
210 const SvxBrushItem* pDefBackground =
211 static_cast<const SvxBrushItem*>( &pPool->GetDefaultItem( ATTR_BACKGROUND ) );
212 const ScMergeAttr* pDefMerge =
213 static_cast<const ScMergeAttr*>( &pPool->GetDefaultItem( ATTR_MERGE ) );
214 const SvxShadowItem* pDefShadow =
215 static_cast<const SvxShadowItem*>( &pPool->GetDefaultItem( ATTR_SHADOW ) );
217 SCROW nThisRow;
218 SCCOL nX;
219 SCROW nY;
220 SCsROW nSignedY;
221 SCCOL nArrCol;
222 SCSIZE nArrRow;
223 SCSIZE nArrCount;
224 bool bAnyMerged = false;
225 bool bAnyShadow = false;
226 bool bAnyCondition = false;
227 bool bAnyPreview = false;
229 bool bTabProtect = IsTabProtected(nTab);
231 // for block marks of merged cells
232 // with hidden first row/column
233 bool bPaintMarks = false;
234 bool bSkipMarks = false;
235 SCCOL nBlockStartX = 0, nBlockEndX = 0;
236 SCROW nBlockEndY = 0, nBlockStartY = 0;
237 if (pMarkData && pMarkData->IsMarked())
239 ScRange aTmpRange;
240 pMarkData->GetMarkArea(aTmpRange);
241 if ( nTab >= aTmpRange.aStart.Tab() && nTab <= aTmpRange.aEnd.Tab() )
243 nBlockStartX = aTmpRange.aStart.Col();
244 nBlockStartY = aTmpRange.aStart.Row();
245 nBlockEndX = aTmpRange.aEnd.Col();
246 nBlockEndY = aTmpRange.aEnd.Row();
247 ExtendHidden( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY, nTab ); //? needed ?
248 if (pMarkData->IsMarkNegative())
249 bSkipMarks = true;
250 else
251 bPaintMarks = true;
255 // first only the entries for the entire column
257 nArrRow=0;
258 SCROW nYExtra = nRow2+1;
259 sal_uInt16 nDocHeight = ScGlobal::nStdRowHeight;
260 SCROW nDocHeightEndRow = -1;
261 for (nSignedY=((SCsROW)nRow1)-1; nSignedY<=(SCsROW)nYExtra; nSignedY++)
263 if (nSignedY >= 0)
264 nY = (SCROW) nSignedY;
265 else
266 nY = MAXROW+1; // invalid
268 if (nY > nDocHeightEndRow)
270 if (ValidRow(nY))
271 nDocHeight = GetRowHeight( nY, nTab, NULL, &nDocHeightEndRow );
272 else
273 nDocHeight = ScGlobal::nStdRowHeight;
276 if ( nArrRow==0 || nDocHeight || nY > MAXROW )
278 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
279 pThisRowInfo->pCellInfo = NULL; // is loaded below
281 sal_uInt16 nHeight = (sal_uInt16) ( nDocHeight * fRowScale );
282 if (!nHeight)
283 nHeight = 1;
285 pThisRowInfo->nRowNo = nY; //TODO: case < 0 ?
286 pThisRowInfo->nHeight = nHeight;
287 pThisRowInfo->bEmptyBack = true;
288 pThisRowInfo->bEmptyText = true;
289 pThisRowInfo->bChanged = true;
290 pThisRowInfo->bAutoFilter = false;
291 pThisRowInfo->bPivotButton = false;
292 pThisRowInfo->nRotMaxCol = SC_ROTMAX_NONE;
294 ++nArrRow;
295 if (nArrRow >= ROWINFO_MAX)
297 OSL_FAIL("FillInfo: Range too big" );
298 nYExtra = nSignedY; // End
299 nRow2 = nYExtra - 1; // Adjust range
302 else
303 if (nSignedY==(SCsROW) nYExtra) // hidden additional line?
304 ++nYExtra;
306 nArrCount = nArrRow; // incl. Dummys
308 // Rotated text...
310 // Is Attribute really used in document?
311 bool bAnyItem = false;
312 sal_uInt32 nRotCount = pPool->GetItemCount2( ATTR_ROTATE_VALUE );
313 for (sal_uInt32 nItem=0; nItem<nRotCount; nItem++)
314 if (pPool->GetItem2( ATTR_ROTATE_VALUE, nItem ))
316 bAnyItem = true;
317 break;
320 SCCOL nRotMax = nCol2;
321 if ( bAnyItem && HasAttrib( 0,nRow1,nTab, MAXCOL,nRow2+1,nTab,
322 HASATTR_ROTATE | HASATTR_CONDITIONAL ) )
324 //TODO: check Conditionals also for HASATTR_ROTATE ????
326 OSL_ENSURE( nArrCount>2, "nArrCount too small" );
327 FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-1, nCol1, nCol2 );
328 // FindMaxRotCol setzt nRotMaxCol
330 for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
331 if (pRowInfo[nArrRow].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nArrRow].nRotMaxCol > nRotMax)
332 nRotMax = pRowInfo[nArrRow].nRotMaxCol;
335 // Allocate cell information only after the test rotation
336 // to nRotMax due to nRotateDir Flag
338 for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
340 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
341 nY = pThisRowInfo->nRowNo;
342 pThisRowInfo->pCellInfo = new CellInfo[ nRotMax+1+2 ]; // to delete the caller!
344 for (nArrCol=0; nArrCol<=nRotMax+2; nArrCol++) // Preassign cell info
346 if (nArrCol>0)
347 nX = nArrCol-1;
348 else
349 nX = MAXCOL+1; // invalid
351 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
352 pInfo->bEmptyCellText = true;
353 pInfo->maCell.clear();
354 if (bPaintMarks)
355 pInfo->bMarked = ( nX >= nBlockStartX && nX <= nBlockEndX
356 && nY >= nBlockStartY && nY <= nBlockEndY );
357 else
358 pInfo->bMarked = false;
359 pInfo->nWidth = 0;
361 pInfo->nClipMark = SC_CLIPMARK_NONE;
362 pInfo->bMerged = false;
363 pInfo->bHOverlapped = false;
364 pInfo->bVOverlapped = false;
365 pInfo->bAutoFilter = false;
366 pInfo->bPivotButton = false;
367 pInfo->bPivotPopupButton = false;
368 pInfo->bFilterActive = false;
369 pInfo->nRotateDir = SC_ROTDIR_NONE;
371 pInfo->bPrinted = false; // view-internal
372 pInfo->bHideGrid = false; // view-internal
373 pInfo->bEditEngine = false; // view-internal
375 pInfo->pBackground = NULL; //TODO: omit?
376 pInfo->pPatternAttr = NULL;
377 pInfo->pConditionSet= NULL;
379 pInfo->pLinesAttr = NULL;
380 pInfo->mpTLBRLine = NULL;
381 pInfo->mpBLTRLine = NULL;
383 pInfo->pShadowAttr = pDefShadow;
384 pInfo->pHShadowOrigin = NULL;
385 pInfo->pVShadowOrigin = NULL;
389 for (nArrCol=nCol2+3; nArrCol<=nRotMax+2; nArrCol++) // Add remaining widths
391 nX = nArrCol-1;
392 if ( ValidCol(nX) )
394 if (!ColHidden(nX, nTab))
396 sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * fColScale);
397 if (!nThisWidth)
398 nThisWidth = 1;
400 pRowInfo[0].pCellInfo[nArrCol].nWidth = nThisWidth;
405 ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
406 if(pCondFormList)
407 pCondFormList->startRendering();
409 for (nArrCol=0; nArrCol<=nCol2+2; nArrCol++) // left & right + 1
411 nX = (nArrCol>0) ? nArrCol-1 : MAXCOL+1; // negative -> invalid
413 if ( ValidCol(nX) )
415 // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes
416 // will disturb the output
418 // TODO: Optimize this loop.
419 if (!ColHidden(nX, nTab))
421 sal_uInt16 nThisWidth = (sal_uInt16) (GetColWidth( nX, nTab ) * fColScale);
422 if (!nThisWidth)
423 nThisWidth = 1;
425 pRowInfo[0].pCellInfo[nArrCol].nWidth = nThisWidth; //TODO: this should be enough
427 ScColumn* pThisCol = &maTabs[nTab]->aCol[nX]; // Column data
429 nArrRow = 1;
430 // Iterate between rows nY1 and nY2 and pick up non-empty
431 // cells that are not hidden.
432 RowInfoFiller aFunc(*this, nTab, pRowInfo, nArrCol, nArrRow);
433 sc::ParseAllNonEmpty(
434 pThisCol->maCells.begin(), pThisCol->maCells, nRow1, nRow2, aFunc);
436 if (nX+1 >= nCol1) // Attribute/Blockmark from nX1-1
438 ScAttrArray* pThisAttrArr = pThisCol->pAttrArray; // Attribute
440 nArrRow = 0;
441 const ScPatternAttr* pPattern;
442 SCROW nCurRow=nRow1; // single rows
443 if (nCurRow>0)
444 --nCurRow; // 1 more on top
445 else
446 nArrRow = 1;
447 nThisRow=nCurRow; // end of range
448 SCSIZE nIndex;
449 (void) pThisAttrArr->Search( nCurRow, nIndex );
453 nThisRow=pThisAttrArr->pData[nIndex].nRow; // End of range
454 pPattern=pThisAttrArr->pData[nIndex].pPattern;
456 const SvxBrushItem* pBackground = static_cast<const SvxBrushItem*>(
457 &pPattern->GetItem(ATTR_BACKGROUND));
458 const SvxBoxItem* pLinesAttr = static_cast<const SvxBoxItem*>(
459 &pPattern->GetItem(ATTR_BORDER));
461 const SvxLineItem* pTLBRLine = static_cast< const SvxLineItem* >(
462 &pPattern->GetItem( ATTR_BORDER_TLBR ) );
463 const SvxLineItem* pBLTRLine = static_cast< const SvxLineItem* >(
464 &pPattern->GetItem( ATTR_BORDER_BLTR ) );
466 const SvxShadowItem* pShadowAttr = static_cast<const SvxShadowItem*>(
467 &pPattern->GetItem(ATTR_SHADOW));
468 if (pShadowAttr != pDefShadow)
469 bAnyShadow = true;
471 const ScMergeAttr* pMergeAttr = static_cast<const ScMergeAttr*>(
472 &pPattern->GetItem(ATTR_MERGE));
473 bool bMerged = ( pMergeAttr != pDefMerge && *pMergeAttr != *pDefMerge );
474 sal_uInt16 nOverlap = static_cast<const ScMergeFlagAttr*>( &pPattern->GetItemSet().
475 Get(ATTR_MERGE_FLAG))->GetValue();
476 bool bHOverlapped = ((nOverlap & SC_MF_HOR) != 0);
477 bool bVOverlapped = ((nOverlap & SC_MF_VER) != 0);
478 bool bAutoFilter = ((nOverlap & SC_MF_AUTO) != 0);
479 bool bPivotButton = ((nOverlap & SC_MF_BUTTON) != 0);
480 bool bScenario = ((nOverlap & SC_MF_SCENARIO) != 0);
481 bool bPivotPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0);
482 bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0);
483 if (bMerged||bHOverlapped||bVOverlapped)
484 bAnyMerged = true; // internal
486 bool bHidden, bHideFormula;
487 if (bTabProtect)
489 const ScProtectionAttr& rProtAttr = static_cast<const ScProtectionAttr&>(
490 pPattern->GetItem(ATTR_PROTECTION));
491 bHidden = rProtAttr.GetHideCell();
492 bHideFormula = rProtAttr.GetHideFormula();
494 else
495 bHidden = bHideFormula = false;
497 const std::vector<sal_uInt32>& rCondFormats = static_cast<const ScCondFormatItem&>(pPattern->GetItem(ATTR_CONDITIONAL)).GetCondFormatData();
498 bool bContainsCondFormat = !rCondFormats.empty();
502 SCROW nLastHiddenRow = -1;
503 bool bRowHidden = RowHidden(nCurRow, nTab, NULL, &nLastHiddenRow);
504 if ( nArrRow==0 || !bRowHidden )
506 if ( GetPreviewCellStyle( nX, nCurRow, nTab ) != NULL )
507 bAnyPreview = true;
508 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
509 if (pBackground != pDefBackground) // Column background == Default ?
510 pThisRowInfo->bEmptyBack = false;
511 if (bContainsCondFormat)
512 pThisRowInfo->bEmptyBack = false;
513 if (bAutoFilter)
514 pThisRowInfo->bAutoFilter = true;
515 if (bPivotButton || bPivotPopupButton)
516 pThisRowInfo->bPivotButton = true;
518 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
519 pInfo->pBackground = pBackground;
520 pInfo->pPatternAttr = pPattern;
521 pInfo->bMerged = bMerged;
522 pInfo->bHOverlapped = bHOverlapped;
523 pInfo->bVOverlapped = bVOverlapped;
524 pInfo->bAutoFilter = bAutoFilter;
525 pInfo->bPivotButton = bPivotButton;
526 pInfo->bPivotPopupButton = bPivotPopupButton;
527 pInfo->bFilterActive = bFilterActive;
528 pInfo->pLinesAttr = pLinesAttr;
529 pInfo->mpTLBRLine = pTLBRLine;
530 pInfo->mpBLTRLine = pBLTRLine;
531 pInfo->pShadowAttr = pShadowAttr;
532 // nWidth is no longer set individually
534 if (bScenario)
536 pInfo->pBackground = ScGlobal::GetButtonBrushItem();
537 pThisRowInfo->bEmptyBack = false;
540 if ( bContainsCondFormat )
542 bool bFound = false;
543 for(std::vector<sal_uInt32>::const_iterator itr = rCondFormats.begin();
544 itr != rCondFormats.end() && !bFound; ++itr)
546 ScConditionalFormat* pCondForm = pCondFormList->GetFormat(*itr);
547 if(!pCondForm)
548 continue;
550 ScCondFormatData aData = pCondForm->GetData(
551 pInfo->maCell, ScAddress(nX, nCurRow, nTab));
552 if (!aData.aStyleName.isEmpty())
554 SfxStyleSheetBase* pStyleSheet =
555 pStlPool->Find( aData.aStyleName, SFX_STYLE_FAMILY_PARA );
556 if ( pStyleSheet )
558 //TODO: cache Style-Sets !!!
559 pInfo->pConditionSet = &pStyleSheet->GetItemSet();
560 bAnyCondition = true;
562 // we need to check already here for protected cells
563 const SfxPoolItem* pItem;
564 if ( bTabProtect && pInfo->pConditionSet->GetItemState( ATTR_PROTECTION, true, &pItem ) == SfxItemState::SET )
566 const ScProtectionAttr* pProtAttr = static_cast<const ScProtectionAttr*>(pItem);
567 bHidden = pProtAttr->GetHideCell();
568 bHideFormula = pProtAttr->GetHideFormula();
571 bFound = true;
574 // if style is not there, treat like no condition
576 if(aData.pColorScale)
578 pInfo->pColorScale.reset(aData.pColorScale);
579 bFound = true;
582 if(aData.pDataBar)
584 pInfo->pDataBar.reset(aData.pDataBar);
585 bFound = true;
587 if(aData.pIconSet)
589 pInfo->pIconSet.reset(aData.pIconSet);
590 bFound = true;
595 if (bHidden || (bFormulaMode && bHideFormula && pInfo->maCell.meType == CELLTYPE_FORMULA))
596 pInfo->bEmptyCellText = true;
598 ++nArrRow;
600 else if (bRowHidden && nLastHiddenRow >= 0)
602 nCurRow = nLastHiddenRow;
603 if (nCurRow > nThisRow)
604 nCurRow = nThisRow;
606 ++nCurRow;
608 while (nCurRow <= nThisRow && nCurRow <= nYExtra);
609 ++nIndex;
611 while ( nIndex < pThisAttrArr->nCount && nThisRow < nYExtra );
613 if (pMarkData && pMarkData->IsMultiMarked())
615 // Block marks
616 const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nX;
617 nArrRow = 1;
618 nCurRow = nRow1; // single rows
619 nThisRow = nRow1; // End of range
621 if ( pThisMarkArr->Search( nRow1, nIndex ) )
625 nThisRow=pThisMarkArr->pData[nIndex].nRow; // End of range
626 const bool bThisMarked=pThisMarkArr->pData[nIndex].bMarked;
630 if ( !RowHidden( nCurRow,nTab ) )
632 if ( bThisMarked )
634 bool bSkip = bSkipMarks &&
635 nX >= nBlockStartX &&
636 nX <= nBlockEndX &&
637 nCurRow >= nBlockStartY &&
638 nCurRow <= nBlockEndY;
639 if (!bSkip)
641 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
642 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
643 pInfo->bMarked = true;
646 ++nArrRow;
648 ++nCurRow;
650 while (nCurRow <= nThisRow && nCurRow <= nRow2);
651 ++nIndex;
653 while ( nIndex < pThisMarkArr->nCount && nThisRow < nRow2 );
657 else // columns in front
659 for (nArrRow=1; nArrRow+1<nArrCount; nArrRow++)
661 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
662 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
664 pInfo->nWidth = nThisWidth; //TODO: or check only 0 ??
669 else
670 pRowInfo[0].pCellInfo[nArrCol].nWidth = STD_COL_WIDTH;
671 // STD_COL_WIDTH farthest to the left and right is needed for DrawExtraShadow
674 if(pCondFormList)
675 pCondFormList->endRendering();
677 // bedingte Formatierung auswerten
678 ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
679 // favour preview over condition
680 if (bAnyCondition || bAnyPreview)
682 for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
684 for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++) // 1 more left and right
686 CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
687 SCCOL nCol = (nArrCol>0) ? nArrCol-1 : MAXCOL+1;
688 ScPatternAttr* pModifiedPatt = NULL;
690 if ( ValidCol(nCol) && pRowInfo[nArrRow].nRowNo <= MAXROW )
692 if ( ScStyleSheet* pPreviewStyle = GetPreviewCellStyle( nCol, pRowInfo[nArrRow].nRowNo, nTab ) )
694 aAltPatterns.push_back( new ScPatternAttr( *pInfo->pPatternAttr ) );
695 pModifiedPatt = &aAltPatterns.back();
696 pModifiedPatt->SetStyleSheet( pPreviewStyle );
699 // favour preview over condition
700 const SfxItemSet* pCondSet = pModifiedPatt ? &pModifiedPatt->GetItemSet() : pInfo->pConditionSet;
702 if (pCondSet)
704 const SfxPoolItem* pItem;
706 // Background
707 if ( pCondSet->GetItemState( ATTR_BACKGROUND, true, &pItem ) == SfxItemState::SET )
709 pInfo->pBackground = static_cast<const SvxBrushItem*>(pItem);
710 pRowInfo[nArrRow].bEmptyBack = false;
713 // Border
714 if ( pCondSet->GetItemState( ATTR_BORDER, true, &pItem ) == SfxItemState::SET )
715 pInfo->pLinesAttr = static_cast<const SvxBoxItem*>(pItem);
717 if ( pCondSet->GetItemState( ATTR_BORDER_TLBR, true, &pItem ) == SfxItemState::SET )
718 pInfo->mpTLBRLine = static_cast< const SvxLineItem* >( pItem );
719 if ( pCondSet->GetItemState( ATTR_BORDER_BLTR, true, &pItem ) == SfxItemState::SET )
720 pInfo->mpBLTRLine = static_cast< const SvxLineItem* >( pItem );
722 // Shadow
723 if ( pCondSet->GetItemState( ATTR_SHADOW, true, &pItem ) == SfxItemState::SET )
725 pInfo->pShadowAttr = static_cast<const SvxShadowItem*>(pItem);
726 bAnyShadow = true;
729 if( bAnyCondition && pInfo->pColorScale)
731 pRowInfo[nArrRow].bEmptyBack = false;
732 pInfo->pBackground = new SvxBrushItem(*pInfo->pColorScale, ATTR_BACKGROUND);
738 // End conditional formatting
740 // Adjust data from merged cells
742 if (bAnyMerged)
744 for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
746 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
747 nSignedY = nArrRow ? pThisRowInfo->nRowNo : ((SCsROW)nRow1)-1;
749 for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++) // 1 more left and right
751 SCsCOL nSignedX = ((SCsCOL) nArrCol) - 1;
752 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
754 if (pInfo->bMerged || pInfo->bHOverlapped || pInfo->bVOverlapped)
756 SCsCOL nStartX;
757 SCsROW nStartY;
758 SCsCOL nEndX;
759 SCsROW nEndY;
760 lcl_GetMergeRange( nSignedX,nSignedY, nArrRow, this,pRowInfo, nCol1,nRow1,nCol2,nRow2,nTab,
761 nStartX,nStartY, nEndX,nEndY );
762 const ScPatternAttr* pStartPattern = GetPattern( nStartX,nStartY,nTab );
763 const SfxItemSet* pStartCond = GetCondResult( nStartX,nStartY,nTab );
764 const SfxPoolItem* pItem;
766 // Copy Background (or in output.cxx)
768 if ( !pStartCond || pStartCond->
769 GetItemState(ATTR_BACKGROUND,true,&pItem) != SfxItemState::SET )
770 pItem = &pStartPattern->GetItem(ATTR_BACKGROUND);
771 pInfo->pBackground = static_cast<const SvxBrushItem*>(pItem);
772 pRowInfo[nArrRow].bEmptyBack = false;
774 // Shadow
776 if ( !pStartCond || pStartCond->
777 GetItemState(ATTR_SHADOW,true,&pItem) != SfxItemState::SET )
778 pItem = &pStartPattern->GetItem(ATTR_SHADOW);
779 pInfo->pShadowAttr = static_cast<const SvxShadowItem*>(pItem);
780 if (pInfo->pShadowAttr != pDefShadow)
781 bAnyShadow = true;
783 // Block marks - again with the original merge values
785 bool bCellMarked = false;
786 if (bPaintMarks)
787 bCellMarked = ( nStartX >= (SCsCOL) nBlockStartX
788 && nStartX <= (SCsCOL) nBlockEndX
789 && nStartY >= (SCsROW) nBlockStartY
790 && nStartY <= (SCsROW) nBlockEndY );
791 if (pMarkData && pMarkData->IsMultiMarked() && !bCellMarked)
793 const ScMarkArray* pThisMarkArr = pMarkData->GetArray()+nStartX;
794 SCSIZE nIndex;
795 if ( pThisMarkArr->Search( nStartY, nIndex ) )
796 bCellMarked=pThisMarkArr->pData[nIndex].bMarked;
799 pInfo->bMarked = bCellMarked;
805 if (bAnyShadow) // distribute Shadow
807 for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
809 bool bTop = ( nArrRow == 0 );
810 bool bBottom = ( nArrRow+1 == nArrCount );
812 for (nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++) // 1 more left and right
814 bool bLeft = ( nArrCol == nCol1 );
815 bool bRight = ( nArrCol == nCol2+2 );
817 CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
818 const SvxShadowItem* pThisAttr = pInfo->pShadowAttr;
819 SvxShadowLocation eLoc = pThisAttr ? pThisAttr->GetLocation() : SVX_SHADOW_NONE;
820 if (eLoc != SVX_SHADOW_NONE)
822 // or test on != eLoc
824 SCsCOL nDxPos = 1;
825 SCsCOL nDxNeg = -1;
827 while ( nArrCol+nDxPos < nCol2+2 && pRowInfo[0].pCellInfo[nArrCol+nDxPos].nWidth == 0 )
828 ++nDxPos;
829 while ( nArrCol+nDxNeg > nCol1 && pRowInfo[0].pCellInfo[nArrCol+nDxNeg].nWidth == 0 )
830 --nDxNeg;
832 bool bLeftDiff = !bLeft &&
833 pRowInfo[nArrRow].pCellInfo[nArrCol+nDxNeg].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
834 bool bRightDiff = !bRight &&
835 pRowInfo[nArrRow].pCellInfo[nArrCol+nDxPos].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
836 bool bTopDiff = !bTop &&
837 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
838 bool bBottomDiff = !bBottom &&
839 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == SVX_SHADOW_NONE;
841 if ( bLayoutRTL )
843 switch (eLoc)
845 case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break;
846 case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
847 case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_TOPLEFT; break;
848 case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break;
849 default:
851 // added to avoid warnings
856 switch (eLoc)
858 case SVX_SHADOW_BOTTOMRIGHT:
859 if (bBottomDiff)
861 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
862 pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
863 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
865 if (bRightDiff)
867 pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
868 pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
869 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
871 if (bBottomDiff && bRightDiff)
873 pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
874 pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
876 break;
878 case SVX_SHADOW_BOTTOMLEFT:
879 if (bBottomDiff)
881 pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
882 pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
883 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
885 if (bLeftDiff)
887 pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
888 pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
889 bTopDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
891 if (bBottomDiff && bLeftDiff)
893 pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
894 pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
896 break;
898 case SVX_SHADOW_TOPRIGHT:
899 if (bTopDiff)
901 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
902 pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
903 bLeftDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
905 if (bRightDiff)
907 pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
908 pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
909 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
911 if (bTopDiff && bRightDiff)
913 pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
914 pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
916 break;
918 case SVX_SHADOW_TOPLEFT:
919 if (bTopDiff)
921 pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
922 pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
923 bRightDiff ? SC_SHADOW_HSTART : SC_SHADOW_HORIZ;
925 if (bLeftDiff)
927 pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
928 pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
929 bBottomDiff ? SC_SHADOW_VSTART : SC_SHADOW_VERT;
931 if (bTopDiff && bLeftDiff)
933 pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
934 pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
936 break;
938 default:
939 OSL_FAIL("wrong Shadow-Enum");
946 rTabInfo.mnArrCount = sal::static_int_cast<sal_uInt16>(nArrCount);
947 rTabInfo.mbPageMode = bPageMode;
949 // *** create the frame border array ***
951 // RowInfo structs are filled in the range [ 0 , nArrCount-1 ]
952 // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ]
954 size_t nColCount = nCol2 - nCol1 + 3;
955 size_t nRowCount = nArrCount;
957 svx::frame::Array& rArray = rTabInfo.maArray;
958 rArray.Initialize( nColCount, nRowCount );
959 rArray.SetUseDiagDoubleClipping( false );
961 for( size_t nRow = 0; nRow < nRowCount; ++nRow )
963 sal_uInt16 nCellInfoY = static_cast< sal_uInt16 >( nRow );
964 RowInfo& rThisRowInfo = pRowInfo[ nCellInfoY ];
966 for( size_t nCol = 0; nCol < nColCount; ++nCol )
968 sal_uInt16 nCellInfoX = static_cast< sal_uInt16 >( nCol + nCol1 );
969 const CellInfo& rInfo = rThisRowInfo.pCellInfo[ nCellInfoX ];
971 const SvxBoxItem* pBox = rInfo.pLinesAttr;
972 const SvxLineItem* pTLBR = rInfo.mpTLBRLine;
973 const SvxLineItem* pBLTR = rInfo.mpBLTRLine;
975 size_t nFirstCol = nCol;
976 size_t nFirstRow = nRow;
978 // *** merged cells *** -------------------------------------------
980 if( !rArray.IsMerged( nCol, nRow ) && (rInfo.bMerged || rInfo.bHOverlapped || rInfo.bVOverlapped) )
982 // *** insert merged range in svx::frame::Array ***
984 /* #i69369# top-left cell of a merged range may be located in
985 a hidden column or row. Use lcl_GetMergeRange() to find the
986 complete merged range, then calculate dimensions and
987 document position of the visible range. */
989 // note: document columns are always one less than CellInfoX coords
990 // note: document rows must be looked up in RowInfo structs
992 // current column and row in document coordinates
993 SCCOL nCurrDocCol = static_cast< SCCOL >( nCellInfoX - 1 );
994 SCROW nCurrDocRow = static_cast< SCROW >( (nCellInfoY > 0) ? rThisRowInfo.nRowNo : (nRow1 - 1) );
996 // find entire merged range in document, returns signed document coordinates
997 SCsCOL nFirstRealDocColS, nLastRealDocColS;
998 SCsROW nFirstRealDocRowS, nLastRealDocRowS;
999 lcl_GetMergeRange( static_cast< SCsCOL >( nCurrDocCol ), static_cast< SCsROW >( nCurrDocRow ),
1000 nCellInfoY, this, pRowInfo, nCol1,nRow1,nCol2,nRow2,nTab,
1001 nFirstRealDocColS, nFirstRealDocRowS, nLastRealDocColS, nLastRealDocRowS );
1003 // *complete* merged range in document coordinates
1004 SCCOL nFirstRealDocCol = static_cast< SCCOL >( nFirstRealDocColS );
1005 SCROW nFirstRealDocRow = static_cast< SCROW >( nFirstRealDocRowS );
1006 SCCOL nLastRealDocCol = static_cast< SCCOL >( nLastRealDocColS );
1007 SCROW nLastRealDocRow = static_cast< SCROW >( nLastRealDocRowS );
1009 // first visible column (nX1-1 is first processed document column)
1010 SCCOL nFirstDocCol = (nCol1 > 0) ? ::std::max< SCCOL >( nFirstRealDocCol, nCol1 - 1 ) : nFirstRealDocCol;
1011 sal_uInt16 nFirstCellInfoX = static_cast< sal_uInt16 >( nFirstDocCol + 1 );
1012 nFirstCol = static_cast< size_t >( nFirstCellInfoX - nCol1 );
1014 // last visible column (nX2+1 is last processed document column)
1015 SCCOL nLastDocCol = (nCol2 < MAXCOL) ? ::std::min< SCCOL >( nLastRealDocCol, nCol2 + 1 ) : nLastRealDocCol;
1016 sal_uInt16 nLastCellInfoX = static_cast< sal_uInt16 >( nLastDocCol + 1 );
1017 size_t nLastCol = static_cast< size_t >( nLastCellInfoX - nCol1 );
1019 // first visible row
1020 sal_uInt16 nFirstCellInfoY = nCellInfoY;
1021 while( ((nFirstCellInfoY > 1) && (pRowInfo[ nFirstCellInfoY - 1 ].nRowNo >= nFirstRealDocRow)) ||
1022 ((nFirstCellInfoY == 1) && (static_cast< SCROW >( nRow1 - 1 ) >= nFirstRealDocRow)) )
1023 --nFirstCellInfoY;
1024 SCROW nFirstDocRow = (nFirstCellInfoY > 0) ? pRowInfo[ nFirstCellInfoY ].nRowNo : static_cast< SCROW >( nRow1 - 1 );
1025 nFirstRow = static_cast< size_t >( nFirstCellInfoY );
1027 // last visible row
1028 sal_uInt16 nLastCellInfoY = nCellInfoY;
1029 while( (sal::static_int_cast<SCSIZE>(nLastCellInfoY + 1) < nArrCount) &&
1030 (pRowInfo[ nLastCellInfoY + 1 ].nRowNo <= nLastRealDocRow) )
1031 ++nLastCellInfoY;
1032 SCROW nLastDocRow = (nLastCellInfoY > 0) ? pRowInfo[ nLastCellInfoY ].nRowNo : static_cast< SCROW >( nRow1 - 1 );
1033 size_t nLastRow = static_cast< size_t >( nLastCellInfoY );
1035 // insert merged range
1036 rArray.SetMergedRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
1038 // *** find additional size not included in svx::frame::Array ***
1040 // additional space before first column
1041 if( nFirstCol == 0 )
1043 long nSize = 0;
1044 for( SCCOL nDocCol = nFirstRealDocCol; nDocCol < nFirstDocCol; ++nDocCol )
1045 nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * fColScale ), 1L );
1046 rArray.SetAddMergedLeftSize( nCol, nRow, nSize );
1048 // additional space after last column
1049 if( nLastCol + 1 == nColCount )
1051 long nSize = 0;
1052 for( SCCOL nDocCol = nLastDocCol + 1; nDocCol <= nLastRealDocCol; ++nDocCol )
1053 nSize += std::max( static_cast< long >( GetColWidth( nDocCol, nTab ) * fColScale ), 1L );
1054 rArray.SetAddMergedRightSize( nCol, nRow, nSize );
1056 // additional space above first row
1057 if( nFirstRow == 0 )
1059 long nSize = 0;
1060 for( SCROW nDocRow = nFirstRealDocRow; nDocRow < nFirstDocRow; ++nDocRow )
1061 nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * fRowScale ), 1L );
1062 rArray.SetAddMergedTopSize( nCol, nRow, nSize );
1064 // additional space beyond last row
1065 if( nLastRow + 1 == nRowCount )
1067 long nSize = 0;
1068 for( SCROW nDocRow = nLastDocRow + 1; nDocRow <= nLastRealDocRow; ++nDocRow )
1069 nSize += std::max( static_cast< long >( GetRowHeight( nDocRow, nTab ) * fRowScale ), 1L );
1070 rArray.SetAddMergedBottomSize( nCol, nRow, nSize );
1073 // *** use line attributes from real origin cell ***
1075 if( (nFirstRealDocCol != nCurrDocCol) || (nFirstRealDocRow != nCurrDocRow) )
1077 if( const ScPatternAttr* pPattern = GetPattern( nFirstRealDocCol, nFirstRealDocRow, nTab ) )
1079 const SfxItemSet* pCond = GetCondResult( nFirstRealDocCol, nFirstRealDocRow, nTab );
1080 pBox = static_cast< const SvxBoxItem* >( &pPattern->GetItem( ATTR_BORDER, pCond ) );
1081 pTLBR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_TLBR, pCond ) );
1082 pBLTR = static_cast< const SvxLineItem* >( &pPattern->GetItem( ATTR_BORDER_BLTR, pCond ) );
1084 else
1086 pBox = 0;
1087 pTLBR = pBLTR = 0;
1092 // *** borders *** ------------------------------------------------
1094 if( pBox )
1096 rArray.SetCellStyleLeft( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetLeft(), fColScale ) );
1097 rArray.SetCellStyleRight( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetRight(), fColScale ) );
1098 rArray.SetCellStyleTop( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetTop(), fRowScale ) );
1099 rArray.SetCellStyleBottom( nFirstCol, nFirstRow, svx::frame::Style( pBox->GetBottom(), fRowScale ) );
1102 if( pTLBR )
1103 rArray.SetCellStyleTLBR( nFirstCol, nFirstRow, svx::frame::Style( pTLBR->GetLine(), fRowScale ) );
1104 if( pBLTR )
1105 rArray.SetCellStyleBLTR( nFirstCol, nFirstRow, svx::frame::Style( pBLTR->GetLine(), fRowScale ) );
1109 /* Mirror the entire frame array.
1110 1st param = Mirror the vertical double line styles as well.
1111 2nd param = Do not swap diagonal lines.
1113 if( bLayoutRTL )
1114 rArray.MirrorSelfX( true, false );
1117 ScTableInfo::ScTableInfo()
1118 : mpRowInfo(new RowInfo[ROWINFO_MAX])
1119 , mnArrCount(0)
1120 , mbPageMode(false)
1122 memset(mpRowInfo, 0, ROWINFO_MAX*sizeof(RowInfo));
1125 ScTableInfo::~ScTableInfo()
1127 for( sal_uInt16 nIdx = 0; nIdx < ROWINFO_MAX; ++nIdx )
1128 delete [] mpRowInfo[ nIdx ].pCellInfo;
1129 delete [] mpRowInfo;
1132 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */