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