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