Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "scitems.hxx"
21 : #include <editeng/eeitem.hxx>
22 :
23 : #include "printfun.hxx"
24 :
25 : #include <svx/svxids.hrc>
26 : #include <editeng/adjustitem.hxx>
27 : #include <editeng/boxitem.hxx>
28 : #include <editeng/brushitem.hxx>
29 : #include <svtools/colorcfg.hxx>
30 : #include <editeng/editstat.hxx> // EE_CNTRL_RTFSTYLESHEETS
31 : #include <svx/fmview.hxx>
32 : #include <editeng/frmdiritem.hxx>
33 : #include <editeng/lrspitem.hxx>
34 : #include <editeng/paperinf.hxx>
35 : #include <editeng/pbinitem.hxx>
36 : #include <editeng/shaditem.hxx>
37 : #include <editeng/sizeitem.hxx>
38 : #include <svx/svdpagv.hxx>
39 : #include <editeng/ulspitem.hxx>
40 : #include <sfx2/app.hxx>
41 : #include <sfx2/printer.hxx>
42 : #include <tools/multisel.hxx>
43 : #include <sfx2/docfile.hxx>
44 : #include <tools/urlobj.hxx>
45 : #include <svx/xoutbmp.hxx>
46 :
47 : #include "editutil.hxx"
48 : #include "docsh.hxx"
49 : #include "output.hxx"
50 : #include "viewdata.hxx"
51 : #include "viewopti.hxx"
52 : #include "stlpool.hxx"
53 : #include "pagepar.hxx"
54 : #include "attrib.hxx"
55 : #include "patattr.hxx"
56 : #include "docpool.hxx"
57 : #include "dociter.hxx"
58 : #include "formulacell.hxx"
59 : #include "drawutil.hxx"
60 : #include "globstr.hrc"
61 : #include "scresid.hxx"
62 : #include "sc.hrc"
63 : #include "pagedata.hxx"
64 : #include "printopt.hxx"
65 : #include "prevloc.hxx"
66 : #include "scmod.hxx"
67 : #include "drwlayer.hxx"
68 : #include "fillinfo.hxx"
69 : #include "postit.hxx"
70 :
71 : #include <vcl/lineinfo.hxx>
72 :
73 : #include <boost/scoped_ptr.hpp>
74 : #include <com/sun/star/document/XDocumentProperties.hpp>
75 :
76 : #define ZOOM_MIN 10
77 :
78 : #define GET_BOOL(set,which) ((const SfxBoolItem&)(set)->Get((which))).GetValue()
79 : #define GET_USHORT(set,which) ((const SfxUInt16Item&)(set)->Get((which))).GetValue()
80 : #define GET_SHOW(set,which) ( VOBJ_MODE_SHOW == ScVObjMode( ((const ScViewObjectModeItem&)(set)->Get((which))).GetValue()) )
81 :
82 : //------------------------------------------------------------------------
83 :
84 0 : ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r)
85 : {
86 0 : nStartRow = r.nStartRow;
87 0 : nEndRow = r.nEndRow;
88 0 : nPagesX = r.nPagesX;
89 0 : if (r.pHidden && nPagesX)
90 : {
91 0 : pHidden = new sal_Bool[nPagesX];
92 0 : memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
93 : }
94 : else
95 0 : pHidden = NULL;
96 0 : }
97 :
98 0 : const ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r)
99 : {
100 0 : delete[] pHidden;
101 :
102 0 : nStartRow = r.nStartRow;
103 0 : nEndRow = r.nEndRow;
104 0 : nPagesX = r.nPagesX;
105 0 : if (r.pHidden && nPagesX)
106 : {
107 0 : pHidden = new sal_Bool[nPagesX];
108 0 : memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
109 : }
110 : else
111 0 : pHidden = NULL;
112 :
113 0 : return *this;
114 : }
115 :
116 83 : void ScPageRowEntry::SetPagesX(size_t nNew)
117 : {
118 83 : if (pHidden)
119 : {
120 : OSL_FAIL("SetPagesX nicht nach SetHidden");
121 0 : delete[] pHidden;
122 0 : pHidden = NULL;
123 : }
124 83 : nPagesX = nNew;
125 83 : }
126 :
127 0 : void ScPageRowEntry::SetHidden(size_t nX)
128 : {
129 0 : if ( nX < nPagesX )
130 : {
131 0 : if ( nX+1 == nPagesX ) // last page?
132 0 : --nPagesX;
133 : else
134 : {
135 0 : if (!pHidden)
136 : {
137 0 : pHidden = new sal_Bool[nPagesX];
138 0 : memset( pHidden, false, nPagesX * sizeof(sal_Bool) );
139 : }
140 0 : pHidden[nX] = sal_True;
141 : }
142 : }
143 0 : }
144 :
145 56 : sal_Bool ScPageRowEntry::IsHidden(size_t nX) const
146 : {
147 56 : return nX>=nPagesX || ( pHidden && pHidden[nX] ); //! inline?
148 : }
149 :
150 28 : size_t ScPageRowEntry::CountVisible() const
151 : {
152 28 : if ( pHidden )
153 : {
154 0 : size_t nVis = 0;
155 0 : for (size_t i=0; i<nPagesX; i++)
156 0 : if (!pHidden[i])
157 0 : ++nVis;
158 0 : return nVis;
159 : }
160 : else
161 28 : return nPagesX;
162 : }
163 :
164 : //------------------------------------------------------------------------
165 :
166 4792 : static long lcl_LineTotal(const ::editeng::SvxBorderLine* pLine)
167 : {
168 4792 : return pLine ? ( pLine->GetOutWidth() + pLine->GetInWidth() + pLine->GetDistance() ) : 0;
169 : }
170 :
171 236 : void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
172 : {
173 236 : pDocShell->UpdatePendingRowHeights( nPrintTab );
174 236 : pDoc = pDocShell->GetDocument();
175 :
176 236 : SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // use the printer, even for preview
177 236 : if (pDocPrinter)
178 236 : aOldPrinterMode = pDocPrinter->GetMapMode();
179 :
180 : // unified MapMode for all calls (e.g. Repaint!!!)
181 : // else, EditEngine outputs different text heights
182 236 : pDev->SetMapMode(MAP_PIXEL);
183 :
184 236 : pPageEndX = NULL;
185 236 : pPageEndY = NULL;
186 236 : pPageRows = NULL;
187 236 : pBorderItem = NULL;
188 236 : pBackgroundItem = NULL;
189 236 : pShadowItem = NULL;
190 :
191 236 : pEditEngine = NULL;
192 236 : pEditDefaults = NULL;
193 :
194 236 : ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
195 : SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
196 : pDoc->GetPageStyle( nPrintTab ),
197 236 : SFX_STYLE_FAMILY_PAGE );
198 236 : if (pStyleSheet)
199 236 : pParamSet = &pStyleSheet->GetItemSet();
200 : else
201 : {
202 : OSL_FAIL("Seitenvorlage nicht gefunden" );
203 0 : pParamSet = NULL;
204 : }
205 :
206 236 : if (!bState)
207 190 : nZoom = 100;
208 236 : nManualZoom = 100;
209 236 : bClearWin = false;
210 236 : bUseStyleColor = false;
211 236 : bIsRender = false;
212 :
213 236 : InitParam(pOptions);
214 :
215 236 : pPageData = NULL; // wird nur zur Initialisierung gebraucht
216 236 : }
217 :
218 162 : ScPrintFunc::ScPrintFunc( ScDocShell* pShell, SfxPrinter* pNewPrinter, SCTAB nTab,
219 : long nPage, long nDocP, const ScRange* pArea,
220 : const ScPrintOptions* pOptions,
221 : ScPageBreakData* pData )
222 : : pDocShell ( pShell ),
223 : pPrinter ( pNewPrinter ),
224 : pDrawView ( NULL ),
225 : nPrintTab ( nTab ),
226 : nPageStart ( nPage ),
227 : nDocPages ( nDocP ),
228 : pUserArea ( pArea ),
229 : bState ( false ),
230 : bSourceRangeValid ( false ),
231 : bPrintCurrentTable ( false ),
232 : bMultiArea ( false ),
233 : nTabPages ( 0 ),
234 : nTotalPages ( 0 ),
235 : nPagesX(0),
236 : nPagesY(0),
237 : nTotalY(0),
238 162 : pPageData ( pData )
239 : {
240 162 : pDev = pPrinter;
241 162 : aSrcOffset = pPrinter->PixelToLogic( pPrinter->GetPageOffsetPixel(), MAP_100TH_MM );
242 162 : Construct( pOptions );
243 162 : }
244 :
245 28 : ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, SCTAB nTab,
246 : long nPage, long nDocP, const ScRange* pArea,
247 : const ScPrintOptions* pOptions )
248 : : pDocShell ( pShell ),
249 : pPrinter ( NULL ),
250 : pDrawView ( NULL ),
251 : nPrintTab ( nTab ),
252 : nPageStart ( nPage ),
253 : nDocPages ( nDocP ),
254 : pUserArea ( pArea ),
255 : bState ( false ),
256 : bSourceRangeValid ( false ),
257 : bPrintCurrentTable ( false ),
258 : bMultiArea ( false ),
259 : nTabPages ( 0 ),
260 : nTotalPages ( 0 ),
261 : nPagesX(0),
262 : nPagesY(0),
263 : nTotalY(0),
264 28 : pPageData ( NULL )
265 : {
266 28 : pDev = pOutDev;
267 28 : Construct( pOptions );
268 28 : }
269 :
270 46 : ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell,
271 : const ScPrintState& rState, const ScPrintOptions* pOptions )
272 : : pDocShell ( pShell ),
273 : pPrinter ( NULL ),
274 : pDrawView ( NULL ),
275 : pUserArea ( NULL ),
276 : bSourceRangeValid ( false ),
277 : bPrintCurrentTable ( false ),
278 : bMultiArea ( false ),
279 : nPagesX(0),
280 : nPagesY(0),
281 : nTotalY(0),
282 46 : pPageData ( NULL )
283 : {
284 46 : pDev = pOutDev;
285 :
286 46 : nPrintTab = rState.nPrintTab;
287 46 : nStartCol = rState.nStartCol;
288 46 : nStartRow = rState.nStartRow;
289 46 : nEndCol = rState.nEndCol;
290 46 : nEndRow = rState.nEndRow;
291 46 : nZoom = rState.nZoom;
292 46 : nPagesX = rState.nPagesX;
293 46 : nPagesY = rState.nPagesY;
294 46 : nTabPages = rState.nTabPages;
295 46 : nTotalPages = rState.nTotalPages;
296 46 : nPageStart = rState.nPageStart;
297 46 : nDocPages = rState.nDocPages;
298 46 : bState = sal_True;
299 :
300 46 : Construct( pOptions );
301 46 : }
302 :
303 28 : void ScPrintFunc::GetPrintState( ScPrintState& rState )
304 : {
305 28 : rState.nPrintTab = nPrintTab;
306 28 : rState.nStartCol = nStartCol;
307 28 : rState.nStartRow = nStartRow;
308 28 : rState.nEndCol = nEndCol;
309 28 : rState.nEndRow = nEndRow;
310 28 : rState.nZoom = nZoom;
311 28 : rState.nPagesX = nPagesX;
312 28 : rState.nPagesY = nPagesY;
313 28 : rState.nTabPages = nTabPages;
314 28 : rState.nTotalPages = nTotalPages;
315 28 : rState.nPageStart = nPageStart;
316 28 : rState.nDocPages = nDocPages;
317 28 : }
318 :
319 0 : sal_Bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const
320 : {
321 0 : rRange = aLastSourceRange;
322 0 : return bSourceRangeValid;
323 : }
324 :
325 1 : void ScPrintFunc::FillPageData()
326 : {
327 1 : if (pPageData)
328 : {
329 1 : sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
330 1 : ScPrintRangeData& rData = pPageData->GetData(nCount); // count up
331 :
332 : rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab,
333 1 : nEndCol, nEndRow, nPrintTab ) );
334 1 : rData.SetPagesX( nPagesX, pPageEndX );
335 1 : rData.SetPagesY( nTotalY, pPageEndY );
336 :
337 : // Settings
338 1 : rData.SetTopDown( aTableParam.bTopDown );
339 1 : rData.SetAutomatic( !aAreaParam.bPrintArea );
340 : }
341 1 : }
342 :
343 472 : ScPrintFunc::~ScPrintFunc()
344 : {
345 236 : delete[] pPageEndX;
346 236 : delete[] pPageEndY;
347 236 : delete[] pPageRows;
348 236 : delete pEditDefaults;
349 236 : delete pEditEngine;
350 :
351 : // Printer settings are now restored from outside
352 :
353 : // For DrawingLayer/Charts, the MapMode of the printer (RefDevice) must always be correct
354 236 : SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // use Preview also for the printer
355 236 : if (pDocPrinter)
356 236 : pDocPrinter->SetMapMode(aOldPrinterMode);
357 236 : }
358 :
359 56 : void ScPrintFunc::SetDrawView( FmFormView* pNew )
360 : {
361 56 : pDrawView = pNew;
362 56 : }
363 :
364 36 : static void lcl_HidePrint( ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 )
365 : {
366 152 : for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++)
367 : {
368 116 : RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY];
369 481 : for (SCCOL nX=nX1; nX<=nX2; nX++)
370 : {
371 365 : const CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1];
372 365 : if (!rCellInfo.bEmptyCellText)
373 34 : if (((const ScProtectionAttr&)rCellInfo.pPatternAttr->
374 34 : GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet)).GetHidePrint())
375 : {
376 0 : pThisRowInfo->pCellInfo[nX+1].maCell.clear();
377 0 : pThisRowInfo->pCellInfo[nX+1].bEmptyCellText = true;
378 : }
379 : }
380 : }
381 36 : }
382 :
383 : //
384 : // output to Device (static)
385 : //
386 : // us used for:
387 : // - Clipboard/Bitmap
388 : // - Ole-Object (DocShell::Draw)
389 : // - Preview of templates
390 :
391 3 : void ScPrintFunc::DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double /* nPrintFactor */,
392 : const Rectangle& rBound, ScViewData* pViewData, sal_Bool bMetaFile )
393 : {
394 : //! evaluate nPrintFactor !!!
395 :
396 3 : SCTAB nTab = 0;
397 3 : if (pViewData)
398 3 : nTab = pViewData->GetTabNo();
399 :
400 : sal_Bool bDoGrid, bNullVal, bFormula;
401 3 : ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
402 3 : SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
403 3 : if (pStyleSheet)
404 : {
405 3 : SfxItemSet& rSet = pStyleSheet->GetItemSet();
406 3 : bDoGrid = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_GRID)).GetValue();
407 3 : bNullVal = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_NULLVALS)).GetValue();
408 3 : bFormula = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_FORMULAS)).GetValue();
409 : }
410 : else
411 : {
412 0 : const ScViewOptions& rOpt = pDoc->GetViewOptions();
413 0 : bDoGrid = rOpt.GetOption(VOPT_GRID);
414 0 : bNullVal = rOpt.GetOption(VOPT_NULLVALS);
415 0 : bFormula = rOpt.GetOption(VOPT_FORMULAS);
416 : }
417 :
418 3 : MapMode aMode = pDev->GetMapMode();
419 :
420 3 : Rectangle aRect = rBound;
421 :
422 3 : if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top())
423 0 : aRect = Rectangle( Point(), pDev->GetOutputSize() );
424 :
425 3 : SCCOL nX1 = 0;
426 3 : SCROW nY1 = 0;
427 3 : SCCOL nX2 = OLE_STD_CELLS_X - 1;
428 3 : SCROW nY2 = OLE_STD_CELLS_Y - 1;
429 3 : if (bMetaFile)
430 : {
431 3 : ScRange aRange = pDoc->GetRange( nTab, rBound );
432 3 : nX1 = aRange.aStart.Col();
433 3 : nY1 = aRange.aStart.Row();
434 3 : nX2 = aRange.aEnd.Col();
435 3 : nY2 = aRange.aEnd.Row();
436 : }
437 0 : else if (pViewData)
438 : {
439 0 : ScSplitPos eWhich = pViewData->GetActivePart();
440 0 : ScHSplitPos eHWhich = WhichH(eWhich);
441 0 : ScVSplitPos eVWhich = WhichV(eWhich);
442 0 : nX1 = pViewData->GetPosX(eHWhich);
443 0 : nY1 = pViewData->GetPosY(eVWhich);
444 0 : nX2 = nX1 + pViewData->VisibleCellsX(eHWhich);
445 0 : if (nX2>nX1) --nX2;
446 0 : nY2 = nY1 + pViewData->VisibleCellsY(eVWhich);
447 0 : if (nY2>nY1) --nY2;
448 : }
449 :
450 3 : if (nX1 > MAXCOL) nX1 = MAXCOL;
451 3 : if (nX2 > MAXCOL) nX2 = MAXCOL;
452 3 : if (nY1 > MAXROW) nY1 = MAXROW;
453 3 : if (nY2 > MAXROW) nY2 = MAXROW;
454 :
455 3 : long nDevSizeX = aRect.Right()-aRect.Left()+1;
456 3 : long nDevSizeY = aRect.Bottom()-aRect.Top()+1;
457 :
458 3 : Rectangle aLines;
459 3 : ScRange aRange( nX1,nY1,nTab, nX2,nY2,nTab );
460 :
461 3 : long nTwipsSizeX = 0;
462 15 : for (SCCOL i=nX1; i<=nX2; i++)
463 12 : nTwipsSizeX += pDoc->GetColWidth( i, nTab );
464 3 : long nTwipsSizeY = (long) pDoc->GetRowHeight( nY1, nY2, nTab );
465 :
466 : // if no lines, still space for the outline frame (20 Twips = 1pt)
467 : // (HasLines initalizes aLines to 0,0,0,0)
468 3 : nTwipsSizeX += aLines.Left() + std::max( aLines.Right(), 20L );
469 3 : nTwipsSizeY += aLines.Top() + std::max( aLines.Bottom(), 20L );
470 :
471 3 : double nScaleX = (double) nDevSizeX / nTwipsSizeX;
472 3 : double nScaleY = (double) nDevSizeY / nTwipsSizeY;
473 :
474 : //! hand over Flag at FillInfo !!!!!
475 3 : ScRange aERange;
476 3 : sal_Bool bEmbed = pDoc->IsEmbedded();
477 3 : if (bEmbed)
478 : {
479 0 : pDoc->GetEmbedded(aERange);
480 0 : pDoc->ResetEmbedded();
481 : }
482 :
483 : // Assemble data
484 :
485 6 : ScTableInfo aTabInfo;
486 : pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
487 3 : nScaleX, nScaleY, false, bFormula );
488 3 : lcl_HidePrint( aTabInfo, nX1, nX2 );
489 :
490 3 : if (bEmbed)
491 0 : pDoc->SetEmbedded(aERange);
492 :
493 3 : long nScrX = aRect.Left();
494 3 : long nScrY = aRect.Top();
495 :
496 : // If no lines, still leave space for grid lines
497 : // (would be elseways cut away)
498 3 : long nAddX = (long)( aLines.Left() * nScaleX );
499 3 : nScrX += ( nAddX ? nAddX : 1 );
500 3 : long nAddY = (long)( aLines.Top() * nScaleY );
501 3 : nScrY += ( nAddY ? nAddY : 1 );
502 :
503 : ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nTab,
504 6 : nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
505 3 : aOutputData.SetMetaFileMode(bMetaFile);
506 3 : aOutputData.SetShowNullValues(bNullVal);
507 3 : aOutputData.SetShowFormulas(bFormula);
508 :
509 : // #114135#
510 3 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
511 3 : FmFormView* pDrawView = NULL;
512 :
513 3 : if( pModel )
514 : {
515 3 : pDrawView = new FmFormView( pModel, pDev );
516 3 : pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
517 3 : pDrawView->SetPrintPreview( sal_True );
518 3 : aOutputData.SetDrawView( pDrawView );
519 : }
520 :
521 : //! SetUseStyleColor ??
522 :
523 3 : if ( bMetaFile && pDev->GetOutDevType() == OUTDEV_VIRDEV )
524 3 : aOutputData.SetSnapPixel();
525 :
526 3 : Point aLogStart = pDev->PixelToLogic( Point(nScrX,nScrY), MAP_100TH_MM );
527 3 : long nLogStX = aLogStart.X();
528 3 : long nLogStY = aLogStart.Y();
529 :
530 : //! nZoom for GetFont in OutputData ???
531 :
532 3 : if (!bMetaFile && pViewData)
533 0 : pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
534 :
535 : // #i72502#
536 3 : const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
537 3 : aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
538 :
539 3 : if (!bMetaFile && pViewData)
540 0 : pDev->SetMapMode(aMode);
541 :
542 3 : aOutputData.DrawBackground();
543 3 : aOutputData.DrawShadow();
544 3 : aOutputData.DrawFrame();
545 3 : aOutputData.DrawStrings();
546 :
547 3 : if (!bMetaFile && pViewData)
548 0 : pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
549 :
550 3 : aOutputData.DrawEdit(!bMetaFile);
551 :
552 3 : if (bDoGrid)
553 : {
554 0 : if (!bMetaFile && pViewData)
555 0 : pDev->SetMapMode(aMode);
556 :
557 0 : aOutputData.DrawGrid( sal_True, false ); // no page breaks
558 :
559 0 : pDev->SetLineColor( COL_BLACK );
560 :
561 0 : Size aOne = pDev->PixelToLogic( Size(1,1) );
562 0 : if (bMetaFile)
563 0 : aOne = Size(1,1); // compatible with DrawGrid
564 0 : long nRight = nScrX + aOutputData.GetScrW() - aOne.Width();
565 0 : long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height();
566 :
567 0 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
568 :
569 : // extra line at the left edge for left-to-right, right for right-to-left
570 0 : if ( bLayoutRTL )
571 0 : pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) );
572 : else
573 0 : pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) );
574 : // extra line at the top in both cases
575 0 : pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) );
576 : }
577 :
578 : // #i72502#
579 3 : aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
580 3 : aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
581 3 : aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
582 :
583 : // #114135#
584 6 : delete pDrawView;
585 3 : }
586 :
587 : //
588 : // Printing
589 : //
590 :
591 472 : static void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet )
592 : {
593 : // nDistance must be initialized differently before
594 :
595 472 : if ( pHFSet == NULL )
596 : {
597 0 : rParam.bEnable = false;
598 0 : rParam.pBorder = NULL;
599 0 : rParam.pBack = NULL;
600 0 : rParam.pShadow = NULL;
601 : }
602 : else
603 : {
604 472 : rParam.bEnable = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_ON)).GetValue();
605 472 : rParam.bDynamic = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_DYNAMIC)).GetValue();
606 472 : rParam.bShared = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_SHARED)).GetValue();
607 472 : rParam.nHeight = ((const SvxSizeItem&) pHFSet->Get(ATTR_PAGE_SIZE)).GetSize().Height();
608 472 : const SvxLRSpaceItem* pHFLR = &(const SvxLRSpaceItem&) pHFSet->Get(ATTR_LRSPACE);
609 : long nTmp;
610 472 : nTmp = pHFLR->GetLeft();
611 472 : rParam.nLeft = nTmp < 0 ? 0 : sal_uInt16(nTmp);
612 472 : nTmp = pHFLR->GetRight();
613 472 : rParam.nRight = nTmp < 0 ? 0 : sal_uInt16(nTmp);
614 472 : rParam.pBorder = (const SvxBoxItem*) &pHFSet->Get(ATTR_BORDER);
615 472 : rParam.pBack = (const SvxBrushItem*) &pHFSet->Get(ATTR_BACKGROUND);
616 472 : rParam.pShadow = (const SvxShadowItem*)&pHFSet->Get(ATTR_SHADOW);
617 :
618 : // now back in the dialog:
619 : // rParam.nHeight += rParam.nDistance; // not in the dialog any more ???
620 :
621 472 : if (rParam.pBorder)
622 472 : rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
623 472 : lcl_LineTotal( rParam.pBorder->GetBottom() );
624 :
625 472 : rParam.nManHeight = rParam.nHeight;
626 : }
627 :
628 472 : if (!rParam.bEnable)
629 4 : rParam.nHeight = 0;
630 472 : }
631 :
632 : // bNew = TRUE: search for used part of the document
633 : // bNew = FALSE: only limit whole lines/columns
634 :
635 234 : sal_Bool ScPrintFunc::AdjustPrintArea( sal_Bool bNew )
636 : {
637 234 : SCCOL nOldEndCol = nEndCol; // only important for !bNew
638 234 : SCROW nOldEndRow = nEndRow;
639 234 : sal_Bool bChangeCol = sal_True; // at bNew both are being adjusted
640 234 : sal_Bool bChangeRow = sal_True;
641 :
642 234 : sal_Bool bNotes = aTableParam.bNotes;
643 234 : if ( bNew )
644 : {
645 198 : nStartCol = 0;
646 198 : nStartRow = 0;
647 198 : if (!pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ))
648 166 : return false; // nix
649 : }
650 : else
651 : {
652 36 : sal_Bool bFound = sal_True;
653 36 : bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL );
654 36 : bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW );
655 36 : sal_Bool bForcedChangeRow = false;
656 :
657 : // #i53558# Crop entire column of old row limit to real print area with
658 : // some fuzzyness.
659 36 : if (!bChangeRow && nStartRow == 0)
660 : {
661 : SCROW nPAEndRow;
662 36 : bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nPAEndRow, bNotes );
663 : // Say we don't want to print more than ~1000 empty rows, which are
664 : // about 14 pages intentionally left blank..
665 36 : const SCROW nFuzzy = 23*42;
666 36 : if (nPAEndRow + nFuzzy < nEndRow)
667 : {
668 0 : bForcedChangeRow = sal_True;
669 0 : nEndRow = nPAEndRow;
670 : }
671 : else
672 36 : bFound = sal_True; // user seems to _want_ to print some empty rows
673 : }
674 : // TODO: in case we extend the number of columns we may have to do the
675 : // same for horizontal cropping.
676 :
677 36 : if ( bChangeCol && bChangeRow )
678 0 : bFound = pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes );
679 36 : else if ( bChangeCol )
680 0 : bFound = pDoc->GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol, bNotes );
681 36 : else if ( bChangeRow )
682 0 : bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes );
683 :
684 36 : if (!bFound)
685 0 : return false; // empty
686 :
687 36 : if (bForcedChangeRow)
688 0 : bChangeRow = sal_True;
689 : }
690 :
691 : pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab,
692 68 : false ); // no Refresh, incl. Attrs
693 :
694 68 : if ( bChangeCol )
695 : {
696 32 : OutputDevice* pRefDev = pDoc->GetPrinter(); // use the printer also for Preview
697 32 : pRefDev->SetMapMode( MAP_PIXEL ); // important for GetNeededSize
698 :
699 : pDoc->ExtendPrintArea( pRefDev,
700 32 : nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow );
701 : // changing nEndCol
702 : }
703 :
704 136 : if ( nEndCol < MAXCOL && pDoc->HasAttrib(
705 68 : nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_RIGHT ) )
706 0 : ++nEndCol;
707 136 : if ( nEndRow < MAXROW && pDoc->HasAttrib(
708 68 : nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_DOWN ) )
709 0 : ++nEndRow;
710 :
711 68 : if (!bChangeCol) nEndCol = nOldEndCol;
712 68 : if (!bChangeRow) nEndRow = nOldEndRow;
713 :
714 68 : return sal_True;
715 : }
716 :
717 3276 : long ScPrintFunc::TextHeight( const EditTextObject* pObject )
718 : {
719 3276 : if (!pObject)
720 546 : return 0;
721 :
722 2730 : pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
723 :
724 2730 : return (long) pEditEngine->GetTextHeight();
725 : }
726 :
727 : // nZoom must be set !!!
728 : // and the respective Twip-MapMode configured
729 :
730 496 : void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam )
731 : {
732 : OSL_ENSURE( aPageSize.Width(), "UpdateHFHeight ohne aPageSize");
733 :
734 496 : if (rParam.bEnable && rParam.bDynamic)
735 : {
736 : // calculate nHeight from content
737 :
738 490 : MakeEditEngine();
739 490 : long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin -
740 490 : rParam.nLeft - rParam.nRight ) * 100 / nZoom;
741 490 : if (rParam.pBorder)
742 980 : nPaperWidth -= ( rParam.pBorder->GetDistance(BOX_LINE_LEFT) +
743 980 : rParam.pBorder->GetDistance(BOX_LINE_RIGHT) +
744 980 : lcl_LineTotal(rParam.pBorder->GetLeft()) +
745 980 : lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom;
746 :
747 490 : if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
748 0 : nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SHADOW_LEFT) +
749 0 : rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT) ) * 100L / nZoom;
750 :
751 490 : pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) );
752 :
753 490 : long nMaxHeight = 0;
754 490 : if ( rParam.pLeft )
755 : {
756 490 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) );
757 490 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) );
758 490 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) );
759 : }
760 490 : if ( rParam.pRight )
761 : {
762 490 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) );
763 490 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) );
764 490 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) );
765 : }
766 :
767 490 : rParam.nHeight = nMaxHeight + rParam.nDistance;
768 490 : if (rParam.pBorder)
769 980 : rParam.nHeight += rParam.pBorder->GetDistance(BOX_LINE_TOP) +
770 980 : rParam.pBorder->GetDistance(BOX_LINE_BOTTOM) +
771 490 : lcl_LineTotal( rParam.pBorder->GetTop() ) +
772 490 : lcl_LineTotal( rParam.pBorder->GetBottom() );
773 490 : if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
774 0 : rParam.nHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
775 0 : rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
776 :
777 490 : if (rParam.nHeight < rParam.nManHeight)
778 490 : rParam.nHeight = rParam.nManHeight; // configured minimum
779 : }
780 496 : }
781 :
782 236 : void ScPrintFunc::InitParam( const ScPrintOptions* pOptions )
783 : {
784 236 : if (!pParamSet)
785 236 : return;
786 :
787 : // TabPage "Page"
788 236 : const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &pParamSet->Get( ATTR_LRSPACE );
789 : long nTmp;
790 236 : nTmp = pLRItem->GetLeft();
791 236 : nLeftMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
792 236 : nTmp = pLRItem->GetRight();
793 236 : nRightMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
794 236 : const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &pParamSet->Get( ATTR_ULSPACE );
795 236 : nTopMargin = pULItem->GetUpper();
796 236 : nBottomMargin = pULItem->GetLower();
797 :
798 236 : const SvxPageItem* pPageItem = (const SvxPageItem*) &pParamSet->Get( ATTR_PAGE );
799 236 : nPageUsage = pPageItem->GetPageUsage();
800 236 : bLandscape = pPageItem->IsLandscape();
801 236 : aFieldData.eNumType = pPageItem->GetNumType();
802 :
803 236 : bCenterHor = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_HORCENTER)).GetValue();
804 236 : bCenterVer = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_VERCENTER)).GetValue();
805 :
806 236 : aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
807 236 : if ( !aPageSize.Width() || !aPageSize.Height() )
808 : {
809 : OSL_FAIL("PageSize Null ?!?!?");
810 0 : aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
811 : }
812 :
813 236 : pBorderItem = (const SvxBoxItem*) &pParamSet->Get(ATTR_BORDER);
814 236 : pBackgroundItem = (const SvxBrushItem*) &pParamSet->Get(ATTR_BACKGROUND);
815 236 : pShadowItem = (const SvxShadowItem*) &pParamSet->Get(ATTR_SHADOW);
816 :
817 : // TabPage "Headline"
818 :
819 236 : aHdr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERLEFT); // Content
820 236 : aHdr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERRIGHT);
821 :
822 : const SvxSetItem* pHeaderSetItem;
823 236 : const SfxItemSet* pHeaderSet = NULL;
824 236 : if ( pParamSet->GetItemState( ATTR_PAGE_HEADERSET, false,
825 236 : (const SfxPoolItem**)&pHeaderSetItem ) == SFX_ITEM_SET )
826 : {
827 236 : pHeaderSet = &pHeaderSetItem->GetItemSet();
828 : // Headline has space below
829 236 : aHdr.nDistance = ((const SvxULSpaceItem&) pHeaderSet->Get(ATTR_ULSPACE)).GetLower();
830 : }
831 236 : lcl_FillHFParam( aHdr, pHeaderSet );
832 :
833 : // TabPage "Footline"
834 :
835 236 : aFtr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERLEFT); // Content
836 236 : aFtr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT);
837 :
838 : const SvxSetItem* pFooterSetItem;
839 236 : const SfxItemSet* pFooterSet = NULL;
840 236 : if ( pParamSet->GetItemState( ATTR_PAGE_FOOTERSET, false,
841 236 : (const SfxPoolItem**)&pFooterSetItem ) == SFX_ITEM_SET )
842 : {
843 236 : pFooterSet = &pFooterSetItem->GetItemSet();
844 : // Footline has space above
845 236 : aFtr.nDistance = ((const SvxULSpaceItem&) pFooterSet->Get(ATTR_ULSPACE)).GetUpper();
846 : }
847 236 : lcl_FillHFParam( aFtr, pFooterSet );
848 :
849 : //------------------------------------------------------
850 : // Compile Table-/Area-Params from single Items
851 : //------------------------------------------------------
852 : // TabPage "Table"
853 :
854 236 : const SfxUInt16Item* pScaleItem = NULL;
855 236 : const ScPageScaleToItem* pScaleToItem = NULL;
856 236 : const SfxUInt16Item* pScaleToPagesItem = NULL;
857 : SfxItemState eState;
858 :
859 : eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, false,
860 236 : (const SfxPoolItem**)&pScaleItem );
861 236 : if ( SFX_ITEM_DEFAULT == eState )
862 : pScaleItem = (const SfxUInt16Item*)
863 234 : &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE );
864 :
865 : eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, false,
866 236 : (const SfxPoolItem**)&pScaleToItem );
867 236 : if ( SFX_ITEM_DEFAULT == eState )
868 : pScaleToItem = (const ScPageScaleToItem*)
869 236 : &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO );
870 :
871 : eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, false,
872 236 : (const SfxPoolItem**)&pScaleToPagesItem );
873 236 : if ( SFX_ITEM_DEFAULT == eState )
874 : pScaleToPagesItem = (const SfxUInt16Item*)
875 236 : &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETOPAGES );
876 :
877 : OSL_ENSURE( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" );
878 :
879 236 : aTableParam.bCellContent = sal_True;
880 236 : aTableParam.bNotes = GET_BOOL(pParamSet,ATTR_PAGE_NOTES);
881 236 : aTableParam.bGrid = GET_BOOL(pParamSet,ATTR_PAGE_GRID);
882 236 : aTableParam.bHeaders = GET_BOOL(pParamSet,ATTR_PAGE_HEADERS);
883 236 : aTableParam.bFormulas = GET_BOOL(pParamSet,ATTR_PAGE_FORMULAS);
884 236 : aTableParam.bNullVals = GET_BOOL(pParamSet,ATTR_PAGE_NULLVALS);
885 236 : aTableParam.bCharts = GET_SHOW(pParamSet,ATTR_PAGE_CHARTS);
886 236 : aTableParam.bObjects = GET_SHOW(pParamSet,ATTR_PAGE_OBJECTS);
887 236 : aTableParam.bDrawings = GET_SHOW(pParamSet,ATTR_PAGE_DRAWINGS);
888 236 : aTableParam.bTopDown = GET_BOOL(pParamSet,ATTR_PAGE_TOPDOWN);
889 236 : aTableParam.bLeftRight = !aTableParam.bLeftRight;
890 236 : aTableParam.nFirstPageNo = GET_USHORT(pParamSet,ATTR_PAGE_FIRSTPAGENO);
891 236 : if (!aTableParam.nFirstPageNo)
892 10 : aTableParam.nFirstPageNo = (sal_uInt16) nPageStart; // from previous table
893 :
894 236 : if ( pScaleItem && pScaleToItem && pScaleToPagesItem )
895 : {
896 236 : sal_uInt16 nScaleAll = pScaleItem->GetValue();
897 236 : sal_uInt16 nScaleToPages = pScaleToPagesItem->GetValue();
898 :
899 236 : aTableParam.bScaleNone = (nScaleAll == 100);
900 236 : aTableParam.bScaleAll = (nScaleAll > 0 );
901 236 : aTableParam.bScaleTo = pScaleToItem->IsValid();
902 236 : aTableParam.bScalePageNum = (nScaleToPages > 0 );
903 236 : aTableParam.nScaleAll = nScaleAll;
904 236 : aTableParam.nScaleWidth = pScaleToItem->GetWidth();
905 236 : aTableParam.nScaleHeight = pScaleToItem->GetHeight();
906 236 : aTableParam.nScalePageNum = nScaleToPages;
907 : }
908 : else
909 : {
910 0 : aTableParam.bScaleNone = sal_True;
911 0 : aTableParam.bScaleAll = false;
912 0 : aTableParam.bScaleTo = false;
913 0 : aTableParam.bScalePageNum = false;
914 0 : aTableParam.nScaleAll = 0;
915 0 : aTableParam.nScaleWidth = 0;
916 0 : aTableParam.nScaleHeight = 0;
917 0 : aTableParam.nScalePageNum = 0;
918 : }
919 :
920 : // skip empty pages only if options with that flag are passed
921 236 : aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty();
922 236 : if ( pPageData )
923 1 : aTableParam.bSkipEmpty = false;
924 : // If pPageData is set, only the breaks are interesting for the
925 : // pagebreak preview, empty pages are not addressed separately.
926 :
927 : //------------------------------------------------------
928 : // TabPage "Parts":
929 : //------------------------------------------------------
930 :
931 : //! walk throuch all PrintAreas of the table !!!
932 236 : const ScRange* pPrintArea = pDoc->GetPrintRange( nPrintTab, 0 );
933 236 : const ScRange* pRepeatCol = pDoc->GetRepeatColRange( nPrintTab );
934 236 : const ScRange* pRepeatRow = pDoc->GetRepeatRowRange( nPrintTab );
935 :
936 : // ignoring ATTR_PAGE_PRINTTABLES
937 :
938 236 : if ( pUserArea ) // UserArea (selection) has prority
939 : {
940 : bPrintCurrentTable =
941 0 : aAreaParam.bPrintArea = sal_True; // Selection
942 0 : aAreaParam.aPrintArea = *pUserArea;
943 :
944 : // The table-query is already in DocShell::Print, here always
945 0 : aAreaParam.aPrintArea.aStart.SetTab(nPrintTab);
946 0 : aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab);
947 : }
948 236 : else if ( pDoc->HasPrintRange() )
949 : {
950 236 : if ( pPrintArea ) // at least one set?
951 : {
952 : bPrintCurrentTable =
953 2 : aAreaParam.bPrintArea = sal_True;
954 2 : aAreaParam.aPrintArea = *pPrintArea;
955 :
956 2 : bMultiArea = ( pDoc->GetPrintRangeCount(nPrintTab) > 1 );
957 : }
958 : else
959 : {
960 : // do not print hidden sheets with "Print entire sheet" flag
961 234 : bPrintCurrentTable = pDoc->IsPrintEntireSheet( nPrintTab ) && pDoc->IsVisible( nPrintTab );
962 234 : aAreaParam.bPrintArea = !bPrintCurrentTable; // otherwise the table is always counted
963 : }
964 : }
965 : else
966 : {
967 : // don't print hidden tables if there's no print range defined there
968 0 : if ( pDoc->IsVisible( nPrintTab ) )
969 : {
970 0 : aAreaParam.bPrintArea = false;
971 0 : bPrintCurrentTable = sal_True;
972 : }
973 : else
974 : {
975 0 : aAreaParam.bPrintArea = sal_True; // otherwise the table is always counted
976 0 : bPrintCurrentTable = false;
977 : }
978 : }
979 :
980 236 : if ( pRepeatCol )
981 : {
982 2 : aAreaParam.bRepeatCol = sal_True;
983 2 : aAreaParam.aRepeatCol = *pRepeatCol;
984 2 : nRepeatStartCol = pRepeatCol->aStart.Col();
985 2 : nRepeatEndCol = pRepeatCol->aEnd .Col();
986 : }
987 : else
988 : {
989 234 : aAreaParam.bRepeatCol = false;
990 234 : nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE;
991 : }
992 :
993 236 : if ( pRepeatRow )
994 : {
995 5 : aAreaParam.bRepeatRow = sal_True;
996 5 : aAreaParam.aRepeatRow = *pRepeatRow;
997 5 : nRepeatStartRow = pRepeatRow->aStart.Row();
998 5 : nRepeatEndRow = pRepeatRow->aEnd .Row();
999 : }
1000 : else
1001 : {
1002 231 : aAreaParam.bRepeatRow = false;
1003 231 : nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE;
1004 : }
1005 :
1006 : //
1007 : // Split pages
1008 : //
1009 :
1010 236 : if (!bState)
1011 : {
1012 190 : nTabPages = CountPages(); // also calculates zoom
1013 190 : nTotalPages = nTabPages;
1014 190 : nTotalPages += CountNotePages();
1015 : }
1016 : else
1017 : {
1018 46 : CalcPages(); // search breaks only
1019 46 : CountNotePages(); // Count notes, even if number of pages is already known
1020 : }
1021 :
1022 236 : if (nDocPages)
1023 56 : aFieldData.nTotalPages = nDocPages;
1024 : else
1025 180 : aFieldData.nTotalPages = nTotalPages;
1026 :
1027 236 : SetDateTime( Date( Date::SYSTEM ), Time( Time::SYSTEM ) );
1028 :
1029 236 : if( pDocShell->getDocProperties()->getTitle().getLength() != 0 )
1030 2 : aFieldData.aTitle = pDocShell->getDocProperties()->getTitle();
1031 : else
1032 234 : aFieldData.aTitle = pDocShell->GetTitle();
1033 :
1034 236 : const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
1035 236 : aFieldData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
1036 236 : if ( aFieldData.aLongDocName.Len() )
1037 158 : aFieldData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
1038 : else
1039 78 : aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle;
1040 :
1041 : // Printer settings (Orientation, Paper) at DoPrint
1042 : }
1043 :
1044 0 : Size ScPrintFunc::GetDataSize() const
1045 : {
1046 0 : Size aSize = aPageSize;
1047 0 : aSize.Width() -= nLeftMargin + nRightMargin;
1048 0 : aSize.Height() -= nTopMargin + nBottomMargin;
1049 0 : aSize.Height() -= aHdr.nHeight + aFtr.nHeight;
1050 0 : return aSize;
1051 : }
1052 :
1053 0 : void ScPrintFunc::GetScaleData( Size& rPhysSize, long& rDocHdr, long& rDocFtr )
1054 : {
1055 0 : rPhysSize = aPageSize;
1056 0 : rPhysSize.Width() -= nLeftMargin + nRightMargin;
1057 0 : rPhysSize.Height() -= nTopMargin + nBottomMargin;
1058 :
1059 0 : rDocHdr = aHdr.nHeight;
1060 0 : rDocFtr = aFtr.nHeight;
1061 0 : }
1062 :
1063 292 : void ScPrintFunc::SetDateTime( const Date& rDate, const Time& rTime )
1064 : {
1065 292 : aFieldData.aDate = rDate;
1066 292 : aFieldData.aTime = rTime;
1067 292 : }
1068 :
1069 0 : static void lcl_DrawGraphic( const Graphic &rGraphic, OutputDevice *pOut,
1070 : const Rectangle &rGrf, const Rectangle &rOut )
1071 : {
1072 0 : const bool bNotInside = !rOut.IsInside( rGrf );
1073 0 : if ( bNotInside )
1074 : {
1075 0 : pOut->Push();
1076 0 : pOut->IntersectClipRegion( rOut );
1077 : }
1078 :
1079 0 : ((Graphic&)rGraphic).Draw( pOut, rGrf.TopLeft(), rGrf.GetSize() );
1080 :
1081 0 : if ( bNotInside )
1082 0 : pOut->Pop();
1083 0 : }
1084 :
1085 0 : static void lcl_DrawGraphic( const SvxBrushItem &rBrush, OutputDevice *pOut, OutputDevice* pRefDev,
1086 : const Rectangle &rOrg, const Rectangle &rOut )
1087 : {
1088 0 : Size aGrfSize(0,0);
1089 0 : const Graphic *pGraphic = rBrush.GetGraphic();
1090 : SvxGraphicPosition ePos;
1091 0 : if ( pGraphic && pGraphic->IsSupportedGraphic() )
1092 : {
1093 0 : const MapMode aMapMM( MAP_100TH_MM );
1094 0 : if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1095 0 : aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM );
1096 : else
1097 : aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1098 0 : pGraphic->GetPrefMapMode(), aMapMM );
1099 0 : ePos = rBrush.GetGraphicPos();
1100 : }
1101 : else
1102 0 : ePos = GPOS_NONE;
1103 :
1104 0 : Point aPos;
1105 0 : Size aDrawSize = aGrfSize;
1106 :
1107 0 : bool bDraw = true;
1108 0 : switch ( ePos )
1109 : {
1110 0 : case GPOS_LT: aPos = rOrg.TopLeft();
1111 0 : break;
1112 0 : case GPOS_MT: aPos.Y() = rOrg.Top();
1113 0 : aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1114 0 : break;
1115 0 : case GPOS_RT: aPos.Y() = rOrg.Top();
1116 0 : aPos.X() = rOrg.Right() - aGrfSize.Width();
1117 0 : break;
1118 :
1119 0 : case GPOS_LM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1120 0 : aPos.X() = rOrg.Left();
1121 0 : break;
1122 0 : case GPOS_MM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1123 0 : aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1124 0 : break;
1125 0 : case GPOS_RM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1126 0 : aPos.X() = rOrg.Right() - aGrfSize.Width();
1127 0 : break;
1128 :
1129 0 : case GPOS_LB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1130 0 : aPos.X() = rOrg.Left();
1131 0 : break;
1132 0 : case GPOS_MB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1133 0 : aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1134 0 : break;
1135 0 : case GPOS_RB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1136 0 : aPos.X() = rOrg.Right() - aGrfSize.Width();
1137 0 : break;
1138 :
1139 : case GPOS_AREA:
1140 0 : aPos = rOrg.TopLeft();
1141 0 : aDrawSize = rOrg.GetSize();
1142 0 : break;
1143 : case GPOS_TILED:
1144 : {
1145 : // use GraphicObject::DrawTiled instead of an own loop
1146 : // (pixel rounding is handled correctly, and a very small bitmap
1147 : // is duplicated into a bigger one for better performance)
1148 :
1149 0 : GraphicObject aObject( *pGraphic );
1150 :
1151 0 : if( pOut->GetPDFWriter() &&
1152 0 : (aObject.GetType() == GRAPHIC_BITMAP || aObject.GetType() == GRAPHIC_DEFAULT) )
1153 : {
1154 : // For PDF export, every draw
1155 : // operation for bitmaps takes a noticeable
1156 : // amount of place (~50 characters). Thus,
1157 : // optimize between tile bitmap size and
1158 : // number of drawing operations here.
1159 : //
1160 : // A_out
1161 : // n_chars = k1 * ---------- + k2 * A_bitmap
1162 : // A_bitmap
1163 : //
1164 : // minimum n_chars is obtained for (derive for
1165 : // A_bitmap, set to 0, take positive
1166 : // solution):
1167 : // k1
1168 : // A_bitmap = Sqrt( ---- A_out )
1169 : // k2
1170 : //
1171 : // where k1 is the number of chars per draw
1172 : // operation, and k2 is the number of chars
1173 : // per bitmap pixel. This is approximately 50
1174 : // and 7 for current PDF writer, respectively.
1175 : //
1176 0 : const double k1( 50 );
1177 0 : const double k2( 7 );
1178 0 : const Size aSize( rOrg.GetSize() );
1179 0 : const double Abitmap( k1/k2 * aSize.Width()*aSize.Height() );
1180 :
1181 : aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0),
1182 : NULL, GRFMGR_DRAW_STANDARD,
1183 0 : ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
1184 : }
1185 : else
1186 : {
1187 0 : aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0) );
1188 : }
1189 :
1190 0 : bDraw = false;
1191 : }
1192 0 : break;
1193 :
1194 : case GPOS_NONE:
1195 0 : bDraw = false;
1196 0 : break;
1197 :
1198 : default: OSL_ENSURE( !pOut, "new Graphic position?" );
1199 : }
1200 0 : Rectangle aGrf( aPos,aDrawSize );
1201 0 : if ( bDraw && aGrf.IsOver( rOut ) )
1202 : {
1203 0 : lcl_DrawGraphic( *pGraphic, pOut, aGrf, rOut );
1204 : }
1205 0 : }
1206 :
1207 : // Rahmen wird nach innen gezeichnet
1208 :
1209 99 : void ScPrintFunc::DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH,
1210 : const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground,
1211 : const SvxShadowItem* pShadow )
1212 : {
1213 : //! direkte Ausgabe aus SvxBoxItem !!!
1214 :
1215 99 : if (pBorderData)
1216 198 : if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() &&
1217 99 : !pBorderData->GetRight() )
1218 99 : pBorderData = NULL;
1219 :
1220 99 : if (!pBorderData && !pBackground && !pShadow)
1221 0 : return; // nichts zu tun
1222 :
1223 99 : long nLeft = 0;
1224 99 : long nRight = 0;
1225 99 : long nTop = 0;
1226 99 : long nBottom = 0;
1227 :
1228 : // aFrameRect - ouside around frame, without shadow
1229 99 : if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1230 : {
1231 0 : nLeft += (long) ( pShadow->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
1232 0 : nRight += (long) ( pShadow->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
1233 0 : nTop += (long) ( pShadow->CalcShadowSpace(SHADOW_TOP) * nScaleY );
1234 0 : nBottom += (long) ( pShadow->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
1235 : }
1236 : Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop),
1237 99 : Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) );
1238 :
1239 : // center of frame, to paint lines through OutputData
1240 99 : if (pBorderData)
1241 : {
1242 0 : nLeft += (long) ( lcl_LineTotal(pBorderData->GetLeft()) * nScaleX / 2 );
1243 0 : nRight += (long) ( lcl_LineTotal(pBorderData->GetRight()) * nScaleX / 2 );
1244 0 : nTop += (long) ( lcl_LineTotal(pBorderData->GetTop()) * nScaleY / 2 );
1245 0 : nBottom += (long) ( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 );
1246 : }
1247 99 : long nEffHeight = nScrH - nTop - nBottom;
1248 99 : long nEffWidth = nScrW - nLeft - nRight;
1249 99 : if (nEffHeight<=0 || nEffWidth<=0)
1250 0 : return; // enmpty
1251 :
1252 99 : if ( pBackground )
1253 : {
1254 99 : if (pBackground->GetGraphicPos() != GPOS_NONE)
1255 : {
1256 : OutputDevice* pRefDev;
1257 0 : if ( bIsRender )
1258 0 : pRefDev = pDev; // don't use printer for PDF
1259 : else
1260 0 : pRefDev = pDoc->GetPrinter(); // use printer also for preview
1261 :
1262 0 : lcl_DrawGraphic( *pBackground, pDev, pRefDev, aFrameRect, aFrameRect );
1263 : }
1264 : else
1265 : {
1266 99 : pDev->SetFillColor(pBackground->GetColor());
1267 99 : pDev->SetLineColor();
1268 99 : pDev->DrawRect(aFrameRect);
1269 : }
1270 : }
1271 :
1272 99 : if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1273 : {
1274 0 : pDev->SetFillColor(pShadow->GetColor());
1275 0 : pDev->SetLineColor();
1276 0 : long nShadowX = (long) ( pShadow->GetWidth() * nScaleX );
1277 0 : long nShadowY = (long) ( pShadow->GetWidth() * nScaleY );
1278 0 : switch (pShadow->GetLocation())
1279 : {
1280 : case SVX_SHADOW_TOPLEFT:
1281 : pDev->DrawRect( Rectangle(
1282 0 : aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1283 0 : aFrameRect.Right()-nShadowX, aFrameRect.Top() ) );
1284 : pDev->DrawRect( Rectangle(
1285 0 : aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1286 0 : aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) );
1287 0 : break;
1288 : case SVX_SHADOW_TOPRIGHT:
1289 : pDev->DrawRect( Rectangle(
1290 0 : aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY,
1291 0 : aFrameRect.Right()+nShadowX, aFrameRect.Top() ) );
1292 : pDev->DrawRect( Rectangle(
1293 0 : aFrameRect.Right(), aFrameRect.Top()-nShadowY,
1294 0 : aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) );
1295 0 : break;
1296 : case SVX_SHADOW_BOTTOMLEFT:
1297 : pDev->DrawRect( Rectangle(
1298 0 : aFrameRect.Left()-nShadowX, aFrameRect.Bottom(),
1299 0 : aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) );
1300 : pDev->DrawRect( Rectangle(
1301 0 : aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY,
1302 0 : aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) );
1303 0 : break;
1304 : case SVX_SHADOW_BOTTOMRIGHT:
1305 : pDev->DrawRect( Rectangle(
1306 0 : aFrameRect.Left()+nShadowX, aFrameRect.Bottom(),
1307 0 : aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1308 : pDev->DrawRect( Rectangle(
1309 0 : aFrameRect.Right(), aFrameRect.Top()+nShadowY,
1310 0 : aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1311 0 : break;
1312 : default:
1313 : {
1314 : // added to avoid warnings
1315 : }
1316 : }
1317 : }
1318 :
1319 99 : if (pBorderData)
1320 : {
1321 0 : ScDocument* pBorderDoc = new ScDocument( SCDOCMODE_UNDO );
1322 0 : pBorderDoc->InitUndo( pDoc, 0,0, sal_True,sal_True );
1323 0 : if (pBorderData)
1324 0 : pBorderDoc->ApplyAttr( 0,0,0, *pBorderData );
1325 :
1326 0 : ScTableInfo aTabInfo;
1327 : pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0,
1328 0 : nScaleX, nScaleY, false, false );
1329 : OSL_ENSURE(aTabInfo.mnArrCount,"nArrCount == 0");
1330 :
1331 0 : aTabInfo.mpRowInfo[1].nHeight = (sal_uInt16) nEffHeight;
1332 0 : aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth =
1333 0 : aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = (sal_uInt16) nEffWidth;
1334 :
1335 : ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc, 0,
1336 0 : nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY );
1337 0 : aOutputData.SetUseStyleColor( bUseStyleColor );
1338 :
1339 0 : if (pBorderData)
1340 0 : aOutputData.DrawFrame();
1341 :
1342 0 : delete pBorderDoc;
1343 : }
1344 : }
1345 :
1346 6 : void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY )
1347 : {
1348 6 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1349 6 : long nLayoutSign = bLayoutRTL ? -1 : 1;
1350 :
1351 6 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1352 6 : long nOneX = aOnePixel.Width();
1353 6 : long nOneY = aOnePixel.Height();
1354 : SCCOL nCol;
1355 :
1356 6 : long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1357 6 : long nEndY = nScrY + nHeight - nOneY;
1358 :
1359 6 : long nPosX = nScrX;
1360 6 : if ( bLayoutRTL )
1361 : {
1362 0 : for (nCol=nX1; nCol<=nX2; nCol++)
1363 0 : nPosX += (long)( pDoc->GetColWidth( nCol, nPrintTab ) * nScaleX );
1364 : }
1365 : else
1366 6 : nPosX -= nOneX;
1367 6 : long nPosY = nScrY - nOneY;
1368 6 : String aText;
1369 :
1370 12 : for (nCol=nX1; nCol<=nX2; nCol++)
1371 : {
1372 6 : sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1373 6 : if (nDocW)
1374 : {
1375 6 : long nWidth = (long) (nDocW * nScaleX);
1376 6 : long nEndX = nPosX + nWidth * nLayoutSign;
1377 :
1378 6 : pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1379 :
1380 6 : aText = ::ScColToAlpha( nCol);
1381 6 : long nTextWidth = pDev->GetTextWidth(aText);
1382 6 : long nTextHeight = pDev->GetTextHeight();
1383 6 : long nAddX = ( nWidth - nTextWidth ) / 2;
1384 6 : long nAddY = ( nHeight - nTextHeight ) / 2;
1385 6 : long nTextPosX = nPosX+nAddX;
1386 6 : if ( bLayoutRTL )
1387 0 : nTextPosX -= nWidth;
1388 6 : pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText );
1389 :
1390 6 : nPosX = nEndX;
1391 : }
1392 6 : }
1393 6 : }
1394 :
1395 6 : void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY )
1396 : {
1397 6 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1398 6 : long nOneX = aOnePixel.Width();
1399 6 : long nOneY = aOnePixel.Height();
1400 :
1401 6 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1402 :
1403 6 : long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1404 6 : long nEndX = nScrX + nWidth;
1405 6 : long nPosX = nScrX;
1406 6 : if ( !bLayoutRTL )
1407 : {
1408 6 : nEndX -= nOneX;
1409 6 : nPosX -= nOneX;
1410 : }
1411 6 : long nPosY = nScrY - nOneY;
1412 6 : String aText;
1413 :
1414 12 : for (SCROW nRow=nY1; nRow<=nY2; nRow++)
1415 : {
1416 6 : sal_uInt16 nDocH = pDoc->GetRowHeight( nRow, nPrintTab );
1417 6 : if (nDocH)
1418 : {
1419 6 : long nHeight = (long) (nDocH * nScaleY);
1420 6 : long nEndY = nPosY + nHeight;
1421 :
1422 6 : pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1423 :
1424 6 : aText = OUString::number( nRow+1 );
1425 6 : long nTextWidth = pDev->GetTextWidth(aText);
1426 6 : long nTextHeight = pDev->GetTextHeight();
1427 6 : long nAddX = ( nWidth - nTextWidth ) / 2;
1428 6 : long nAddY = ( nHeight - nTextHeight ) / 2;
1429 6 : pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText );
1430 :
1431 6 : nPosY = nEndY;
1432 : }
1433 6 : }
1434 6 : }
1435 :
1436 2 : void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY,
1437 : sal_Bool bRepCol, ScPreviewLocationData& rLocationData )
1438 : {
1439 2 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1440 2 : long nOneX = aOnePixel.Width();
1441 2 : long nOneY = aOnePixel.Height();
1442 :
1443 2 : long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1444 2 : long nEndY = nScrY + nHeight - nOneY;
1445 :
1446 2 : long nPosX = nScrX - nOneX;
1447 4 : for (SCCOL nCol=nX1; nCol<=nX2; nCol++)
1448 : {
1449 2 : sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1450 2 : if (nDocW)
1451 2 : nPosX += (long) (nDocW * nScaleX);
1452 : }
1453 2 : Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY );
1454 2 : rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol );
1455 2 : }
1456 :
1457 2 : void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY,
1458 : sal_Bool bRepRow, ScPreviewLocationData& rLocationData )
1459 : {
1460 2 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1461 2 : long nOneX = aOnePixel.Width();
1462 2 : long nOneY = aOnePixel.Height();
1463 :
1464 2 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1465 :
1466 2 : long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1467 2 : long nEndX = nScrX + nWidth;
1468 2 : if ( !bLayoutRTL )
1469 2 : nEndX -= nOneX;
1470 :
1471 2 : long nPosY = nScrY - nOneY;
1472 2 : nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1473 2 : Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY );
1474 2 : rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow );
1475 2 : }
1476 :
1477 23 : void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1478 : long nScrX, long nScrY, sal_Bool bRepCol, sal_Bool bRepRow,
1479 : ScPreviewLocationData& rLocationData )
1480 : {
1481 : // get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer)
1482 :
1483 23 : Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1484 23 : long nLogStX = aLogPos.X();
1485 23 : long nLogStY = aLogPos.Y();
1486 :
1487 : SCCOL nCol;
1488 23 : Point aTwipOffset;
1489 23 : for (nCol=0; nCol<nX1; nCol++)
1490 0 : aTwipOffset.X() -= pDoc->GetColWidth( nCol, nPrintTab );
1491 23 : aTwipOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nPrintTab );
1492 :
1493 23 : Point aMMOffset( aTwipOffset );
1494 23 : aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS);
1495 23 : aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS);
1496 23 : aMMOffset += Point( nLogStX, nLogStY );
1497 23 : MapMode aDrawMapMode( MAP_100TH_MM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() );
1498 :
1499 : // get pixel rectangle
1500 :
1501 23 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1502 23 : long nOneX = aOnePixel.Width();
1503 23 : long nOneY = aOnePixel.Height();
1504 :
1505 23 : long nPosX = nScrX - nOneX;
1506 46 : for (nCol=nX1; nCol<=nX2; nCol++)
1507 : {
1508 23 : sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1509 23 : if (nDocW)
1510 23 : nPosX += (long) (nDocW * nScaleX);
1511 : }
1512 :
1513 23 : long nPosY = nScrY - nOneY;
1514 23 : nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1515 23 : Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY );
1516 : rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ),
1517 23 : bRepCol, bRepRow, aDrawMapMode );
1518 23 : }
1519 :
1520 33 : void ScPrintFunc::PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1521 : long nScrX, long nScrY,
1522 : sal_Bool bShLeft, sal_Bool bShTop, sal_Bool bShRight, sal_Bool bShBottom )
1523 : {
1524 : // #i47547# nothing to do if the end of the print area is before the end of
1525 : // the repeat columns/rows (don't use negative size for ScOutputData)
1526 33 : if ( nX2 < nX1 || nY2 < nY1 )
1527 33 : return;
1528 :
1529 : //! hand over Flag at FillInfo !!!!!
1530 33 : ScRange aERange;
1531 33 : sal_Bool bEmbed = pDoc->IsEmbedded();
1532 33 : if (bEmbed)
1533 : {
1534 0 : pDoc->GetEmbedded(aERange);
1535 0 : pDoc->ResetEmbedded();
1536 : }
1537 :
1538 33 : Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1539 33 : long nLogStX = aPos.X();
1540 33 : long nLogStY = aPos.Y();
1541 :
1542 : // Assemble data
1543 :
1544 33 : ScTableInfo aTabInfo;
1545 : pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab,
1546 33 : nScaleX, nScaleY, sal_True, aTableParam.bFormulas );
1547 33 : lcl_HidePrint( aTabInfo, nX1, nX2 );
1548 :
1549 33 : if (bEmbed)
1550 0 : pDoc->SetEmbedded(aERange);
1551 :
1552 : ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nPrintTab,
1553 66 : nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
1554 :
1555 : // #114135#
1556 33 : aOutputData.SetDrawView( pDrawView );
1557 :
1558 : // test if all paint parts are hidden, then a paint is not necessary at all
1559 33 : const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
1560 33 : const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart()
1561 33 : && pDrawView->getHideDraw() && pDrawView->getHideFormControl() );
1562 :
1563 33 : if(!bHideAllDrawingLayer)
1564 : {
1565 33 : pDev->SetMapMode(aLogicMode);
1566 : // don's set Clipping here (Mapmode is being moved)
1567 :
1568 : // #i72502#
1569 33 : aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
1570 : }
1571 :
1572 33 : pDev->SetMapMode(aOffsetMode);
1573 :
1574 33 : aOutputData.SetShowFormulas( aTableParam.bFormulas );
1575 33 : aOutputData.SetShowNullValues( aTableParam.bNullVals );
1576 33 : aOutputData.SetUseStyleColor( bUseStyleColor );
1577 :
1578 33 : Color aGridColor( COL_BLACK );
1579 33 : if ( bUseStyleColor )
1580 33 : aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
1581 33 : aOutputData.SetGridColor( aGridColor );
1582 :
1583 33 : if ( !pPrinter )
1584 : {
1585 33 : OutputDevice* pRefDev = pDoc->GetPrinter(); // use the printer also for Preview
1586 33 : Fraction aPrintFrac( nZoom, 100 ); // without nManualZoom
1587 : // MapMode, as it would arrive at the printer:
1588 33 : pRefDev->SetMapMode( MapMode( MAP_100TH_MM, Point(), aPrintFrac, aPrintFrac ) );
1589 :
1590 : // when rendering (PDF), don't use printer as ref device, but printer's MapMode
1591 : // has to be set anyway, as charts still use it (#106409#)
1592 33 : if ( !bIsRender )
1593 33 : aOutputData.SetRefDevice( pRefDev );
1594 : }
1595 :
1596 33 : if( aTableParam.bCellContent )
1597 33 : aOutputData.DrawBackground();
1598 :
1599 : pDev->SetClipRegion(Region(Rectangle(
1600 33 : aPos, Size(aOutputData.GetScrW(), aOutputData.GetScrH()))));
1601 33 : pDev->SetClipRegion();
1602 :
1603 33 : if( aTableParam.bCellContent )
1604 : {
1605 33 : aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom );
1606 33 : aOutputData.DrawFrame();
1607 33 : aOutputData.DrawStrings();
1608 33 : aOutputData.DrawEdit(false);
1609 : }
1610 :
1611 33 : if (aTableParam.bGrid)
1612 0 : aOutputData.DrawGrid( sal_True, false ); // no page breaks
1613 :
1614 33 : aOutputData.AddPDFNotes(); // has no effect if not rendering PDF with notes enabled
1615 :
1616 : // test if all paint parts are hidden, then a paint is not necessary at all
1617 33 : if(!bHideAllDrawingLayer)
1618 : {
1619 : // #i72502#
1620 33 : aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
1621 : }
1622 :
1623 : // #i72502#
1624 33 : aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
1625 66 : aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
1626 : }
1627 :
1628 56 : sal_Bool ScPrintFunc::IsMirror( long nPageNo ) // Mirror margins?
1629 : {
1630 56 : SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1631 56 : return ( eUsage == SVX_PAGE_MIRROR && (nPageNo & 1) );
1632 : }
1633 :
1634 112 : sal_Bool ScPrintFunc::IsLeft( long nPageNo ) // left foot notes?
1635 : {
1636 112 : SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1637 : sal_Bool bLeft;
1638 112 : if (eUsage == SVX_PAGE_LEFT)
1639 0 : bLeft = sal_True;
1640 112 : else if (eUsage == SVX_PAGE_RIGHT)
1641 0 : bLeft = false;
1642 : else
1643 112 : bLeft = (nPageNo & 1) != 0;
1644 112 : return bLeft;
1645 : }
1646 :
1647 56 : void ScPrintFunc::MakeTableString()
1648 : {
1649 56 : OUString aTmp;
1650 56 : pDoc->GetName(nPrintTab, aTmp);
1651 56 : aFieldData.aTabName = aTmp;
1652 56 : }
1653 :
1654 602 : void ScPrintFunc::MakeEditEngine()
1655 : {
1656 602 : if (!pEditEngine)
1657 : {
1658 : // can't use document's edit engine pool here,
1659 : // because pool must have twips as default metric
1660 234 : pEditEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), sal_True );
1661 :
1662 234 : pEditEngine->EnableUndo(false);
1663 : //fdo#45869 we want text to be positioned as it would be for the the
1664 : //high dpi printed output, not as would be ideal for the 96dpi preview
1665 : //window itself
1666 234 : pEditEngine->SetRefDevice(pPrinter ? pPrinter : pDoc->GetRefDevice());
1667 : pEditEngine->SetWordDelimiters(
1668 234 : ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
1669 234 : pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
1670 234 : pDoc->ApplyAsianEditSettings( *pEditEngine );
1671 234 : pEditEngine->EnableAutoColor( bUseStyleColor );
1672 :
1673 : // Default-Set for alignment
1674 234 : pEditDefaults = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
1675 :
1676 234 : const ScPatternAttr& rPattern = (const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN);
1677 234 : rPattern.FillEditItemSet( pEditDefaults );
1678 : // FillEditItemSet adjusts font height to 1/100th mm,
1679 : // but for header/footer twips is needed, as in the PatternAttr:
1680 234 : pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
1681 234 : pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
1682 234 : pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
1683 : // dont use font color, because background color is not used
1684 : //! there's no way to set the background for note pages
1685 234 : pEditDefaults->ClearItem( EE_CHAR_COLOR );
1686 234 : if (ScGlobal::IsSystemRTL())
1687 0 : pEditDefaults->Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
1688 : }
1689 :
1690 602 : pEditEngine->SetData( aFieldData ); // Set page count etc.
1691 602 : }
1692 :
1693 : // nStartY = logic
1694 112 : void ScPrintFunc::PrintHF( long nPageNo, sal_Bool bHeader, long nStartY,
1695 : sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1696 : {
1697 112 : const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr;
1698 :
1699 112 : pDev->SetMapMode( aTwipMode ); // Head-/Footlines in Twips
1700 :
1701 112 : sal_Bool bLeft = IsLeft(nPageNo) && !rParam.bShared;
1702 112 : const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight;
1703 :
1704 112 : long nLineStartX = aPageRect.Left() + rParam.nLeft;
1705 112 : long nLineEndX = aPageRect.Right() - rParam.nRight;
1706 112 : long nLineWidth = nLineEndX - nLineStartX + 1;
1707 :
1708 : // Edit-Engine
1709 :
1710 112 : Point aStart( nLineStartX, nStartY );
1711 112 : Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1712 112 : if ( rParam.pBorder )
1713 : {
1714 112 : long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(BOX_LINE_LEFT);
1715 112 : long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(BOX_LINE_TOP);
1716 112 : aStart.X() += nLeft;
1717 112 : aStart.Y() += nTop;
1718 112 : aPaperSize.Width() -= nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(BOX_LINE_RIGHT);
1719 112 : aPaperSize.Height() -= nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
1720 : }
1721 :
1722 112 : if ( rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE )
1723 : {
1724 0 : long nLeft = rParam.pShadow->CalcShadowSpace(SHADOW_LEFT);
1725 0 : long nTop = rParam.pShadow->CalcShadowSpace(SHADOW_TOP);
1726 0 : aStart.X() += nLeft;
1727 0 : aStart.Y() += nTop;
1728 0 : aPaperSize.Width() -= nLeft + rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT);
1729 0 : aPaperSize.Height() -= nTop + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
1730 : }
1731 :
1732 112 : aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo;
1733 112 : MakeEditEngine();
1734 :
1735 112 : pEditEngine->SetPaperSize(aPaperSize);
1736 :
1737 : // Frame / Background
1738 :
1739 112 : Point aBorderStart( nLineStartX, nStartY );
1740 112 : Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1741 112 : if ( rParam.bDynamic )
1742 : {
1743 : // adjust here again, for even/odd head-/footlines
1744 : // and probably other breaks by variable (page number etc.)
1745 :
1746 112 : long nMaxHeight = 0;
1747 112 : nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) );
1748 112 : nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) );
1749 112 : nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) );
1750 112 : if (rParam.pBorder)
1751 224 : nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
1752 224 : lcl_LineTotal( rParam.pBorder->GetBottom() ) +
1753 224 : rParam.pBorder->GetDistance(BOX_LINE_TOP) +
1754 224 : rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
1755 112 : if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
1756 0 : nMaxHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
1757 0 : rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
1758 :
1759 112 : if (nMaxHeight < rParam.nManHeight-rParam.nDistance)
1760 112 : nMaxHeight = rParam.nManHeight-rParam.nDistance; // configured Minimum
1761 :
1762 112 : aBorderSize.Height() = nMaxHeight;
1763 : }
1764 :
1765 112 : if ( bDoPrint )
1766 : {
1767 66 : double nOldScaleX = nScaleX;
1768 66 : double nOldScaleY = nScaleY;
1769 66 : nScaleX = nScaleY = 1.0; // output directly in Twips
1770 264 : DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(),
1771 330 : rParam.pBorder, rParam.pBack, rParam.pShadow );
1772 66 : nScaleX = nOldScaleX;
1773 66 : nScaleY = nOldScaleY;
1774 :
1775 : // Clipping for Text
1776 :
1777 66 : pDev->SetClipRegion(Region(Rectangle(aStart, aPaperSize)));
1778 :
1779 : // left
1780 :
1781 66 : const EditTextObject* pObject = pHFItem->GetLeftArea();
1782 66 : if (pObject)
1783 : {
1784 66 : pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1785 66 : pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1786 66 : Point aDraw = aStart;
1787 66 : long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1788 66 : if (nDif > 0)
1789 66 : aDraw.Y() += nDif / 2;
1790 66 : pEditEngine->Draw( pDev, aDraw, 0 );
1791 : }
1792 :
1793 : // center
1794 :
1795 66 : pObject = pHFItem->GetCenterArea();
1796 66 : if (pObject)
1797 : {
1798 66 : pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
1799 66 : pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1800 66 : Point aDraw = aStart;
1801 66 : long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1802 66 : if (nDif > 0)
1803 66 : aDraw.Y() += nDif / 2;
1804 66 : pEditEngine->Draw( pDev, aDraw, 0 );
1805 : }
1806 :
1807 : // right
1808 :
1809 66 : pObject = pHFItem->GetRightArea();
1810 66 : if (pObject)
1811 : {
1812 66 : pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
1813 66 : pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1814 66 : Point aDraw = aStart;
1815 66 : long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1816 66 : if (nDif > 0)
1817 66 : aDraw.Y() += nDif / 2;
1818 66 : pEditEngine->Draw( pDev, aDraw, 0 );
1819 : }
1820 :
1821 66 : pDev->SetClipRegion();
1822 : }
1823 :
1824 112 : if ( pLocationData )
1825 : {
1826 46 : Rectangle aHeaderRect( aBorderStart, aBorderSize );
1827 46 : pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft );
1828 : }
1829 112 : }
1830 :
1831 0 : long ScPrintFunc::DoNotes( long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1832 : {
1833 0 : if (bDoPrint)
1834 0 : pDev->SetMapMode(aTwipMode);
1835 :
1836 0 : MakeEditEngine();
1837 0 : pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1838 0 : pEditEngine->SetDefaults( *pEditDefaults );
1839 :
1840 0 : Font aMarkFont;
1841 0 : ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
1842 0 : ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).GetFont( aMarkFont, eColorMode );
1843 0 : pDev->SetFont( aMarkFont );
1844 0 : long nMarkLen = pDev->GetTextWidth(OUString("GW99999:"));
1845 : // without Space-Char, because it rarle arrives there
1846 :
1847 0 : Size aDataSize = aPageRect.GetSize();
1848 0 : if ( nMarkLen > aDataSize.Width() / 2 ) // everything much too small?
1849 0 : nMarkLen = aDataSize.Width() / 2; // split the page appropriately
1850 0 : aDataSize.Width() -= nMarkLen;
1851 :
1852 0 : pEditEngine->SetPaperSize( aDataSize );
1853 0 : long nPosX = aPageRect.Left() + nMarkLen;
1854 0 : long nPosY = aPageRect.Top();
1855 :
1856 0 : long nCount = 0;
1857 0 : long nSize = aNotePosList.size();
1858 : sal_Bool bOk;
1859 0 : do
1860 : {
1861 0 : bOk = false;
1862 0 : if ( nNoteStart + nCount < nSize)
1863 : {
1864 0 : ScAddress &rPos = aNotePosList[ nNoteStart + nCount ];
1865 :
1866 0 : if( const ScPostIt* pNote = pDoc->GetNotes(rPos.Tab())->findByAddress( rPos ) )
1867 : {
1868 0 : if(const EditTextObject *pEditText = pNote->GetEditTextObject())
1869 0 : pEditEngine->SetText(*pEditText);
1870 0 : long nTextHeight = pEditEngine->GetTextHeight();
1871 0 : if ( nPosY + nTextHeight < aPageRect.Bottom() )
1872 : {
1873 0 : if (bDoPrint)
1874 : {
1875 0 : pEditEngine->Draw( pDev, Point( nPosX, nPosY ), 0 );
1876 :
1877 0 : String aMarkStr;
1878 0 : rPos.Format( aMarkStr, SCA_VALID, pDoc, pDoc->GetAddressConvention() );
1879 0 : aMarkStr += ':';
1880 :
1881 : // cell position also via EditEngine, for correct positioning
1882 0 : pEditEngine->SetText(aMarkStr);
1883 0 : pEditEngine->Draw( pDev, Point( aPageRect.Left(), nPosY ), 0 );
1884 : }
1885 :
1886 0 : if ( pLocationData )
1887 : {
1888 0 : Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) );
1889 0 : pLocationData->AddNoteText( aTextRect, rPos );
1890 0 : Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) );
1891 0 : pLocationData->AddNoteMark( aMarkRect, rPos );
1892 : }
1893 :
1894 0 : nPosY += nTextHeight;
1895 0 : nPosY += 200; // Distance
1896 0 : ++nCount;
1897 0 : bOk = sal_True;
1898 : }
1899 : }
1900 : }
1901 : }
1902 : while (bOk);
1903 :
1904 0 : return nCount;
1905 : }
1906 :
1907 66 : long ScPrintFunc::PrintNotes( long nPageNo, long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1908 : {
1909 66 : if ( nNoteStart >= (long) aNotePosList.size() || !aTableParam.bNotes )
1910 66 : return 0;
1911 :
1912 0 : if ( bDoPrint && bClearWin )
1913 : {
1914 : //! aggregate PrintPage !!!
1915 :
1916 0 : Color aBackgroundColor( COL_WHITE );
1917 0 : if ( bUseStyleColor )
1918 0 : aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1919 :
1920 0 : pDev->SetMapMode(aOffsetMode);
1921 0 : pDev->SetLineColor();
1922 0 : pDev->SetFillColor(aBackgroundColor);
1923 : pDev->DrawRect(Rectangle(Point(),
1924 0 : Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
1925 0 : (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
1926 : }
1927 :
1928 :
1929 : // adjust aPageRect for left/right page
1930 :
1931 0 : Rectangle aTempRect = Rectangle( Point(), aPageSize );
1932 0 : if (IsMirror(nPageNo))
1933 : {
1934 0 : aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
1935 0 : aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
1936 : }
1937 : else
1938 : {
1939 0 : aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
1940 0 : aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
1941 : }
1942 :
1943 0 : if ( pPrinter && bDoPrint )
1944 : {
1945 : OSL_FAIL( "StartPage does not exist anymore" );
1946 : }
1947 :
1948 0 : if ( bDoPrint || pLocationData )
1949 : {
1950 : // Head and foot lines
1951 :
1952 0 : if (aHdr.bEnable)
1953 : {
1954 0 : long nHeaderY = aPageRect.Top()-aHdr.nHeight;
1955 0 : PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
1956 : }
1957 0 : if (aFtr.bEnable)
1958 : {
1959 0 : long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
1960 0 : PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
1961 : }
1962 : }
1963 :
1964 0 : long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData );
1965 :
1966 0 : if ( pPrinter && bDoPrint )
1967 : {
1968 : OSL_FAIL( "EndPage does not exist anymore" );
1969 : }
1970 :
1971 0 : return nCount;
1972 : }
1973 :
1974 56 : void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1975 : sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1976 : {
1977 56 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1978 56 : long nLayoutSign = bLayoutRTL ? -1 : 1;
1979 :
1980 : // nPageNo is the page number within all sheets of one "start page" setting
1981 :
1982 56 : if ( bClearWin && bDoPrint )
1983 : {
1984 : // must exactly fit to painting the frame in preview.cxx !!!
1985 :
1986 33 : Color aBackgroundColor( COL_WHITE );
1987 33 : if ( bUseStyleColor )
1988 33 : aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1989 :
1990 33 : pDev->SetMapMode(aOffsetMode);
1991 33 : pDev->SetLineColor();
1992 33 : pDev->SetFillColor(aBackgroundColor);
1993 : pDev->DrawRect(Rectangle(Point(),
1994 33 : Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
1995 66 : (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
1996 : }
1997 :
1998 :
1999 : // adjust aPageRect for left/right page
2000 :
2001 56 : Rectangle aTempRect = Rectangle( Point(), aPageSize );
2002 56 : if (IsMirror(nPageNo))
2003 : {
2004 0 : aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
2005 0 : aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
2006 : }
2007 : else
2008 : {
2009 56 : aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
2010 56 : aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
2011 : }
2012 :
2013 56 : if ( aAreaParam.bRepeatCol )
2014 0 : if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol )
2015 0 : nX1 = nRepeatEndCol + 1;
2016 56 : sal_Bool bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol);
2017 56 : if ( aAreaParam.bRepeatRow )
2018 0 : if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow )
2019 0 : nY1 = nRepeatEndRow + 1;
2020 56 : sal_Bool bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow);
2021 :
2022 : // use new object hide flags in SdrPaintView
2023 56 : if(pDrawView)
2024 : {
2025 56 : pDrawView->setHideOle(!aTableParam.bObjects);
2026 56 : pDrawView->setHideChart(!aTableParam.bCharts);
2027 56 : pDrawView->setHideDraw(!aTableParam.bDrawings);
2028 56 : pDrawView->setHideFormControl(!aTableParam.bDrawings);
2029 : }
2030 :
2031 56 : if ( pPrinter && bDoPrint )
2032 : {
2033 : OSL_FAIL( "StartPage does not exist anymore" );
2034 : }
2035 :
2036 : // head and foot lines (without centering)
2037 :
2038 56 : if (aHdr.bEnable)
2039 : {
2040 56 : long nHeaderY = aPageRect.Top()-aHdr.nHeight;
2041 56 : PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
2042 : }
2043 56 : if (aFtr.bEnable)
2044 : {
2045 56 : long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
2046 56 : PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
2047 : }
2048 :
2049 : // Position ( margins / centering )
2050 :
2051 56 : long nLeftSpace = aPageRect.Left(); // Document-Twips
2052 56 : long nTopSpace = aPageRect.Top();
2053 56 : if ( bCenterHor || bLayoutRTL )
2054 : {
2055 0 : long nDataWidth = 0;
2056 : SCCOL i;
2057 0 : for (i=nX1; i<=nX2; i++)
2058 0 : nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2059 0 : if (bDoRepCol)
2060 0 : for (i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2061 0 : nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2062 0 : if (aTableParam.bHeaders)
2063 0 : nDataWidth += (long) PRINT_HEADER_WIDTH;
2064 0 : if (pBorderItem)
2065 0 : nDataWidth += pBorderItem->GetDistance(BOX_LINE_LEFT) +
2066 0 : pBorderItem->GetDistance(BOX_LINE_RIGHT); //! Line width?
2067 0 : if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2068 0 : nDataWidth += pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
2069 0 : pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
2070 0 : if ( bCenterHor )
2071 : {
2072 0 : nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2; // LTR or RTL
2073 0 : if (pBorderItem)
2074 0 : nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft());
2075 : }
2076 0 : else if ( bLayoutRTL )
2077 0 : nLeftSpace += aPageRect.GetWidth() - nDataWidth; // align to the right edge of the page
2078 : }
2079 56 : if ( bCenterVer )
2080 : {
2081 0 : long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab);
2082 0 : if (bDoRepRow)
2083 : nDataHeight += pDoc->GetRowHeight( nRepeatStartRow,
2084 0 : nRepeatEndRow, nPrintTab);
2085 0 : if (aTableParam.bHeaders)
2086 0 : nDataHeight += (long) PRINT_HEADER_HEIGHT;
2087 0 : if (pBorderItem)
2088 0 : nDataHeight += pBorderItem->GetDistance(BOX_LINE_TOP) +
2089 0 : pBorderItem->GetDistance(BOX_LINE_BOTTOM); //! Line width?
2090 0 : if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2091 0 : nDataHeight += pShadowItem->CalcShadowSpace(SHADOW_TOP) +
2092 0 : pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
2093 0 : nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2;
2094 0 : if (pBorderItem)
2095 0 : nTopSpace -= lcl_LineTotal(pBorderItem->GetTop());
2096 : }
2097 :
2098 : // calculate sizes of the elements for partitioning
2099 : // (header, repeat, data)
2100 :
2101 56 : long nHeaderWidth = 0;
2102 56 : long nHeaderHeight = 0;
2103 56 : long nRepeatWidth = 0;
2104 56 : long nRepeatHeight = 0;
2105 56 : long nContentWidth = 0; // scaled - not the same as nDataWidth above
2106 56 : long nContentHeight = 0;
2107 56 : if (aTableParam.bHeaders)
2108 : {
2109 8 : nHeaderWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
2110 8 : nHeaderHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
2111 : }
2112 56 : if (bDoRepCol)
2113 0 : for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2114 0 : nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2115 56 : if (bDoRepRow)
2116 : nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow,
2117 0 : nRepeatEndRow, nPrintTab, nScaleY);
2118 112 : for (SCCOL i=nX1; i<=nX2; i++)
2119 56 : nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2120 : nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab,
2121 56 : nScaleY);
2122 :
2123 : // partition the page
2124 :
2125 56 : long nStartX = ((long) ( nLeftSpace * nScaleX ));
2126 56 : long nStartY = ((long) ( nTopSpace * nScaleY ));
2127 56 : long nInnerStartX = nStartX;
2128 56 : long nInnerStartY = nStartY;
2129 56 : if (pBorderItem)
2130 : {
2131 112 : nInnerStartX += (long) ( ( lcl_LineTotal(pBorderItem->GetLeft()) +
2132 112 : pBorderItem->GetDistance(BOX_LINE_LEFT) ) * nScaleX );
2133 112 : nInnerStartY += (long) ( ( lcl_LineTotal(pBorderItem->GetTop()) +
2134 112 : pBorderItem->GetDistance(BOX_LINE_TOP) ) * nScaleY );
2135 : }
2136 56 : if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2137 : {
2138 0 : nInnerStartX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
2139 0 : nInnerStartY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_TOP) * nScaleY );
2140 : }
2141 :
2142 56 : if ( bLayoutRTL )
2143 : {
2144 : // arrange elements starting from the right edge
2145 0 : nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth;
2146 :
2147 : // make rounding easier so the elements are really next to each other in preview
2148 0 : Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode );
2149 0 : long nOffsetOneX = aOffsetOnePixel.Width();
2150 0 : nInnerStartX += nOffsetOneX / 2;
2151 : }
2152 :
2153 56 : long nFrameStartX = nInnerStartX;
2154 56 : long nFrameStartY = nInnerStartY;
2155 :
2156 56 : long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign; // widths/heights are 0 if not used
2157 56 : long nRepStartY = nInnerStartY + nHeaderHeight;
2158 56 : long nDataX = nRepStartX + nRepeatWidth * nLayoutSign;
2159 56 : long nDataY = nRepStartY + nRepeatHeight;
2160 56 : long nEndX = nDataX + nContentWidth * nLayoutSign;
2161 56 : long nEndY = nDataY + nContentHeight;
2162 56 : long nFrameEndX = nEndX;
2163 56 : long nFrameEndY = nEndY;
2164 :
2165 56 : if ( bLayoutRTL )
2166 : {
2167 : // each element's start position is its left edge
2168 : //! subtract one pixel less?
2169 0 : nInnerStartX -= nHeaderWidth; // used for header
2170 0 : nRepStartX -= nRepeatWidth;
2171 0 : nDataX -= nContentWidth;
2172 :
2173 : // continue right of the main elements again
2174 0 : nEndX += nHeaderWidth + nRepeatWidth + nContentWidth;
2175 : }
2176 :
2177 : // Page frame / background
2178 :
2179 : //! adjust nEndX/Y
2180 :
2181 56 : long nBorderEndX = nEndX;
2182 56 : long nBorderEndY = nEndY;
2183 56 : if (pBorderItem)
2184 : {
2185 112 : nBorderEndX += (long) ( ( lcl_LineTotal(pBorderItem->GetRight()) +
2186 112 : pBorderItem->GetDistance(BOX_LINE_RIGHT) ) * nScaleX );
2187 112 : nBorderEndY += (long) ( ( lcl_LineTotal(pBorderItem->GetBottom()) +
2188 112 : pBorderItem->GetDistance(BOX_LINE_BOTTOM) ) * nScaleY );
2189 : }
2190 56 : if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2191 : {
2192 0 : nBorderEndX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
2193 0 : nBorderEndY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
2194 : }
2195 :
2196 56 : if ( bDoPrint )
2197 : {
2198 33 : pDev->SetMapMode( aOffsetMode );
2199 : DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY,
2200 33 : pBorderItem, pBackgroundItem, pShadowItem );
2201 :
2202 33 : pDev->SetMapMode( aTwipMode );
2203 : }
2204 :
2205 56 : pDev->SetMapMode( aOffsetMode );
2206 :
2207 : // Output repeating rows/columns
2208 :
2209 56 : if (bDoRepCol && bDoRepRow)
2210 : {
2211 0 : if ( bDoPrint )
2212 : PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2213 0 : nRepStartX,nRepStartY, sal_True,sal_True,false,false );
2214 0 : if ( pLocationData )
2215 : LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2216 0 : nRepStartX,nRepStartY, sal_True,sal_True, *pLocationData );
2217 : }
2218 56 : if (bDoRepCol)
2219 : {
2220 0 : if ( bDoPrint )
2221 : PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY,
2222 0 : sal_True,!bDoRepRow,false,sal_True );
2223 0 : if ( pLocationData )
2224 0 : LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, sal_True,false, *pLocationData );
2225 : }
2226 56 : if (bDoRepRow)
2227 : {
2228 0 : if ( bDoPrint )
2229 : PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY,
2230 0 : !bDoRepCol,sal_True,sal_True,false );
2231 0 : if ( pLocationData )
2232 0 : LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, false,sal_True, *pLocationData );
2233 : }
2234 :
2235 : // output data
2236 :
2237 56 : if ( bDoPrint )
2238 33 : PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow,sal_True,sal_True );
2239 56 : if ( pLocationData )
2240 23 : LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, false,false, *pLocationData );
2241 :
2242 : // output column/row headers
2243 : // after data (throug probably shadow)
2244 :
2245 56 : Color aGridColor( COL_BLACK );
2246 56 : if ( bUseStyleColor )
2247 56 : aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2248 :
2249 56 : if (aTableParam.bHeaders)
2250 : {
2251 8 : if ( bDoPrint )
2252 : {
2253 6 : pDev->SetLineColor( aGridColor );
2254 6 : pDev->SetFillColor();
2255 6 : pDev->SetMapMode(aOffsetMode);
2256 : }
2257 :
2258 8 : ScPatternAttr aPattern( pDoc->GetPool() );
2259 16 : Font aFont;
2260 8 : ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
2261 8 : aPattern.GetFont( aFont, eColorMode, pDev );
2262 8 : pDev->SetFont( aFont );
2263 :
2264 8 : if (bDoRepCol)
2265 : {
2266 0 : if ( bDoPrint )
2267 0 : PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY );
2268 0 : if ( pLocationData )
2269 0 : LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, sal_True, *pLocationData );
2270 : }
2271 8 : if ( bDoPrint )
2272 6 : PrintColHdr( nX1,nX2, nDataX,nInnerStartY );
2273 8 : if ( pLocationData )
2274 2 : LocateColHdr( nX1,nX2, nDataX,nInnerStartY, false, *pLocationData );
2275 8 : if (bDoRepRow)
2276 : {
2277 0 : if ( bDoPrint )
2278 0 : PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY );
2279 0 : if ( pLocationData )
2280 0 : LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, sal_True, *pLocationData );
2281 : }
2282 8 : if ( bDoPrint )
2283 6 : PrintRowHdr( nY1,nY2, nInnerStartX,nDataY );
2284 8 : if ( pLocationData )
2285 10 : LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, false, *pLocationData );
2286 : }
2287 :
2288 : // simple frame
2289 :
2290 56 : if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) )
2291 : {
2292 6 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
2293 6 : long nOneX = aOnePixel.Width();
2294 6 : long nOneY = aOnePixel.Height();
2295 :
2296 6 : long nLeftX = nFrameStartX;
2297 6 : long nTopY = nFrameStartY - nOneY;
2298 6 : long nRightX = nFrameEndX;
2299 6 : long nBottomY = nFrameEndY - nOneY;
2300 6 : if ( !bLayoutRTL )
2301 : {
2302 6 : nLeftX -= nOneX;
2303 6 : nRightX -= nOneX;
2304 : }
2305 6 : pDev->SetMapMode(aOffsetMode);
2306 6 : pDev->SetLineColor( aGridColor );
2307 6 : pDev->SetFillColor();
2308 6 : pDev->DrawRect( Rectangle( nLeftX, nTopY, nRightX, nBottomY ) );
2309 : // nEndX/Y without frame-adaption
2310 : }
2311 :
2312 56 : if ( pPrinter && bDoPrint )
2313 : {
2314 : OSL_FAIL( "EndPage does not exist anymore" );
2315 : }
2316 :
2317 56 : aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab );
2318 56 : bSourceRangeValid = sal_True;
2319 56 : }
2320 :
2321 56 : void ScPrintFunc::SetOffset( const Point& rOfs )
2322 : {
2323 56 : aSrcOffset = rOfs;
2324 56 : }
2325 :
2326 56 : void ScPrintFunc::SetManualZoom( sal_uInt16 nNewZoom )
2327 : {
2328 56 : nManualZoom = nNewZoom;
2329 56 : }
2330 :
2331 56 : void ScPrintFunc::SetClearFlag( sal_Bool bFlag )
2332 : {
2333 56 : bClearWin = bFlag;
2334 56 : }
2335 :
2336 56 : void ScPrintFunc::SetUseStyleColor( sal_Bool bFlag )
2337 : {
2338 56 : bUseStyleColor = bFlag;
2339 56 : if (pEditEngine)
2340 56 : pEditEngine->EnableAutoColor( bUseStyleColor );
2341 56 : }
2342 :
2343 0 : void ScPrintFunc::SetRenderFlag( sal_Bool bFlag )
2344 : {
2345 0 : bIsRender = bFlag; // set when using XRenderable (PDF)
2346 0 : }
2347 :
2348 0 : void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects()
2349 : {
2350 0 : aTableParam.bCellContent = false;
2351 0 : aTableParam.bNotes = false;
2352 0 : aTableParam.bGrid = false;
2353 0 : aTableParam.bHeaders = false;
2354 0 : aTableParam.bFormulas = false;
2355 0 : aTableParam.bNullVals = false;
2356 0 : }
2357 :
2358 : //
2359 : // UpdatePages is only called from outside to set the breaks correctly for viewing
2360 : // - always without UserArea
2361 : //
2362 :
2363 161 : sal_Bool ScPrintFunc::UpdatePages()
2364 : {
2365 161 : if (!pParamSet)
2366 0 : return false;
2367 :
2368 : // Zoom
2369 :
2370 161 : nZoom = 100;
2371 161 : if (aTableParam.bScalePageNum || aTableParam.bScaleTo)
2372 0 : nZoom = ZOOM_MIN; // correct for breaks
2373 161 : else if (aTableParam.bScaleAll)
2374 : {
2375 161 : nZoom = aTableParam.nScaleAll;
2376 161 : if ( nZoom <= ZOOM_MIN )
2377 0 : nZoom = ZOOM_MIN;
2378 : }
2379 :
2380 161 : OUString aName = pDoc->GetPageStyle( nPrintTab );
2381 161 : SCTAB nTabCount = pDoc->GetTableCount();
2382 333 : for (SCTAB nTab=0; nTab<nTabCount; nTab++)
2383 172 : if ( nTab==nPrintTab || pDoc->GetPageStyle(nTab)==aName )
2384 : {
2385 : // Repeating rows/columns
2386 168 : pDoc->SetRepeatArea( nTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2387 :
2388 : // set breaks
2389 168 : ResetBreaks(nTab);
2390 168 : pDocShell->PostPaint(0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID);
2391 : }
2392 :
2393 161 : return sal_True;
2394 : }
2395 :
2396 190 : long ScPrintFunc::CountPages() // sets also nPagesX, nPagesY
2397 : {
2398 190 : sal_Bool bAreaOk = false;
2399 :
2400 190 : if (pDoc->HasTable( nPrintTab ))
2401 : {
2402 190 : if (aAreaParam.bPrintArea) // Specify print area?
2403 : {
2404 2 : if ( bPrintCurrentTable )
2405 : {
2406 2 : ScRange& rRange = aAreaParam.aPrintArea;
2407 :
2408 : // Here, no comparison of the tables any more. Area is always valid for this table
2409 : // If comparison should be done here, the table of print ranges must be adjusted
2410 : // when inserting tables etc.!
2411 :
2412 2 : nStartCol = rRange.aStart.Col();
2413 2 : nStartRow = rRange.aStart.Row();
2414 2 : nEndCol = rRange.aEnd .Col();
2415 2 : nEndRow = rRange.aEnd .Row();
2416 2 : bAreaOk = AdjustPrintArea(false); // limit
2417 : }
2418 : else
2419 0 : bAreaOk = false;
2420 : }
2421 : else // search from document
2422 188 : bAreaOk = AdjustPrintArea(sal_True);
2423 : }
2424 :
2425 190 : if (bAreaOk)
2426 : {
2427 34 : long nPages = 0;
2428 : size_t nY;
2429 34 : if (bMultiArea)
2430 : {
2431 0 : sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
2432 0 : for (sal_uInt16 i=0; i<nRCount; i++)
2433 : {
2434 0 : CalcZoom(i);
2435 0 : if ( aTableParam.bSkipEmpty )
2436 0 : for (nY=0; nY<nPagesY; nY++)
2437 0 : nPages += pPageRows[nY].CountVisible();
2438 : else
2439 0 : nPages += ((long) nPagesX) * nPagesY;
2440 0 : if ( pPageData )
2441 0 : FillPageData();
2442 : }
2443 : }
2444 : else
2445 : {
2446 34 : CalcZoom(RANGENO_NORANGE); // calculate Zoom
2447 34 : if ( aTableParam.bSkipEmpty )
2448 56 : for (nY=0; nY<nPagesY; nY++)
2449 28 : nPages += pPageRows[nY].CountVisible();
2450 : else
2451 6 : nPages += ((long) nPagesX) * nPagesY;
2452 34 : if ( pPageData )
2453 1 : FillPageData();
2454 : }
2455 34 : return nPages;
2456 : }
2457 : else
2458 : {
2459 156 : nPagesX = nPagesY = nTotalY = 0;
2460 156 : return 0;
2461 : }
2462 : }
2463 :
2464 236 : long ScPrintFunc::CountNotePages()
2465 : {
2466 236 : if ( !aTableParam.bNotes || !bPrintCurrentTable )
2467 226 : return 0;
2468 :
2469 10 : long nCount=0;
2470 :
2471 10 : sal_Bool bError = false;
2472 10 : if (!aAreaParam.bPrintArea)
2473 10 : bError = !AdjustPrintArea(sal_True); // completely search in Doc
2474 :
2475 10 : sal_uInt16 nRepeats = 1; // how often go through it ?
2476 10 : if (bMultiArea)
2477 0 : nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2478 10 : if (bError)
2479 10 : nRepeats = 0;
2480 :
2481 10 : for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2482 : {
2483 0 : sal_Bool bDoThis = sal_True;
2484 0 : if (bMultiArea) // go through all Areas
2485 : {
2486 0 : const ScRange* pThisRange = pDoc->GetPrintRange( nPrintTab, nStep );
2487 0 : if ( pThisRange )
2488 : {
2489 0 : nStartCol = pThisRange->aStart.Col();
2490 0 : nStartRow = pThisRange->aStart.Row();
2491 0 : nEndCol = pThisRange->aEnd .Col();
2492 0 : nEndRow = pThisRange->aEnd .Row();
2493 0 : bDoThis = AdjustPrintArea(false);
2494 : }
2495 : }
2496 :
2497 0 : if (bDoThis)
2498 : {
2499 0 : ScNotes::const_iterator itr = pDoc->GetNotes(nPrintTab)->begin();
2500 0 : ScNotes::const_iterator itrEnd = pDoc->GetNotes(nPrintTab)->end();
2501 0 : for (; itr != itrEnd; ++itr)
2502 : {
2503 0 : SCCOL nCol = itr->first.first;
2504 0 : SCROW nRow = itr->first.second;
2505 0 : if (nCol > nEndCol || nRow > nEndRow)
2506 0 : continue;
2507 :
2508 0 : if (nCol < nStartCol || nRow < nStartRow)
2509 0 : continue;
2510 :
2511 0 : aNotePosList.push_back( ScAddress( nCol, nRow, nPrintTab ) );
2512 0 : ++nCount;
2513 : }
2514 : }
2515 : }
2516 :
2517 10 : long nPages = 0;
2518 10 : long nNoteNr = 0;
2519 : long nNoteAdd;
2520 10 : do
2521 : {
2522 10 : nNoteAdd = PrintNotes( nPages, nNoteNr, false, NULL );
2523 10 : if (nNoteAdd)
2524 : {
2525 0 : nNoteNr += nNoteAdd;
2526 0 : ++nPages;
2527 : }
2528 : }
2529 : while (nNoteAdd);
2530 :
2531 10 : return nPages;
2532 : }
2533 :
2534 304 : void ScPrintFunc::InitModes() // set MapModes from nZoom etc.
2535 : {
2536 304 : aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom );
2537 :
2538 304 : long nEffZoom = nZoom * (long) nManualZoom;
2539 304 : nScaleX = nScaleY = HMM_PER_TWIPS; // output in 1/100 mm
2540 :
2541 304 : Fraction aZoomFract( nEffZoom,10000 );
2542 304 : Fraction aHorFract = aZoomFract;
2543 :
2544 304 : if ( !pPrinter && !bIsRender ) // adjust scale for preview
2545 : {
2546 130 : double nFact = pDocShell->GetOutputFactor();
2547 130 : aHorFract = Fraction( (long)( nEffZoom / nFact ), 10000 );
2548 : }
2549 :
2550 304 : aLogicMode = MapMode( MAP_100TH_MM, Point(), aHorFract, aZoomFract );
2551 :
2552 304 : Point aLogicOfs( -aOffset.X(), -aOffset.Y() );
2553 304 : aOffsetMode = MapMode( MAP_100TH_MM, aLogicOfs, aHorFract, aZoomFract );
2554 :
2555 304 : Point aTwipsOfs( (long) ( -aOffset.X() / nScaleX + 0.5 ), (long) ( -aOffset.Y() / nScaleY + 0.5 ) );
2556 304 : aTwipMode = MapMode( MAP_TWIP, aTwipsOfs, aHorFract, aZoomFract );
2557 304 : }
2558 :
2559 : //--------------------------------------------------------------------
2560 :
2561 0 : void ScPrintFunc::ApplyPrintSettings()
2562 : {
2563 0 : if ( pPrinter )
2564 : {
2565 : //
2566 : // Configure Printer to Printing
2567 : //
2568 :
2569 0 : Size aEnumSize = aPageSize;
2570 :
2571 :
2572 0 : pPrinter->SetOrientation( bLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT );
2573 0 : if ( bLandscape )
2574 : {
2575 : // landscape is always interpreted as a rotation by 90 degrees !
2576 : // this leads to non WYSIWIG but at least it prints!
2577 : // #i21775#
2578 0 : long nTemp = aEnumSize.Width();
2579 0 : aEnumSize.Width() = aEnumSize.Height();
2580 0 : aEnumSize.Height() = nTemp;
2581 : }
2582 0 : Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, sal_True );
2583 0 : sal_uInt16 nPaperBin = ((const SvxPaperBinItem&)pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue();
2584 :
2585 0 : pPrinter->SetPaper( ePaper );
2586 0 : if ( PAPER_USER == ePaper )
2587 : {
2588 0 : MapMode aPrinterMode = pPrinter->GetMapMode();
2589 0 : MapMode aLocalMode( MAP_TWIP );
2590 0 : pPrinter->SetMapMode( aLocalMode );
2591 0 : pPrinter->SetPaperSizeUser( aEnumSize );
2592 0 : pPrinter->SetMapMode( aPrinterMode );
2593 : }
2594 :
2595 0 : pPrinter->SetPaperBin( nPaperBin );
2596 : }
2597 0 : }
2598 :
2599 : //--------------------------------------------------------------------
2600 : // rPageRanges = range for all tables
2601 : // nStartPage = rPageRanges starts at nStartPage
2602 : // nDisplayStart = continious number for displaying the page number
2603 :
2604 56 : long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges,
2605 : long nStartPage, long nDisplayStart, bool bDoPrint,
2606 : ScPreviewLocationData* pLocationData )
2607 : {
2608 : OSL_ENSURE(pDev,"Device == NULL");
2609 56 : if (!pParamSet)
2610 0 : return 0;
2611 :
2612 56 : if ( pPrinter && bDoPrint )
2613 0 : ApplyPrintSettings();
2614 :
2615 : //--------------------------------------------------------------------
2616 :
2617 56 : InitModes();
2618 56 : if ( pLocationData )
2619 : {
2620 23 : pLocationData->SetCellMapMode( aOffsetMode );
2621 23 : pLocationData->SetPrintTab( nPrintTab );
2622 : }
2623 :
2624 56 : MakeTableString();
2625 :
2626 : //--------------------------------------------------------------------
2627 :
2628 56 : long nPageNo = 0;
2629 56 : long nPrinted = 0;
2630 56 : long nEndPage = rPageRanges.GetTotalRange().Max();
2631 :
2632 56 : sal_uInt16 nRepeats = 1;
2633 56 : if (bMultiArea)
2634 0 : nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2635 112 : for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2636 : {
2637 56 : if (bMultiArea) // replace area
2638 : {
2639 0 : CalcZoom(nStep); // also sets nStartCol etc. new
2640 0 : InitModes();
2641 : }
2642 :
2643 : SCCOL nX1;
2644 : SCROW nY1;
2645 : SCCOL nX2;
2646 : SCROW nY2;
2647 : size_t nCountX;
2648 : size_t nCountY;
2649 :
2650 56 : if (aTableParam.bTopDown) // top-bottom
2651 : {
2652 56 : nX1 = nStartCol;
2653 112 : for (nCountX=0; nCountX<nPagesX; nCountX++)
2654 : {
2655 56 : nX2 = pPageEndX[nCountX];
2656 112 : for (nCountY=0; nCountY<nPagesY; nCountY++)
2657 : {
2658 56 : nY1 = pPageRows[nCountY].GetStartRow();
2659 56 : nY2 = pPageRows[nCountY].GetEndRow();
2660 56 : if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
2661 : {
2662 56 : if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2663 : {
2664 : PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2665 56 : bDoPrint, pLocationData );
2666 56 : ++nPrinted;
2667 : }
2668 56 : ++nPageNo;
2669 : }
2670 : }
2671 56 : nX1 = nX2 + 1;
2672 : }
2673 : }
2674 : else // left to right
2675 : {
2676 0 : for (nCountY=0; nCountY<nPagesY; nCountY++)
2677 : {
2678 0 : nY1 = pPageRows[nCountY].GetStartRow();
2679 0 : nY2 = pPageRows[nCountY].GetEndRow();
2680 0 : nX1 = nStartCol;
2681 0 : for (nCountX=0; nCountX<nPagesX; nCountX++)
2682 : {
2683 0 : nX2 = pPageEndX[nCountX];
2684 0 : if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
2685 : {
2686 0 : if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2687 : {
2688 : PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2689 0 : bDoPrint, pLocationData );
2690 0 : ++nPrinted;
2691 : }
2692 0 : ++nPageNo;
2693 : }
2694 0 : nX1 = nX2 + 1;
2695 : }
2696 : }
2697 : }
2698 : }
2699 :
2700 56 : aFieldData.aTabName = ScGlobal::GetRscString( STR_NOTES );
2701 :
2702 56 : long nNoteNr = 0;
2703 : long nNoteAdd;
2704 56 : do
2705 : {
2706 56 : if ( nPageNo+nStartPage <= nEndPage )
2707 : {
2708 56 : sal_Bool bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 );
2709 56 : nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected,
2710 112 : ( bPageSelected ? pLocationData : NULL ) );
2711 56 : if ( nNoteAdd )
2712 : {
2713 0 : nNoteNr += nNoteAdd;
2714 0 : if (bPageSelected)
2715 : {
2716 0 : ++nPrinted;
2717 0 : bSourceRangeValid = false; // last page was no cell range
2718 : }
2719 0 : ++nPageNo;
2720 : }
2721 : }
2722 : else
2723 0 : nNoteAdd = 0;
2724 : }
2725 : while (nNoteAdd);
2726 :
2727 56 : if ( bMultiArea )
2728 0 : ResetBreaks(nPrintTab); //breaks correct for displaying
2729 :
2730 56 : return nPrinted;
2731 : }
2732 :
2733 34 : void ScPrintFunc::CalcZoom( sal_uInt16 nRangeNo ) // calculate zoom
2734 : {
2735 34 : sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
2736 34 : const ScRange* pThisRange = NULL;
2737 34 : if ( nRangeNo != RANGENO_NORANGE || nRangeNo < nRCount )
2738 0 : pThisRange = pDoc->GetPrintRange( nPrintTab, nRangeNo );
2739 34 : if ( pThisRange )
2740 : {
2741 0 : nStartCol = pThisRange->aStart.Col();
2742 0 : nStartRow = pThisRange->aStart.Row();
2743 0 : nEndCol = pThisRange->aEnd .Col();
2744 0 : nEndRow = pThisRange->aEnd .Row();
2745 : }
2746 :
2747 34 : if (!AdjustPrintArea(false)) // empty
2748 : {
2749 0 : nZoom = 100;
2750 0 : nPagesX = nPagesY = nTotalY = 0;
2751 34 : return;
2752 : }
2753 :
2754 34 : pDoc->SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2755 :
2756 34 : if (aTableParam.bScalePageNum)
2757 : {
2758 0 : nZoom = 100;
2759 0 : sal_uInt16 nPagesToFit = aTableParam.nScalePageNum;
2760 :
2761 0 : sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2762 : while (true)
2763 : {
2764 0 : if (nZoom <= ZOOM_MIN)
2765 0 : break;
2766 :
2767 0 : CalcPages();
2768 0 : bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit);
2769 :
2770 0 : if (bFitsPage)
2771 : {
2772 0 : if (nZoom == 100)
2773 : // If it fits at 100 %, it's good enough for me.
2774 0 : break;
2775 :
2776 0 : nLastFitZoom = nZoom;
2777 0 : nZoom = (nLastNonFitZoom + nZoom) / 2;
2778 :
2779 0 : if (nLastFitZoom == nZoom)
2780 : // It converged. Use this zoom level.
2781 0 : break;
2782 : }
2783 : else
2784 : {
2785 0 : if (nZoom - nLastFitZoom <= 1)
2786 : {
2787 0 : nZoom = nLastFitZoom;
2788 0 : CalcPages();
2789 0 : break;
2790 : }
2791 :
2792 0 : nLastNonFitZoom = nZoom;
2793 0 : nZoom = (nLastFitZoom + nZoom) / 2;
2794 : }
2795 0 : }
2796 : }
2797 34 : else if (aTableParam.bScaleTo)
2798 : {
2799 0 : nZoom = 100;
2800 0 : sal_uInt16 nW = aTableParam.nScaleWidth;
2801 0 : sal_uInt16 nH = aTableParam.nScaleHeight;
2802 :
2803 0 : sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2804 : while (true)
2805 : {
2806 0 : if (nZoom <= ZOOM_MIN)
2807 0 : break;
2808 :
2809 0 : CalcPages();
2810 0 : bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH)));
2811 :
2812 0 : if (bFitsPage)
2813 : {
2814 0 : if (nZoom == 100)
2815 : // If it fits at 100 %, it's good enough for me.
2816 0 : break;
2817 :
2818 0 : nLastFitZoom = nZoom;
2819 0 : nZoom = (nLastNonFitZoom + nZoom) / 2;
2820 :
2821 0 : if (nLastFitZoom == nZoom)
2822 : // It converged. Use this zoom level.
2823 0 : break;
2824 : }
2825 : else
2826 : {
2827 0 : if (nZoom - nLastFitZoom <= 1)
2828 : {
2829 0 : nZoom = nLastFitZoom;
2830 0 : CalcPages();
2831 0 : break;
2832 : }
2833 :
2834 0 : nLastNonFitZoom = nZoom;
2835 0 : nZoom = (nLastFitZoom + nZoom) / 2;
2836 : }
2837 0 : }
2838 : }
2839 34 : else if (aTableParam.bScaleAll)
2840 : {
2841 34 : nZoom = aTableParam.nScaleAll;
2842 34 : if ( nZoom <= ZOOM_MIN )
2843 0 : nZoom = ZOOM_MIN;
2844 34 : CalcPages();
2845 : }
2846 : else
2847 : {
2848 : OSL_ENSURE( aTableParam.bScaleNone, "kein Scale-Flag gesetzt" );
2849 0 : nZoom = 100;
2850 0 : CalcPages();
2851 : }
2852 : }
2853 :
2854 248 : Size ScPrintFunc::GetDocPageSize()
2855 : {
2856 : // Adjust height of head/foot line
2857 :
2858 248 : InitModes(); // initialize aTwipMode from nZoom
2859 248 : pDev->SetMapMode( aTwipMode ); // head/foot line in Twips
2860 248 : UpdateHFHeight( aHdr );
2861 248 : UpdateHFHeight( aFtr );
2862 :
2863 : // Page size in Document-Twips
2864 : // Calculating Left / Right also in PrintPage
2865 :
2866 248 : aPageRect = Rectangle( Point(), aPageSize );
2867 248 : aPageRect.Left() = ( aPageRect.Left() + nLeftMargin ) * 100 / nZoom;
2868 248 : aPageRect.Right() = ( aPageRect.Right() - nRightMargin ) * 100 / nZoom;
2869 248 : aPageRect.Top() = ( aPageRect.Top() + nTopMargin ) * 100 / nZoom + aHdr.nHeight;
2870 248 : aPageRect.Bottom() = ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight;
2871 :
2872 248 : Size aDocPageSize = aPageRect.GetSize();
2873 248 : if (aTableParam.bHeaders)
2874 : {
2875 10 : aDocPageSize.Width() -= (long) PRINT_HEADER_WIDTH;
2876 10 : aDocPageSize.Height() -= (long) PRINT_HEADER_HEIGHT;
2877 : }
2878 248 : if (pBorderItem)
2879 : {
2880 744 : aDocPageSize.Width() -= lcl_LineTotal(pBorderItem->GetLeft()) +
2881 496 : lcl_LineTotal(pBorderItem->GetRight()) +
2882 496 : pBorderItem->GetDistance(BOX_LINE_LEFT) +
2883 744 : pBorderItem->GetDistance(BOX_LINE_RIGHT);
2884 744 : aDocPageSize.Height() -= lcl_LineTotal(pBorderItem->GetTop()) +
2885 496 : lcl_LineTotal(pBorderItem->GetBottom()) +
2886 496 : pBorderItem->GetDistance(BOX_LINE_TOP) +
2887 744 : pBorderItem->GetDistance(BOX_LINE_BOTTOM);
2888 : }
2889 248 : if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2890 : {
2891 0 : aDocPageSize.Width() -= pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
2892 0 : pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
2893 0 : aDocPageSize.Height() -= pShadowItem->CalcShadowSpace(SHADOW_TOP) +
2894 0 : pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
2895 : }
2896 248 : return aDocPageSize;
2897 : }
2898 :
2899 168 : void ScPrintFunc::ResetBreaks( SCTAB nTab ) // Set Breaks correctly for view
2900 : {
2901 168 : pDoc->SetPageSize( nTab, GetDocPageSize() );
2902 168 : pDoc->UpdatePageBreaks( nTab, NULL );
2903 168 : }
2904 :
2905 74 : static void lcl_SetHidden( ScDocument* pDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry,
2906 : SCCOL nStartCol, const SCCOL* pPageEndX )
2907 : {
2908 74 : size_t nPagesX = rPageRowEntry.GetPagesX();
2909 74 : SCROW nStartRow = rPageRowEntry.GetStartRow();
2910 74 : SCROW nEndRow = rPageRowEntry.GetEndRow();
2911 :
2912 74 : sal_Bool bLeftIsEmpty = false;
2913 74 : ScRange aTempRange;
2914 74 : Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 );
2915 :
2916 148 : for (size_t i=0; i<nPagesX; i++)
2917 : {
2918 74 : SCCOL nEndCol = pPageEndX[i];
2919 74 : if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow,
2920 74 : bLeftIsEmpty, &aTempRange, &aTempRect ) )
2921 : {
2922 0 : rPageRowEntry.SetHidden(i);
2923 0 : bLeftIsEmpty = sal_True;
2924 : }
2925 : else
2926 74 : bLeftIsEmpty = false;
2927 :
2928 74 : nStartCol = nEndCol+1;
2929 : }
2930 74 : }
2931 :
2932 80 : void ScPrintFunc::CalcPages() // calculates aPageRect and pages from nZoom
2933 : {
2934 80 : if (!pPageEndX) pPageEndX = new SCCOL[MAXCOL+1];
2935 : //performance impact
2936 : // if (!pPageEndY) pPageEndY = new SCROW[MAXROW+1];
2937 : // if (!pPageRows) pPageRows = new ScPageRowEntry[MAXROW+1]; //! count before !!!!
2938 :
2939 80 : pDoc->SetPageSize( nPrintTab, GetDocPageSize() );
2940 80 : if (aAreaParam.bPrintArea)
2941 : {
2942 2 : ScRange aRange( nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab );
2943 2 : pDoc->UpdatePageBreaks( nPrintTab, &aRange );
2944 : }
2945 : else
2946 78 : pDoc->UpdatePageBreaks( nPrintTab, NULL ); // else, end is marked
2947 80 : SCROW nRealCnt = nEndRow-nStartRow+1;
2948 80 : if (!pPageEndY) pPageEndY = new SCROW[nRealCnt+1];
2949 80 : if (!pPageRows) pPageRows = new ScPageRowEntry[nRealCnt+1]; //! vorher zaehlen !!!!
2950 : //
2951 : // Page alignment/splitting after breaks in Col/RowFlags
2952 : // Of several breaks in a hidden area, only one counts.
2953 : //
2954 :
2955 80 : nPagesX = 0;
2956 80 : nPagesY = 0;
2957 80 : nTotalY = 0;
2958 :
2959 80 : bool bVisCol = false;
2960 206 : for (SCCOL i=nStartCol; i<=nEndCol; i++)
2961 : {
2962 126 : bool bHidden = pDoc->ColHidden(i, nPrintTab);
2963 126 : bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE);
2964 126 : if ( i>nStartCol && bVisCol && bPageBreak )
2965 : {
2966 4 : pPageEndX[nPagesX] = i-1;
2967 4 : ++nPagesX;
2968 4 : bVisCol = false;
2969 : }
2970 126 : if (!bHidden)
2971 126 : bVisCol = true;
2972 : }
2973 80 : if (bVisCol) // also at the end, no empty pages
2974 : {
2975 80 : pPageEndX[nPagesX] = nEndCol;
2976 80 : ++nPagesX;
2977 : }
2978 :
2979 80 : bool bVisRow = false;
2980 80 : SCROW nPageStartRow = nStartRow;
2981 80 : SCROW nLastVisibleRow = -1;
2982 :
2983 80 : ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab));
2984 80 : SCROW nNextPageBreak = pRowBreakIter->first();
2985 160 : while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow)
2986 : // Skip until the page break position is at the start row or greater.
2987 0 : nNextPageBreak = pRowBreakIter->next();
2988 :
2989 330 : for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
2990 : {
2991 250 : bool bPageBreak = (nNextPageBreak == nRow);
2992 250 : if (bPageBreak)
2993 3 : nNextPageBreak = pRowBreakIter->next();
2994 :
2995 250 : if (nRow > nStartRow && bVisRow && bPageBreak )
2996 : {
2997 3 : pPageEndY[nTotalY] = nRow-1;
2998 3 : ++nTotalY;
2999 :
3000 3 : if ( !aTableParam.bSkipEmpty ||
3001 0 : !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) )
3002 : {
3003 3 : pPageRows[nPagesY].SetStartRow( nPageStartRow );
3004 3 : pPageRows[nPagesY].SetEndRow( nRow-1 );
3005 3 : pPageRows[nPagesY].SetPagesX( nPagesX );
3006 3 : if (aTableParam.bSkipEmpty)
3007 0 : lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX );
3008 3 : ++nPagesY;
3009 : }
3010 :
3011 3 : nPageStartRow = nRow;
3012 3 : bVisRow = false;
3013 : }
3014 :
3015 250 : if (nRow <= nLastVisibleRow)
3016 : {
3017 : // This row is still visible. Don't bother calling RowHidden() to
3018 : // find out, for speed optimization.
3019 170 : bVisRow = true;
3020 170 : continue;
3021 : }
3022 :
3023 80 : SCROW nLastRow = -1;
3024 80 : if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow))
3025 : {
3026 80 : bVisRow = true;
3027 80 : nLastVisibleRow = nLastRow;
3028 : }
3029 : else
3030 : // skip all hidden rows.
3031 0 : nRow = nLastRow;
3032 : }
3033 :
3034 80 : if (bVisRow)
3035 : {
3036 80 : pPageEndY[nTotalY] = nEndRow;
3037 80 : ++nTotalY;
3038 :
3039 154 : if ( !aTableParam.bSkipEmpty ||
3040 74 : !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) )
3041 : {
3042 80 : pPageRows[nPagesY].SetStartRow( nPageStartRow );
3043 80 : pPageRows[nPagesY].SetEndRow( nEndRow );
3044 80 : pPageRows[nPagesY].SetPagesX( nPagesX );
3045 80 : if (aTableParam.bSkipEmpty)
3046 74 : lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX );
3047 80 : ++nPagesY;
3048 : }
3049 80 : }
3050 173 : }
3051 :
3052 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|