GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / sc / source / ui / view / printfun.cxx
blob87c508bf8e26ee0198927c345065603ce6ee73df
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "scitems.hxx"
21 #include <editeng/eeitem.hxx>
23 #include "printfun.hxx"
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>
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>
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"
71 #include <vcl/lineinfo.hxx>
73 #include <boost/scoped_ptr.hpp>
74 #include <com/sun/star/document/XDocumentProperties.hpp>
76 #define ZOOM_MIN 10
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()) )
82 //------------------------------------------------------------------------
84 ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r)
86 nStartRow = r.nStartRow;
87 nEndRow = r.nEndRow;
88 nPagesX = r.nPagesX;
89 if (r.pHidden && nPagesX)
91 pHidden = new sal_Bool[nPagesX];
92 memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
94 else
95 pHidden = NULL;
98 const ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r)
100 delete[] pHidden;
102 nStartRow = r.nStartRow;
103 nEndRow = r.nEndRow;
104 nPagesX = r.nPagesX;
105 if (r.pHidden && nPagesX)
107 pHidden = new sal_Bool[nPagesX];
108 memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
110 else
111 pHidden = NULL;
113 return *this;
116 void ScPageRowEntry::SetPagesX(size_t nNew)
118 if (pHidden)
120 OSL_FAIL("SetPagesX nicht nach SetHidden");
121 delete[] pHidden;
122 pHidden = NULL;
124 nPagesX = nNew;
127 void ScPageRowEntry::SetHidden(size_t nX)
129 if ( nX < nPagesX )
131 if ( nX+1 == nPagesX ) // last page?
132 --nPagesX;
133 else
135 if (!pHidden)
137 pHidden = new sal_Bool[nPagesX];
138 memset( pHidden, false, nPagesX * sizeof(sal_Bool) );
140 pHidden[nX] = sal_True;
145 sal_Bool ScPageRowEntry::IsHidden(size_t nX) const
147 return nX>=nPagesX || ( pHidden && pHidden[nX] ); //! inline?
150 size_t ScPageRowEntry::CountVisible() const
152 if ( pHidden )
154 size_t nVis = 0;
155 for (size_t i=0; i<nPagesX; i++)
156 if (!pHidden[i])
157 ++nVis;
158 return nVis;
160 else
161 return nPagesX;
164 //------------------------------------------------------------------------
166 static long lcl_LineTotal(const ::editeng::SvxBorderLine* pLine)
168 return pLine ? ( pLine->GetScaledWidth() ) : 0;
171 void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
173 pDocShell->UpdatePendingRowHeights( nPrintTab );
174 pDoc = pDocShell->GetDocument();
176 SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // use the printer, even for preview
177 if (pDocPrinter)
178 aOldPrinterMode = pDocPrinter->GetMapMode();
180 // unified MapMode for all calls (e.g. Repaint!!!)
181 // else, EditEngine outputs different text heights
182 pDev->SetMapMode(MAP_PIXEL);
184 pPageEndX = NULL;
185 pPageEndY = NULL;
186 pPageRows = NULL;
187 pBorderItem = NULL;
188 pBackgroundItem = NULL;
189 pShadowItem = NULL;
191 pEditEngine = NULL;
192 pEditDefaults = NULL;
194 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
195 SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
196 pDoc->GetPageStyle( nPrintTab ),
197 SFX_STYLE_FAMILY_PAGE );
198 if (pStyleSheet)
199 pParamSet = &pStyleSheet->GetItemSet();
200 else
202 OSL_FAIL("Seitenvorlage nicht gefunden" );
203 pParamSet = NULL;
206 if (!bState)
207 nZoom = 100;
208 nManualZoom = 100;
209 bClearWin = false;
210 bUseStyleColor = false;
211 bIsRender = false;
213 InitParam(pOptions);
215 pPageData = NULL; // wird nur zur Initialisierung gebraucht
218 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 pPageData ( pData )
240 pDev = pPrinter;
241 aSrcOffset = pPrinter->PixelToLogic( pPrinter->GetPageOffsetPixel(), MAP_100TH_MM );
242 Construct( pOptions );
245 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 pPageData ( NULL )
266 pDev = pOutDev;
267 Construct( pOptions );
270 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 pPageData ( NULL )
284 pDev = pOutDev;
286 nPrintTab = rState.nPrintTab;
287 nStartCol = rState.nStartCol;
288 nStartRow = rState.nStartRow;
289 nEndCol = rState.nEndCol;
290 nEndRow = rState.nEndRow;
291 nZoom = rState.nZoom;
292 nPagesX = rState.nPagesX;
293 nPagesY = rState.nPagesY;
294 nTabPages = rState.nTabPages;
295 nTotalPages = rState.nTotalPages;
296 nPageStart = rState.nPageStart;
297 nDocPages = rState.nDocPages;
298 bState = sal_True;
300 Construct( pOptions );
303 void ScPrintFunc::GetPrintState( ScPrintState& rState )
305 rState.nPrintTab = nPrintTab;
306 rState.nStartCol = nStartCol;
307 rState.nStartRow = nStartRow;
308 rState.nEndCol = nEndCol;
309 rState.nEndRow = nEndRow;
310 rState.nZoom = nZoom;
311 rState.nPagesX = nPagesX;
312 rState.nPagesY = nPagesY;
313 rState.nTabPages = nTabPages;
314 rState.nTotalPages = nTotalPages;
315 rState.nPageStart = nPageStart;
316 rState.nDocPages = nDocPages;
319 sal_Bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const
321 rRange = aLastSourceRange;
322 return bSourceRangeValid;
325 void ScPrintFunc::FillPageData()
327 if (pPageData)
329 sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
330 ScPrintRangeData& rData = pPageData->GetData(nCount); // count up
332 rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab,
333 nEndCol, nEndRow, nPrintTab ) );
334 rData.SetPagesX( nPagesX, pPageEndX );
335 rData.SetPagesY( nTotalY, pPageEndY );
337 // Settings
338 rData.SetTopDown( aTableParam.bTopDown );
339 rData.SetAutomatic( !aAreaParam.bPrintArea );
343 ScPrintFunc::~ScPrintFunc()
345 delete[] pPageEndX;
346 delete[] pPageEndY;
347 delete[] pPageRows;
348 delete pEditDefaults;
349 delete pEditEngine;
351 // Printer settings are now restored from outside
353 // For DrawingLayer/Charts, the MapMode of the printer (RefDevice) must always be correct
354 SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // use Preview also for the printer
355 if (pDocPrinter)
356 pDocPrinter->SetMapMode(aOldPrinterMode);
359 void ScPrintFunc::SetDrawView( FmFormView* pNew )
361 pDrawView = pNew;
364 static void lcl_HidePrint( ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 )
366 for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++)
368 RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY];
369 for (SCCOL nX=nX1; nX<=nX2; nX++)
371 const CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1];
372 if (!rCellInfo.bEmptyCellText)
373 if (((const ScProtectionAttr&)rCellInfo.pPatternAttr->
374 GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet)).GetHidePrint())
376 pThisRowInfo->pCellInfo[nX+1].maCell.clear();
377 pThisRowInfo->pCellInfo[nX+1].bEmptyCellText = true;
384 // output to Device (static)
386 // us used for:
387 // - Clipboard/Bitmap
388 // - Ole-Object (DocShell::Draw)
389 // - Preview of templates
391 void ScPrintFunc::DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double /* nPrintFactor */,
392 const Rectangle& rBound, ScViewData* pViewData, sal_Bool bMetaFile )
394 //! evaluate nPrintFactor !!!
396 SCTAB nTab = 0;
397 if (pViewData)
398 nTab = pViewData->GetTabNo();
400 sal_Bool bDoGrid, bNullVal, bFormula;
401 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
402 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
403 if (pStyleSheet)
405 SfxItemSet& rSet = pStyleSheet->GetItemSet();
406 bDoGrid = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_GRID)).GetValue();
407 bNullVal = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_NULLVALS)).GetValue();
408 bFormula = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_FORMULAS)).GetValue();
410 else
412 const ScViewOptions& rOpt = pDoc->GetViewOptions();
413 bDoGrid = rOpt.GetOption(VOPT_GRID);
414 bNullVal = rOpt.GetOption(VOPT_NULLVALS);
415 bFormula = rOpt.GetOption(VOPT_FORMULAS);
418 MapMode aMode = pDev->GetMapMode();
420 Rectangle aRect = rBound;
422 if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top())
423 aRect = Rectangle( Point(), pDev->GetOutputSize() );
425 SCCOL nX1 = 0;
426 SCROW nY1 = 0;
427 SCCOL nX2 = OLE_STD_CELLS_X - 1;
428 SCROW nY2 = OLE_STD_CELLS_Y - 1;
429 if (bMetaFile)
431 ScRange aRange = pDoc->GetRange( nTab, rBound );
432 nX1 = aRange.aStart.Col();
433 nY1 = aRange.aStart.Row();
434 nX2 = aRange.aEnd.Col();
435 nY2 = aRange.aEnd.Row();
437 else if (pViewData)
439 ScSplitPos eWhich = pViewData->GetActivePart();
440 ScHSplitPos eHWhich = WhichH(eWhich);
441 ScVSplitPos eVWhich = WhichV(eWhich);
442 nX1 = pViewData->GetPosX(eHWhich);
443 nY1 = pViewData->GetPosY(eVWhich);
444 nX2 = nX1 + pViewData->VisibleCellsX(eHWhich);
445 if (nX2>nX1) --nX2;
446 nY2 = nY1 + pViewData->VisibleCellsY(eVWhich);
447 if (nY2>nY1) --nY2;
450 if (nX1 > MAXCOL) nX1 = MAXCOL;
451 if (nX2 > MAXCOL) nX2 = MAXCOL;
452 if (nY1 > MAXROW) nY1 = MAXROW;
453 if (nY2 > MAXROW) nY2 = MAXROW;
455 long nDevSizeX = aRect.Right()-aRect.Left()+1;
456 long nDevSizeY = aRect.Bottom()-aRect.Top()+1;
458 Rectangle aLines;
459 ScRange aRange( nX1,nY1,nTab, nX2,nY2,nTab );
461 long nTwipsSizeX = 0;
462 for (SCCOL i=nX1; i<=nX2; i++)
463 nTwipsSizeX += pDoc->GetColWidth( i, nTab );
464 long nTwipsSizeY = (long) pDoc->GetRowHeight( nY1, nY2, nTab );
466 // if no lines, still space for the outline frame (20 Twips = 1pt)
467 // (HasLines initalizes aLines to 0,0,0,0)
468 nTwipsSizeX += aLines.Left() + std::max( aLines.Right(), 20L );
469 nTwipsSizeY += aLines.Top() + std::max( aLines.Bottom(), 20L );
471 double nScaleX = (double) nDevSizeX / nTwipsSizeX;
472 double nScaleY = (double) nDevSizeY / nTwipsSizeY;
474 //! hand over Flag at FillInfo !!!!!
475 ScRange aERange;
476 sal_Bool bEmbed = pDoc->IsEmbedded();
477 if (bEmbed)
479 pDoc->GetEmbedded(aERange);
480 pDoc->ResetEmbedded();
483 // Assemble data
485 ScTableInfo aTabInfo;
486 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
487 nScaleX, nScaleY, false, bFormula );
488 lcl_HidePrint( aTabInfo, nX1, nX2 );
490 if (bEmbed)
491 pDoc->SetEmbedded(aERange);
493 long nScrX = aRect.Left();
494 long nScrY = aRect.Top();
496 // If no lines, still leave space for grid lines
497 // (would be elseways cut away)
498 long nAddX = (long)( aLines.Left() * nScaleX );
499 nScrX += ( nAddX ? nAddX : 1 );
500 long nAddY = (long)( aLines.Top() * nScaleY );
501 nScrY += ( nAddY ? nAddY : 1 );
503 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nTab,
504 nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
505 aOutputData.SetMetaFileMode(bMetaFile);
506 aOutputData.SetShowNullValues(bNullVal);
507 aOutputData.SetShowFormulas(bFormula);
509 // #114135#
510 ScDrawLayer* pModel = pDoc->GetDrawLayer();
511 FmFormView* pDrawView = NULL;
513 if( pModel )
515 pDrawView = new FmFormView( pModel, pDev );
516 pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
517 pDrawView->SetPrintPreview( sal_True );
518 aOutputData.SetDrawView( pDrawView );
521 //! SetUseStyleColor ??
523 if ( bMetaFile && pDev->GetOutDevType() == OUTDEV_VIRDEV )
524 aOutputData.SetSnapPixel();
526 Point aLogStart = pDev->PixelToLogic( Point(nScrX,nScrY), MAP_100TH_MM );
527 long nLogStX = aLogStart.X();
528 long nLogStY = aLogStart.Y();
530 //! nZoom for GetFont in OutputData ???
532 if (!bMetaFile && pViewData)
533 pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
535 // #i72502#
536 const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
537 aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
539 if (!bMetaFile && pViewData)
540 pDev->SetMapMode(aMode);
542 aOutputData.DrawBackground();
543 aOutputData.DrawShadow();
544 aOutputData.DrawFrame();
545 aOutputData.DrawStrings();
547 if (!bMetaFile && pViewData)
548 pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
550 aOutputData.DrawEdit(!bMetaFile);
552 if (bDoGrid)
554 if (!bMetaFile && pViewData)
555 pDev->SetMapMode(aMode);
557 aOutputData.DrawGrid( sal_True, false ); // no page breaks
559 pDev->SetLineColor( COL_BLACK );
561 Size aOne = pDev->PixelToLogic( Size(1,1) );
562 if (bMetaFile)
563 aOne = Size(1,1); // compatible with DrawGrid
564 long nRight = nScrX + aOutputData.GetScrW() - aOne.Width();
565 long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height();
567 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
569 // extra line at the left edge for left-to-right, right for right-to-left
570 if ( bLayoutRTL )
571 pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) );
572 else
573 pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) );
574 // extra line at the top in both cases
575 pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) );
578 // #i72502#
579 aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
580 aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
581 aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
583 // #114135#
584 delete pDrawView;
588 // Printing
591 static void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet )
593 // nDistance must be initialized differently before
595 if ( pHFSet == NULL )
597 rParam.bEnable = false;
598 rParam.pBorder = NULL;
599 rParam.pBack = NULL;
600 rParam.pShadow = NULL;
602 else
604 rParam.bEnable = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_ON)).GetValue();
605 rParam.bDynamic = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_DYNAMIC)).GetValue();
606 rParam.bShared = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_SHARED)).GetValue();
607 rParam.nHeight = ((const SvxSizeItem&) pHFSet->Get(ATTR_PAGE_SIZE)).GetSize().Height();
608 const SvxLRSpaceItem* pHFLR = &(const SvxLRSpaceItem&) pHFSet->Get(ATTR_LRSPACE);
609 long nTmp;
610 nTmp = pHFLR->GetLeft();
611 rParam.nLeft = nTmp < 0 ? 0 : sal_uInt16(nTmp);
612 nTmp = pHFLR->GetRight();
613 rParam.nRight = nTmp < 0 ? 0 : sal_uInt16(nTmp);
614 rParam.pBorder = (const SvxBoxItem*) &pHFSet->Get(ATTR_BORDER);
615 rParam.pBack = (const SvxBrushItem*) &pHFSet->Get(ATTR_BACKGROUND);
616 rParam.pShadow = (const SvxShadowItem*)&pHFSet->Get(ATTR_SHADOW);
618 // now back in the dialog:
619 // rParam.nHeight += rParam.nDistance; // not in the dialog any more ???
621 if (rParam.pBorder)
622 rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
623 lcl_LineTotal( rParam.pBorder->GetBottom() );
625 rParam.nManHeight = rParam.nHeight;
628 if (!rParam.bEnable)
629 rParam.nHeight = 0;
632 // bNew = TRUE: search for used part of the document
633 // bNew = FALSE: only limit whole lines/columns
635 sal_Bool ScPrintFunc::AdjustPrintArea( sal_Bool bNew )
637 SCCOL nOldEndCol = nEndCol; // only important for !bNew
638 SCROW nOldEndRow = nEndRow;
639 sal_Bool bChangeCol = sal_True; // at bNew both are being adjusted
640 sal_Bool bChangeRow = sal_True;
642 sal_Bool bNotes = aTableParam.bNotes;
643 if ( bNew )
645 nStartCol = 0;
646 nStartRow = 0;
647 if (!pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ))
648 return false; // nix
650 else
652 sal_Bool bFound = sal_True;
653 bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL );
654 bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW );
655 sal_Bool bForcedChangeRow = false;
657 // #i53558# Crop entire column of old row limit to real print area with
658 // some fuzzyness.
659 if (!bChangeRow && nStartRow == 0)
661 SCROW nPAEndRow;
662 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 const SCROW nFuzzy = 23*42;
666 if (nPAEndRow + nFuzzy < nEndRow)
668 bForcedChangeRow = sal_True;
669 nEndRow = nPAEndRow;
671 else
672 bFound = sal_True; // user seems to _want_ to print some empty rows
674 // TODO: in case we extend the number of columns we may have to do the
675 // same for horizontal cropping.
677 if ( bChangeCol && bChangeRow )
678 bFound = pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes );
679 else if ( bChangeCol )
680 bFound = pDoc->GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol, bNotes );
681 else if ( bChangeRow )
682 bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes );
684 if (!bFound)
685 return false; // empty
687 if (bForcedChangeRow)
688 bChangeRow = sal_True;
691 pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab,
692 false ); // no Refresh, incl. Attrs
694 if ( bChangeCol )
696 OutputDevice* pRefDev = pDoc->GetPrinter(); // use the printer also for Preview
697 pRefDev->SetMapMode( MAP_PIXEL ); // important for GetNeededSize
699 pDoc->ExtendPrintArea( pRefDev,
700 nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow );
701 // changing nEndCol
704 if ( nEndCol < MAXCOL && pDoc->HasAttrib(
705 nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_RIGHT ) )
706 ++nEndCol;
707 if ( nEndRow < MAXROW && pDoc->HasAttrib(
708 nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_DOWN ) )
709 ++nEndRow;
711 if (!bChangeCol) nEndCol = nOldEndCol;
712 if (!bChangeRow) nEndRow = nOldEndRow;
714 return sal_True;
717 long ScPrintFunc::TextHeight( const EditTextObject* pObject )
719 if (!pObject)
720 return 0;
722 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
724 return (long) pEditEngine->GetTextHeight();
727 // nZoom must be set !!!
728 // and the respective Twip-MapMode configured
730 void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam )
732 OSL_ENSURE( aPageSize.Width(), "UpdateHFHeight ohne aPageSize");
734 if (rParam.bEnable && rParam.bDynamic)
736 // calculate nHeight from content
738 MakeEditEngine();
739 long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin -
740 rParam.nLeft - rParam.nRight ) * 100 / nZoom;
741 if (rParam.pBorder)
742 nPaperWidth -= ( rParam.pBorder->GetDistance(BOX_LINE_LEFT) +
743 rParam.pBorder->GetDistance(BOX_LINE_RIGHT) +
744 lcl_LineTotal(rParam.pBorder->GetLeft()) +
745 lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom;
747 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
748 nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SHADOW_LEFT) +
749 rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT) ) * 100L / nZoom;
751 pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) );
753 long nMaxHeight = 0;
754 if ( rParam.pLeft )
756 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) );
757 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) );
758 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) );
760 if ( rParam.pRight )
762 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) );
763 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) );
764 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) );
767 rParam.nHeight = nMaxHeight + rParam.nDistance;
768 if (rParam.pBorder)
769 rParam.nHeight += rParam.pBorder->GetDistance(BOX_LINE_TOP) +
770 rParam.pBorder->GetDistance(BOX_LINE_BOTTOM) +
771 lcl_LineTotal( rParam.pBorder->GetTop() ) +
772 lcl_LineTotal( rParam.pBorder->GetBottom() );
773 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
774 rParam.nHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
775 rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
777 if (rParam.nHeight < rParam.nManHeight)
778 rParam.nHeight = rParam.nManHeight; // configured minimum
782 void ScPrintFunc::InitParam( const ScPrintOptions* pOptions )
784 if (!pParamSet)
785 return;
787 // TabPage "Page"
788 const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &pParamSet->Get( ATTR_LRSPACE );
789 long nTmp;
790 nTmp = pLRItem->GetLeft();
791 nLeftMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
792 nTmp = pLRItem->GetRight();
793 nRightMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
794 const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &pParamSet->Get( ATTR_ULSPACE );
795 nTopMargin = pULItem->GetUpper();
796 nBottomMargin = pULItem->GetLower();
798 const SvxPageItem* pPageItem = (const SvxPageItem*) &pParamSet->Get( ATTR_PAGE );
799 nPageUsage = pPageItem->GetPageUsage();
800 bLandscape = pPageItem->IsLandscape();
801 aFieldData.eNumType = pPageItem->GetNumType();
803 bCenterHor = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_HORCENTER)).GetValue();
804 bCenterVer = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_VERCENTER)).GetValue();
806 aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
807 if ( !aPageSize.Width() || !aPageSize.Height() )
809 OSL_FAIL("PageSize Null ?!?!?");
810 aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
813 pBorderItem = (const SvxBoxItem*) &pParamSet->Get(ATTR_BORDER);
814 pBackgroundItem = (const SvxBrushItem*) &pParamSet->Get(ATTR_BACKGROUND);
815 pShadowItem = (const SvxShadowItem*) &pParamSet->Get(ATTR_SHADOW);
817 // TabPage "Headline"
819 aHdr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERLEFT); // Content
820 aHdr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERRIGHT);
822 const SvxSetItem* pHeaderSetItem;
823 const SfxItemSet* pHeaderSet = NULL;
824 if ( pParamSet->GetItemState( ATTR_PAGE_HEADERSET, false,
825 (const SfxPoolItem**)&pHeaderSetItem ) == SFX_ITEM_SET )
827 pHeaderSet = &pHeaderSetItem->GetItemSet();
828 // Headline has space below
829 aHdr.nDistance = ((const SvxULSpaceItem&) pHeaderSet->Get(ATTR_ULSPACE)).GetLower();
831 lcl_FillHFParam( aHdr, pHeaderSet );
833 // TabPage "Footline"
835 aFtr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERLEFT); // Content
836 aFtr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT);
838 const SvxSetItem* pFooterSetItem;
839 const SfxItemSet* pFooterSet = NULL;
840 if ( pParamSet->GetItemState( ATTR_PAGE_FOOTERSET, false,
841 (const SfxPoolItem**)&pFooterSetItem ) == SFX_ITEM_SET )
843 pFooterSet = &pFooterSetItem->GetItemSet();
844 // Footline has space above
845 aFtr.nDistance = ((const SvxULSpaceItem&) pFooterSet->Get(ATTR_ULSPACE)).GetUpper();
847 lcl_FillHFParam( aFtr, pFooterSet );
849 //------------------------------------------------------
850 // Compile Table-/Area-Params from single Items
851 //------------------------------------------------------
852 // TabPage "Table"
854 const SfxUInt16Item* pScaleItem = NULL;
855 const ScPageScaleToItem* pScaleToItem = NULL;
856 const SfxUInt16Item* pScaleToPagesItem = NULL;
857 SfxItemState eState;
859 eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, false,
860 (const SfxPoolItem**)&pScaleItem );
861 if ( SFX_ITEM_DEFAULT == eState )
862 pScaleItem = (const SfxUInt16Item*)
863 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE );
865 eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, false,
866 (const SfxPoolItem**)&pScaleToItem );
867 if ( SFX_ITEM_DEFAULT == eState )
868 pScaleToItem = (const ScPageScaleToItem*)
869 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO );
871 eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, false,
872 (const SfxPoolItem**)&pScaleToPagesItem );
873 if ( SFX_ITEM_DEFAULT == eState )
874 pScaleToPagesItem = (const SfxUInt16Item*)
875 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETOPAGES );
877 OSL_ENSURE( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" );
879 aTableParam.bCellContent = sal_True;
880 aTableParam.bNotes = GET_BOOL(pParamSet,ATTR_PAGE_NOTES);
881 aTableParam.bGrid = GET_BOOL(pParamSet,ATTR_PAGE_GRID);
882 aTableParam.bHeaders = GET_BOOL(pParamSet,ATTR_PAGE_HEADERS);
883 aTableParam.bFormulas = GET_BOOL(pParamSet,ATTR_PAGE_FORMULAS);
884 aTableParam.bNullVals = GET_BOOL(pParamSet,ATTR_PAGE_NULLVALS);
885 aTableParam.bCharts = GET_SHOW(pParamSet,ATTR_PAGE_CHARTS);
886 aTableParam.bObjects = GET_SHOW(pParamSet,ATTR_PAGE_OBJECTS);
887 aTableParam.bDrawings = GET_SHOW(pParamSet,ATTR_PAGE_DRAWINGS);
888 aTableParam.bTopDown = GET_BOOL(pParamSet,ATTR_PAGE_TOPDOWN);
889 aTableParam.bLeftRight = !aTableParam.bLeftRight;
890 aTableParam.nFirstPageNo = GET_USHORT(pParamSet,ATTR_PAGE_FIRSTPAGENO);
891 if (!aTableParam.nFirstPageNo)
892 aTableParam.nFirstPageNo = (sal_uInt16) nPageStart; // from previous table
894 if ( pScaleItem && pScaleToItem && pScaleToPagesItem )
896 sal_uInt16 nScaleAll = pScaleItem->GetValue();
897 sal_uInt16 nScaleToPages = pScaleToPagesItem->GetValue();
899 aTableParam.bScaleNone = (nScaleAll == 100);
900 aTableParam.bScaleAll = (nScaleAll > 0 );
901 aTableParam.bScaleTo = pScaleToItem->IsValid();
902 aTableParam.bScalePageNum = (nScaleToPages > 0 );
903 aTableParam.nScaleAll = nScaleAll;
904 aTableParam.nScaleWidth = pScaleToItem->GetWidth();
905 aTableParam.nScaleHeight = pScaleToItem->GetHeight();
906 aTableParam.nScalePageNum = nScaleToPages;
908 else
910 aTableParam.bScaleNone = sal_True;
911 aTableParam.bScaleAll = false;
912 aTableParam.bScaleTo = false;
913 aTableParam.bScalePageNum = false;
914 aTableParam.nScaleAll = 0;
915 aTableParam.nScaleWidth = 0;
916 aTableParam.nScaleHeight = 0;
917 aTableParam.nScalePageNum = 0;
920 // skip empty pages only if options with that flag are passed
921 aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty();
922 if ( pPageData )
923 aTableParam.bSkipEmpty = false;
924 // If pPageData is set, only the breaks are interesting for the
925 // pagebreak preview, empty pages are not addressed separately.
927 aTableParam.bForceBreaks = pOptions && pOptions->GetForceBreaks();
929 //------------------------------------------------------
930 // TabPage "Parts":
931 //------------------------------------------------------
933 //! walk throuch all PrintAreas of the table !!!
934 const ScRange* pPrintArea = pDoc->GetPrintRange( nPrintTab, 0 );
935 const ScRange* pRepeatCol = pDoc->GetRepeatColRange( nPrintTab );
936 const ScRange* pRepeatRow = pDoc->GetRepeatRowRange( nPrintTab );
938 // ignoring ATTR_PAGE_PRINTTABLES
940 if ( pUserArea ) // UserArea (selection) has prority
942 bPrintCurrentTable =
943 aAreaParam.bPrintArea = sal_True; // Selection
944 aAreaParam.aPrintArea = *pUserArea;
946 // The table-query is already in DocShell::Print, here always
947 aAreaParam.aPrintArea.aStart.SetTab(nPrintTab);
948 aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab);
950 else if ( pDoc->HasPrintRange() )
952 if ( pPrintArea ) // at least one set?
954 bPrintCurrentTable =
955 aAreaParam.bPrintArea = sal_True;
956 aAreaParam.aPrintArea = *pPrintArea;
958 bMultiArea = ( pDoc->GetPrintRangeCount(nPrintTab) > 1 );
960 else
962 // do not print hidden sheets with "Print entire sheet" flag
963 bPrintCurrentTable = pDoc->IsPrintEntireSheet( nPrintTab ) && pDoc->IsVisible( nPrintTab );
964 aAreaParam.bPrintArea = !bPrintCurrentTable; // otherwise the table is always counted
967 else
969 // don't print hidden tables if there's no print range defined there
970 if ( pDoc->IsVisible( nPrintTab ) )
972 aAreaParam.bPrintArea = false;
973 bPrintCurrentTable = sal_True;
975 else
977 aAreaParam.bPrintArea = sal_True; // otherwise the table is always counted
978 bPrintCurrentTable = false;
982 if ( pRepeatCol )
984 aAreaParam.bRepeatCol = sal_True;
985 aAreaParam.aRepeatCol = *pRepeatCol;
986 nRepeatStartCol = pRepeatCol->aStart.Col();
987 nRepeatEndCol = pRepeatCol->aEnd .Col();
989 else
991 aAreaParam.bRepeatCol = false;
992 nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE;
995 if ( pRepeatRow )
997 aAreaParam.bRepeatRow = sal_True;
998 aAreaParam.aRepeatRow = *pRepeatRow;
999 nRepeatStartRow = pRepeatRow->aStart.Row();
1000 nRepeatEndRow = pRepeatRow->aEnd .Row();
1002 else
1004 aAreaParam.bRepeatRow = false;
1005 nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE;
1009 // Split pages
1012 if (!bState)
1014 nTabPages = CountPages(); // also calculates zoom
1015 nTotalPages = nTabPages;
1016 nTotalPages += CountNotePages();
1018 else
1020 CalcPages(); // search breaks only
1021 CountNotePages(); // Count notes, even if number of pages is already known
1024 if (nDocPages)
1025 aFieldData.nTotalPages = nDocPages;
1026 else
1027 aFieldData.nTotalPages = nTotalPages;
1029 SetDateTime( Date( Date::SYSTEM ), Time( Time::SYSTEM ) );
1031 if( pDocShell->getDocProperties()->getTitle().getLength() != 0 )
1032 aFieldData.aTitle = pDocShell->getDocProperties()->getTitle();
1033 else
1034 aFieldData.aTitle = pDocShell->GetTitle();
1036 const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
1037 aFieldData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
1038 if ( !aFieldData.aLongDocName.isEmpty() )
1039 aFieldData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
1040 else
1041 aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle;
1043 // Printer settings (Orientation, Paper) at DoPrint
1046 Size ScPrintFunc::GetDataSize() const
1048 Size aSize = aPageSize;
1049 aSize.Width() -= nLeftMargin + nRightMargin;
1050 aSize.Height() -= nTopMargin + nBottomMargin;
1051 aSize.Height() -= aHdr.nHeight + aFtr.nHeight;
1052 return aSize;
1055 void ScPrintFunc::GetScaleData( Size& rPhysSize, long& rDocHdr, long& rDocFtr )
1057 rPhysSize = aPageSize;
1058 rPhysSize.Width() -= nLeftMargin + nRightMargin;
1059 rPhysSize.Height() -= nTopMargin + nBottomMargin;
1061 rDocHdr = aHdr.nHeight;
1062 rDocFtr = aFtr.nHeight;
1065 void ScPrintFunc::SetDateTime( const Date& rDate, const Time& rTime )
1067 aFieldData.aDate = rDate;
1068 aFieldData.aTime = rTime;
1071 static void lcl_DrawGraphic( const Graphic &rGraphic, OutputDevice *pOut,
1072 const Rectangle &rGrf, const Rectangle &rOut )
1074 const bool bNotInside = !rOut.IsInside( rGrf );
1075 if ( bNotInside )
1077 pOut->Push();
1078 pOut->IntersectClipRegion( rOut );
1081 ((Graphic&)rGraphic).Draw( pOut, rGrf.TopLeft(), rGrf.GetSize() );
1083 if ( bNotInside )
1084 pOut->Pop();
1087 static void lcl_DrawGraphic( const SvxBrushItem &rBrush, OutputDevice *pOut, OutputDevice* pRefDev,
1088 const Rectangle &rOrg, const Rectangle &rOut,
1089 OUString const & referer )
1091 Size aGrfSize(0,0);
1092 const Graphic *pGraphic = rBrush.GetGraphic(referer);
1093 SvxGraphicPosition ePos;
1094 if ( pGraphic && pGraphic->IsSupportedGraphic() )
1096 const MapMode aMapMM( MAP_100TH_MM );
1097 if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1098 aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM );
1099 else
1100 aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1101 pGraphic->GetPrefMapMode(), aMapMM );
1102 ePos = rBrush.GetGraphicPos();
1104 else
1105 ePos = GPOS_NONE;
1107 Point aPos;
1108 Size aDrawSize = aGrfSize;
1110 bool bDraw = true;
1111 switch ( ePos )
1113 case GPOS_LT: aPos = rOrg.TopLeft();
1114 break;
1115 case GPOS_MT: aPos.Y() = rOrg.Top();
1116 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1117 break;
1118 case GPOS_RT: aPos.Y() = rOrg.Top();
1119 aPos.X() = rOrg.Right() - aGrfSize.Width();
1120 break;
1122 case GPOS_LM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1123 aPos.X() = rOrg.Left();
1124 break;
1125 case GPOS_MM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1126 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1127 break;
1128 case GPOS_RM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1129 aPos.X() = rOrg.Right() - aGrfSize.Width();
1130 break;
1132 case GPOS_LB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1133 aPos.X() = rOrg.Left();
1134 break;
1135 case GPOS_MB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1136 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1137 break;
1138 case GPOS_RB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1139 aPos.X() = rOrg.Right() - aGrfSize.Width();
1140 break;
1142 case GPOS_AREA:
1143 aPos = rOrg.TopLeft();
1144 aDrawSize = rOrg.GetSize();
1145 break;
1146 case GPOS_TILED:
1148 // use GraphicObject::DrawTiled instead of an own loop
1149 // (pixel rounding is handled correctly, and a very small bitmap
1150 // is duplicated into a bigger one for better performance)
1152 GraphicObject aObject( *pGraphic );
1154 if( pOut->GetPDFWriter() &&
1155 (aObject.GetType() == GRAPHIC_BITMAP || aObject.GetType() == GRAPHIC_DEFAULT) )
1157 // For PDF export, every draw
1158 // operation for bitmaps takes a noticeable
1159 // amount of place (~50 characters). Thus,
1160 // optimize between tile bitmap size and
1161 // number of drawing operations here.
1163 // A_out
1164 // n_chars = k1 * ---------- + k2 * A_bitmap
1165 // A_bitmap
1167 // minimum n_chars is obtained for (derive for
1168 // A_bitmap, set to 0, take positive
1169 // solution):
1170 // k1
1171 // A_bitmap = Sqrt( ---- A_out )
1172 // k2
1174 // where k1 is the number of chars per draw
1175 // operation, and k2 is the number of chars
1176 // per bitmap pixel. This is approximately 50
1177 // and 7 for current PDF writer, respectively.
1179 const double k1( 50 );
1180 const double k2( 7 );
1181 const Size aSize( rOrg.GetSize() );
1182 const double Abitmap( k1/k2 * aSize.Width()*aSize.Height() );
1184 aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0),
1185 NULL, GRFMGR_DRAW_STANDARD,
1186 ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
1188 else
1190 aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0) );
1193 bDraw = false;
1195 break;
1197 case GPOS_NONE:
1198 bDraw = false;
1199 break;
1201 default: OSL_ENSURE( !pOut, "new Graphic position?" );
1203 Rectangle aGrf( aPos,aDrawSize );
1204 if ( bDraw && aGrf.IsOver( rOut ) )
1206 lcl_DrawGraphic( *pGraphic, pOut, aGrf, rOut );
1210 // Rahmen wird nach innen gezeichnet
1212 void ScPrintFunc::DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH,
1213 const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground,
1214 const SvxShadowItem* pShadow )
1216 //! direkte Ausgabe aus SvxBoxItem !!!
1218 if (pBorderData)
1219 if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() &&
1220 !pBorderData->GetRight() )
1221 pBorderData = NULL;
1223 if (!pBorderData && !pBackground && !pShadow)
1224 return; // nichts zu tun
1226 long nLeft = 0;
1227 long nRight = 0;
1228 long nTop = 0;
1229 long nBottom = 0;
1231 // aFrameRect - ouside around frame, without shadow
1232 if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1234 nLeft += (long) ( pShadow->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
1235 nRight += (long) ( pShadow->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
1236 nTop += (long) ( pShadow->CalcShadowSpace(SHADOW_TOP) * nScaleY );
1237 nBottom += (long) ( pShadow->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
1239 Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop),
1240 Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) );
1242 // center of frame, to paint lines through OutputData
1243 if (pBorderData)
1245 nLeft += (long) ( lcl_LineTotal(pBorderData->GetLeft()) * nScaleX / 2 );
1246 nRight += (long) ( lcl_LineTotal(pBorderData->GetRight()) * nScaleX / 2 );
1247 nTop += (long) ( lcl_LineTotal(pBorderData->GetTop()) * nScaleY / 2 );
1248 nBottom += (long) ( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 );
1250 long nEffHeight = nScrH - nTop - nBottom;
1251 long nEffWidth = nScrW - nLeft - nRight;
1252 if (nEffHeight<=0 || nEffWidth<=0)
1253 return; // enmpty
1255 if ( pBackground )
1257 if (pBackground->GetGraphicPos() != GPOS_NONE)
1259 OutputDevice* pRefDev;
1260 if ( bIsRender )
1261 pRefDev = pDev; // don't use printer for PDF
1262 else
1263 pRefDev = pDoc->GetPrinter(); // use printer also for preview
1264 OUString referer;
1265 if (pDocShell->HasName()) {
1266 referer = pDocShell->GetMedium()->GetName();
1268 lcl_DrawGraphic( *pBackground, pDev, pRefDev, aFrameRect, aFrameRect, referer );
1270 else
1272 pDev->SetFillColor(pBackground->GetColor());
1273 pDev->SetLineColor();
1274 pDev->DrawRect(aFrameRect);
1278 if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1280 pDev->SetFillColor(pShadow->GetColor());
1281 pDev->SetLineColor();
1282 long nShadowX = (long) ( pShadow->GetWidth() * nScaleX );
1283 long nShadowY = (long) ( pShadow->GetWidth() * nScaleY );
1284 switch (pShadow->GetLocation())
1286 case SVX_SHADOW_TOPLEFT:
1287 pDev->DrawRect( Rectangle(
1288 aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1289 aFrameRect.Right()-nShadowX, aFrameRect.Top() ) );
1290 pDev->DrawRect( Rectangle(
1291 aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1292 aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) );
1293 break;
1294 case SVX_SHADOW_TOPRIGHT:
1295 pDev->DrawRect( Rectangle(
1296 aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY,
1297 aFrameRect.Right()+nShadowX, aFrameRect.Top() ) );
1298 pDev->DrawRect( Rectangle(
1299 aFrameRect.Right(), aFrameRect.Top()-nShadowY,
1300 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) );
1301 break;
1302 case SVX_SHADOW_BOTTOMLEFT:
1303 pDev->DrawRect( Rectangle(
1304 aFrameRect.Left()-nShadowX, aFrameRect.Bottom(),
1305 aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) );
1306 pDev->DrawRect( Rectangle(
1307 aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY,
1308 aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) );
1309 break;
1310 case SVX_SHADOW_BOTTOMRIGHT:
1311 pDev->DrawRect( Rectangle(
1312 aFrameRect.Left()+nShadowX, aFrameRect.Bottom(),
1313 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1314 pDev->DrawRect( Rectangle(
1315 aFrameRect.Right(), aFrameRect.Top()+nShadowY,
1316 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1317 break;
1318 default:
1320 // added to avoid warnings
1325 if (pBorderData)
1327 ScDocument* pBorderDoc = new ScDocument( SCDOCMODE_UNDO );
1328 pBorderDoc->InitUndo( pDoc, 0,0, sal_True,sal_True );
1329 if (pBorderData)
1330 pBorderDoc->ApplyAttr( 0,0,0, *pBorderData );
1332 ScTableInfo aTabInfo;
1333 pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0,
1334 nScaleX, nScaleY, false, false );
1335 OSL_ENSURE(aTabInfo.mnArrCount,"nArrCount == 0");
1337 aTabInfo.mpRowInfo[1].nHeight = (sal_uInt16) nEffHeight;
1338 aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth =
1339 aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = (sal_uInt16) nEffWidth;
1341 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc, 0,
1342 nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY );
1343 aOutputData.SetUseStyleColor( bUseStyleColor );
1345 if (pBorderData)
1346 aOutputData.DrawFrame();
1348 delete pBorderDoc;
1352 void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY )
1354 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1355 long nLayoutSign = bLayoutRTL ? -1 : 1;
1357 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1358 long nOneX = aOnePixel.Width();
1359 long nOneY = aOnePixel.Height();
1360 SCCOL nCol;
1362 long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1363 long nEndY = nScrY + nHeight - nOneY;
1365 long nPosX = nScrX;
1366 if ( bLayoutRTL )
1368 for (nCol=nX1; nCol<=nX2; nCol++)
1369 nPosX += (long)( pDoc->GetColWidth( nCol, nPrintTab ) * nScaleX );
1371 else
1372 nPosX -= nOneX;
1373 long nPosY = nScrY - nOneY;
1374 OUString aText;
1376 for (nCol=nX1; nCol<=nX2; nCol++)
1378 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1379 if (nDocW)
1381 long nWidth = (long) (nDocW * nScaleX);
1382 long nEndX = nPosX + nWidth * nLayoutSign;
1384 pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1386 aText = ::ScColToAlpha( nCol);
1387 long nTextWidth = pDev->GetTextWidth(aText);
1388 long nTextHeight = pDev->GetTextHeight();
1389 long nAddX = ( nWidth - nTextWidth ) / 2;
1390 long nAddY = ( nHeight - nTextHeight ) / 2;
1391 long nTextPosX = nPosX+nAddX;
1392 if ( bLayoutRTL )
1393 nTextPosX -= nWidth;
1394 pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText );
1396 nPosX = nEndX;
1401 void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY )
1403 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1404 long nOneX = aOnePixel.Width();
1405 long nOneY = aOnePixel.Height();
1407 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1409 long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1410 long nEndX = nScrX + nWidth;
1411 long nPosX = nScrX;
1412 if ( !bLayoutRTL )
1414 nEndX -= nOneX;
1415 nPosX -= nOneX;
1417 long nPosY = nScrY - nOneY;
1418 OUString aText;
1420 for (SCROW nRow=nY1; nRow<=nY2; nRow++)
1422 sal_uInt16 nDocH = pDoc->GetRowHeight( nRow, nPrintTab );
1423 if (nDocH)
1425 long nHeight = (long) (nDocH * nScaleY);
1426 long nEndY = nPosY + nHeight;
1428 pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1430 aText = OUString::number( nRow+1 );
1431 long nTextWidth = pDev->GetTextWidth(aText);
1432 long nTextHeight = pDev->GetTextHeight();
1433 long nAddX = ( nWidth - nTextWidth ) / 2;
1434 long nAddY = ( nHeight - nTextHeight ) / 2;
1435 pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText );
1437 nPosY = nEndY;
1442 void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY,
1443 sal_Bool bRepCol, ScPreviewLocationData& rLocationData )
1445 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1446 long nOneX = aOnePixel.Width();
1447 long nOneY = aOnePixel.Height();
1449 long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1450 long nEndY = nScrY + nHeight - nOneY;
1452 long nPosX = nScrX - nOneX;
1453 for (SCCOL nCol=nX1; nCol<=nX2; nCol++)
1455 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1456 if (nDocW)
1457 nPosX += (long) (nDocW * nScaleX);
1459 Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY );
1460 rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol );
1463 void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY,
1464 sal_Bool bRepRow, ScPreviewLocationData& rLocationData )
1466 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1467 long nOneX = aOnePixel.Width();
1468 long nOneY = aOnePixel.Height();
1470 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1472 long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1473 long nEndX = nScrX + nWidth;
1474 if ( !bLayoutRTL )
1475 nEndX -= nOneX;
1477 long nPosY = nScrY - nOneY;
1478 nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1479 Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY );
1480 rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow );
1483 void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1484 long nScrX, long nScrY, sal_Bool bRepCol, sal_Bool bRepRow,
1485 ScPreviewLocationData& rLocationData )
1487 // get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer)
1489 Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1490 long nLogStX = aLogPos.X();
1491 long nLogStY = aLogPos.Y();
1493 SCCOL nCol;
1494 Point aTwipOffset;
1495 for (nCol=0; nCol<nX1; nCol++)
1496 aTwipOffset.X() -= pDoc->GetColWidth( nCol, nPrintTab );
1497 aTwipOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nPrintTab );
1499 Point aMMOffset( aTwipOffset );
1500 aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS);
1501 aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS);
1502 aMMOffset += Point( nLogStX, nLogStY );
1503 MapMode aDrawMapMode( MAP_100TH_MM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() );
1505 // get pixel rectangle
1507 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1508 long nOneX = aOnePixel.Width();
1509 long nOneY = aOnePixel.Height();
1511 long nPosX = nScrX - nOneX;
1512 for (nCol=nX1; nCol<=nX2; nCol++)
1514 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1515 if (nDocW)
1516 nPosX += (long) (nDocW * nScaleX);
1519 long nPosY = nScrY - nOneY;
1520 nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1521 Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY );
1522 rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ),
1523 bRepCol, bRepRow, aDrawMapMode );
1526 void ScPrintFunc::PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1527 long nScrX, long nScrY,
1528 sal_Bool bShLeft, sal_Bool bShTop, sal_Bool bShRight, sal_Bool bShBottom )
1530 // #i47547# nothing to do if the end of the print area is before the end of
1531 // the repeat columns/rows (don't use negative size for ScOutputData)
1532 if ( nX2 < nX1 || nY2 < nY1 )
1533 return;
1535 //! hand over Flag at FillInfo !!!!!
1536 ScRange aERange;
1537 sal_Bool bEmbed = pDoc->IsEmbedded();
1538 if (bEmbed)
1540 pDoc->GetEmbedded(aERange);
1541 pDoc->ResetEmbedded();
1544 Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1545 long nLogStX = aPos.X();
1546 long nLogStY = aPos.Y();
1548 // Assemble data
1550 ScTableInfo aTabInfo;
1551 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab,
1552 nScaleX, nScaleY, sal_True, aTableParam.bFormulas );
1553 lcl_HidePrint( aTabInfo, nX1, nX2 );
1555 if (bEmbed)
1556 pDoc->SetEmbedded(aERange);
1558 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nPrintTab,
1559 nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
1561 // #114135#
1562 aOutputData.SetDrawView( pDrawView );
1564 // test if all paint parts are hidden, then a paint is not necessary at all
1565 const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
1566 const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart()
1567 && pDrawView->getHideDraw() && pDrawView->getHideFormControl() );
1569 if(!bHideAllDrawingLayer)
1571 pDev->SetMapMode(aLogicMode);
1572 // don's set Clipping here (Mapmode is being moved)
1574 // #i72502#
1575 aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
1578 pDev->SetMapMode(aOffsetMode);
1580 aOutputData.SetShowFormulas( aTableParam.bFormulas );
1581 aOutputData.SetShowNullValues( aTableParam.bNullVals );
1582 aOutputData.SetUseStyleColor( bUseStyleColor );
1584 Color aGridColor( COL_BLACK );
1585 if ( bUseStyleColor )
1586 aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
1587 aOutputData.SetGridColor( aGridColor );
1589 if ( !pPrinter )
1591 OutputDevice* pRefDev = pDoc->GetPrinter(); // use the printer also for Preview
1592 Fraction aPrintFrac( nZoom, 100 ); // without nManualZoom
1593 // MapMode, as it would arrive at the printer:
1594 pRefDev->SetMapMode( MapMode( MAP_100TH_MM, Point(), aPrintFrac, aPrintFrac ) );
1596 // when rendering (PDF), don't use printer as ref device, but printer's MapMode
1597 // has to be set anyway, as charts still use it (#106409#)
1598 if ( !bIsRender )
1599 aOutputData.SetRefDevice( pRefDev );
1602 if( aTableParam.bCellContent )
1603 aOutputData.DrawBackground();
1605 pDev->SetClipRegion(Region(Rectangle(
1606 aPos, Size(aOutputData.GetScrW(), aOutputData.GetScrH()))));
1607 pDev->SetClipRegion();
1609 if( aTableParam.bCellContent )
1611 aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom );
1612 aOutputData.DrawFrame();
1613 aOutputData.DrawStrings();
1614 aOutputData.DrawEdit(false);
1617 if (aTableParam.bGrid)
1618 aOutputData.DrawGrid( sal_True, false ); // no page breaks
1620 aOutputData.AddPDFNotes(); // has no effect if not rendering PDF with notes enabled
1622 // test if all paint parts are hidden, then a paint is not necessary at all
1623 if(!bHideAllDrawingLayer)
1625 // #i72502#
1626 aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
1629 // #i72502#
1630 aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
1631 aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
1634 sal_Bool ScPrintFunc::IsMirror( long nPageNo ) // Mirror margins?
1636 SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1637 return ( eUsage == SVX_PAGE_MIRROR && (nPageNo & 1) );
1640 sal_Bool ScPrintFunc::IsLeft( long nPageNo ) // left foot notes?
1642 SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1643 sal_Bool bLeft;
1644 if (eUsage == SVX_PAGE_LEFT)
1645 bLeft = sal_True;
1646 else if (eUsage == SVX_PAGE_RIGHT)
1647 bLeft = false;
1648 else
1649 bLeft = (nPageNo & 1) != 0;
1650 return bLeft;
1653 void ScPrintFunc::MakeTableString()
1655 OUString aTmp;
1656 pDoc->GetName(nPrintTab, aTmp);
1657 aFieldData.aTabName = aTmp;
1660 void ScPrintFunc::MakeEditEngine()
1662 if (!pEditEngine)
1664 // can't use document's edit engine pool here,
1665 // because pool must have twips as default metric
1666 pEditEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), sal_True );
1668 pEditEngine->EnableUndo(false);
1669 //fdo#45869 we want text to be positioned as it would be for the the
1670 //high dpi printed output, not as would be ideal for the 96dpi preview
1671 //window itself
1672 pEditEngine->SetRefDevice(pPrinter ? pPrinter : pDoc->GetRefDevice());
1673 pEditEngine->SetWordDelimiters(
1674 ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
1675 pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
1676 pDoc->ApplyAsianEditSettings( *pEditEngine );
1677 pEditEngine->EnableAutoColor( bUseStyleColor );
1679 // Default-Set for alignment
1680 pEditDefaults = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
1682 const ScPatternAttr& rPattern = (const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN);
1683 rPattern.FillEditItemSet( pEditDefaults );
1684 // FillEditItemSet adjusts font height to 1/100th mm,
1685 // but for header/footer twips is needed, as in the PatternAttr:
1686 pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
1687 pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
1688 pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
1689 // dont use font color, because background color is not used
1690 //! there's no way to set the background for note pages
1691 pEditDefaults->ClearItem( EE_CHAR_COLOR );
1692 if (ScGlobal::IsSystemRTL())
1693 pEditDefaults->Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
1696 pEditEngine->SetData( aFieldData ); // Set page count etc.
1699 // nStartY = logic
1700 void ScPrintFunc::PrintHF( long nPageNo, sal_Bool bHeader, long nStartY,
1701 sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1703 const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr;
1705 pDev->SetMapMode( aTwipMode ); // Head-/Footlines in Twips
1707 sal_Bool bLeft = IsLeft(nPageNo) && !rParam.bShared;
1708 const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight;
1710 long nLineStartX = aPageRect.Left() + rParam.nLeft;
1711 long nLineEndX = aPageRect.Right() - rParam.nRight;
1712 long nLineWidth = nLineEndX - nLineStartX + 1;
1714 // Edit-Engine
1716 Point aStart( nLineStartX, nStartY );
1717 Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1718 if ( rParam.pBorder )
1720 long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(BOX_LINE_LEFT);
1721 long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(BOX_LINE_TOP);
1722 aStart.X() += nLeft;
1723 aStart.Y() += nTop;
1724 aPaperSize.Width() -= nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(BOX_LINE_RIGHT);
1725 aPaperSize.Height() -= nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
1728 if ( rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE )
1730 long nLeft = rParam.pShadow->CalcShadowSpace(SHADOW_LEFT);
1731 long nTop = rParam.pShadow->CalcShadowSpace(SHADOW_TOP);
1732 aStart.X() += nLeft;
1733 aStart.Y() += nTop;
1734 aPaperSize.Width() -= nLeft + rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT);
1735 aPaperSize.Height() -= nTop + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
1738 aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo;
1739 MakeEditEngine();
1741 pEditEngine->SetPaperSize(aPaperSize);
1743 // Frame / Background
1745 Point aBorderStart( nLineStartX, nStartY );
1746 Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1747 if ( rParam.bDynamic )
1749 // adjust here again, for even/odd head-/footlines
1750 // and probably other breaks by variable (page number etc.)
1752 long nMaxHeight = 0;
1753 nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) );
1754 nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) );
1755 nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) );
1756 if (rParam.pBorder)
1757 nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
1758 lcl_LineTotal( rParam.pBorder->GetBottom() ) +
1759 rParam.pBorder->GetDistance(BOX_LINE_TOP) +
1760 rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
1761 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
1762 nMaxHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
1763 rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
1765 if (nMaxHeight < rParam.nManHeight-rParam.nDistance)
1766 nMaxHeight = rParam.nManHeight-rParam.nDistance; // configured Minimum
1768 aBorderSize.Height() = nMaxHeight;
1771 if ( bDoPrint )
1773 double nOldScaleX = nScaleX;
1774 double nOldScaleY = nScaleY;
1775 nScaleX = nScaleY = 1.0; // output directly in Twips
1776 DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(),
1777 rParam.pBorder, rParam.pBack, rParam.pShadow );
1778 nScaleX = nOldScaleX;
1779 nScaleY = nOldScaleY;
1781 // Clipping for Text
1783 pDev->SetClipRegion(Region(Rectangle(aStart, aPaperSize)));
1785 // left
1787 const EditTextObject* pObject = pHFItem->GetLeftArea();
1788 if (pObject)
1790 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1791 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1792 Point aDraw = aStart;
1793 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1794 if (nDif > 0)
1795 aDraw.Y() += nDif / 2;
1796 pEditEngine->Draw( pDev, aDraw, 0 );
1799 // center
1801 pObject = pHFItem->GetCenterArea();
1802 if (pObject)
1804 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
1805 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1806 Point aDraw = aStart;
1807 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1808 if (nDif > 0)
1809 aDraw.Y() += nDif / 2;
1810 pEditEngine->Draw( pDev, aDraw, 0 );
1813 // right
1815 pObject = pHFItem->GetRightArea();
1816 if (pObject)
1818 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
1819 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1820 Point aDraw = aStart;
1821 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1822 if (nDif > 0)
1823 aDraw.Y() += nDif / 2;
1824 pEditEngine->Draw( pDev, aDraw, 0 );
1827 pDev->SetClipRegion();
1830 if ( pLocationData )
1832 Rectangle aHeaderRect( aBorderStart, aBorderSize );
1833 pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft );
1837 long ScPrintFunc::DoNotes( long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1839 if (bDoPrint)
1840 pDev->SetMapMode(aTwipMode);
1842 MakeEditEngine();
1843 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1844 pEditEngine->SetDefaults( *pEditDefaults );
1846 Font aMarkFont;
1847 ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
1848 ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).GetFont( aMarkFont, eColorMode );
1849 pDev->SetFont( aMarkFont );
1850 long nMarkLen = pDev->GetTextWidth(OUString("GW99999:"));
1851 // without Space-Char, because it rarle arrives there
1853 Size aDataSize = aPageRect.GetSize();
1854 if ( nMarkLen > aDataSize.Width() / 2 ) // everything much too small?
1855 nMarkLen = aDataSize.Width() / 2; // split the page appropriately
1856 aDataSize.Width() -= nMarkLen;
1858 pEditEngine->SetPaperSize( aDataSize );
1859 long nPosX = aPageRect.Left() + nMarkLen;
1860 long nPosY = aPageRect.Top();
1862 long nCount = 0;
1863 long nSize = aNotePosList.size();
1864 sal_Bool bOk;
1867 bOk = false;
1868 if ( nNoteStart + nCount < nSize)
1870 ScAddress &rPos = aNotePosList[ nNoteStart + nCount ];
1872 if( const ScPostIt* pNote = pDoc->GetNote( rPos ) )
1874 if(const EditTextObject *pEditText = pNote->GetEditTextObject())
1875 pEditEngine->SetText(*pEditText);
1876 long nTextHeight = pEditEngine->GetTextHeight();
1877 if ( nPosY + nTextHeight < aPageRect.Bottom() )
1879 if (bDoPrint)
1881 pEditEngine->Draw( pDev, Point( nPosX, nPosY ), 0 );
1883 OUString aMarkStr(rPos.Format(SCA_VALID, pDoc, pDoc->GetAddressConvention()));
1884 aMarkStr += ":";
1886 // cell position also via EditEngine, for correct positioning
1887 pEditEngine->SetText(aMarkStr);
1888 pEditEngine->Draw( pDev, Point( aPageRect.Left(), nPosY ), 0 );
1891 if ( pLocationData )
1893 Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) );
1894 pLocationData->AddNoteText( aTextRect, rPos );
1895 Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) );
1896 pLocationData->AddNoteMark( aMarkRect, rPos );
1899 nPosY += nTextHeight;
1900 nPosY += 200; // Distance
1901 ++nCount;
1902 bOk = sal_True;
1907 while (bOk);
1909 return nCount;
1912 long ScPrintFunc::PrintNotes( long nPageNo, long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1914 if ( nNoteStart >= (long) aNotePosList.size() || !aTableParam.bNotes )
1915 return 0;
1917 if ( bDoPrint && bClearWin )
1919 //! aggregate PrintPage !!!
1921 Color aBackgroundColor( COL_WHITE );
1922 if ( bUseStyleColor )
1923 aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1925 pDev->SetMapMode(aOffsetMode);
1926 pDev->SetLineColor();
1927 pDev->SetFillColor(aBackgroundColor);
1928 pDev->DrawRect(Rectangle(Point(),
1929 Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
1930 (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
1934 // adjust aPageRect for left/right page
1936 Rectangle aTempRect = Rectangle( Point(), aPageSize );
1937 if (IsMirror(nPageNo))
1939 aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
1940 aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
1942 else
1944 aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
1945 aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
1948 if ( pPrinter && bDoPrint )
1950 OSL_FAIL( "StartPage does not exist anymore" );
1953 if ( bDoPrint || pLocationData )
1955 // Head and foot lines
1957 if (aHdr.bEnable)
1959 long nHeaderY = aPageRect.Top()-aHdr.nHeight;
1960 PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
1962 if (aFtr.bEnable)
1964 long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
1965 PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
1969 long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData );
1971 if ( pPrinter && bDoPrint )
1973 OSL_FAIL( "EndPage does not exist anymore" );
1976 return nCount;
1979 void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1980 sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1982 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1983 long nLayoutSign = bLayoutRTL ? -1 : 1;
1985 // nPageNo is the page number within all sheets of one "start page" setting
1987 if ( bClearWin && bDoPrint )
1989 // must exactly fit to painting the frame in preview.cxx !!!
1991 Color aBackgroundColor( COL_WHITE );
1992 if ( bUseStyleColor )
1993 aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1995 pDev->SetMapMode(aOffsetMode);
1996 pDev->SetLineColor();
1997 pDev->SetFillColor(aBackgroundColor);
1998 pDev->DrawRect(Rectangle(Point(),
1999 Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
2000 (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
2004 // adjust aPageRect for left/right page
2006 Rectangle aTempRect = Rectangle( Point(), aPageSize );
2007 if (IsMirror(nPageNo))
2009 aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
2010 aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
2012 else
2014 aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
2015 aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
2018 if ( aAreaParam.bRepeatCol )
2019 if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol )
2020 nX1 = nRepeatEndCol + 1;
2021 sal_Bool bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol);
2022 if ( aAreaParam.bRepeatRow )
2023 if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow )
2024 nY1 = nRepeatEndRow + 1;
2025 sal_Bool bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow);
2027 // use new object hide flags in SdrPaintView
2028 if(pDrawView)
2030 pDrawView->setHideOle(!aTableParam.bObjects);
2031 pDrawView->setHideChart(!aTableParam.bCharts);
2032 pDrawView->setHideDraw(!aTableParam.bDrawings);
2033 pDrawView->setHideFormControl(!aTableParam.bDrawings);
2036 if ( pPrinter && bDoPrint )
2038 OSL_FAIL( "StartPage does not exist anymore" );
2041 // head and foot lines (without centering)
2043 if (aHdr.bEnable)
2045 long nHeaderY = aPageRect.Top()-aHdr.nHeight;
2046 PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
2048 if (aFtr.bEnable)
2050 long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
2051 PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
2054 // Position ( margins / centering )
2056 long nLeftSpace = aPageRect.Left(); // Document-Twips
2057 long nTopSpace = aPageRect.Top();
2058 if ( bCenterHor || bLayoutRTL )
2060 long nDataWidth = 0;
2061 SCCOL i;
2062 for (i=nX1; i<=nX2; i++)
2063 nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2064 if (bDoRepCol)
2065 for (i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2066 nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2067 if (aTableParam.bHeaders)
2068 nDataWidth += (long) PRINT_HEADER_WIDTH;
2069 if (pBorderItem)
2070 nDataWidth += pBorderItem->GetDistance(BOX_LINE_LEFT) +
2071 pBorderItem->GetDistance(BOX_LINE_RIGHT); //! Line width?
2072 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2073 nDataWidth += pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
2074 pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
2075 if ( bCenterHor )
2077 nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2; // LTR or RTL
2078 if (pBorderItem)
2079 nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft());
2081 else if ( bLayoutRTL )
2082 nLeftSpace += aPageRect.GetWidth() - nDataWidth; // align to the right edge of the page
2084 if ( bCenterVer )
2086 long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab);
2087 if (bDoRepRow)
2088 nDataHeight += pDoc->GetRowHeight( nRepeatStartRow,
2089 nRepeatEndRow, nPrintTab);
2090 if (aTableParam.bHeaders)
2091 nDataHeight += (long) PRINT_HEADER_HEIGHT;
2092 if (pBorderItem)
2093 nDataHeight += pBorderItem->GetDistance(BOX_LINE_TOP) +
2094 pBorderItem->GetDistance(BOX_LINE_BOTTOM); //! Line width?
2095 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2096 nDataHeight += pShadowItem->CalcShadowSpace(SHADOW_TOP) +
2097 pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
2098 nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2;
2099 if (pBorderItem)
2100 nTopSpace -= lcl_LineTotal(pBorderItem->GetTop());
2103 // calculate sizes of the elements for partitioning
2104 // (header, repeat, data)
2106 long nHeaderWidth = 0;
2107 long nHeaderHeight = 0;
2108 long nRepeatWidth = 0;
2109 long nRepeatHeight = 0;
2110 long nContentWidth = 0; // scaled - not the same as nDataWidth above
2111 long nContentHeight = 0;
2112 if (aTableParam.bHeaders)
2114 nHeaderWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
2115 nHeaderHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
2117 if (bDoRepCol)
2118 for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2119 nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2120 if (bDoRepRow)
2121 nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow,
2122 nRepeatEndRow, nPrintTab, nScaleY);
2123 for (SCCOL i=nX1; i<=nX2; i++)
2124 nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2125 nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab,
2126 nScaleY);
2128 // partition the page
2130 long nStartX = ((long) ( nLeftSpace * nScaleX ));
2131 long nStartY = ((long) ( nTopSpace * nScaleY ));
2132 long nInnerStartX = nStartX;
2133 long nInnerStartY = nStartY;
2134 if (pBorderItem)
2136 nInnerStartX += (long) ( ( lcl_LineTotal(pBorderItem->GetLeft()) +
2137 pBorderItem->GetDistance(BOX_LINE_LEFT) ) * nScaleX );
2138 nInnerStartY += (long) ( ( lcl_LineTotal(pBorderItem->GetTop()) +
2139 pBorderItem->GetDistance(BOX_LINE_TOP) ) * nScaleY );
2141 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2143 nInnerStartX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
2144 nInnerStartY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_TOP) * nScaleY );
2147 if ( bLayoutRTL )
2149 // arrange elements starting from the right edge
2150 nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth;
2152 // make rounding easier so the elements are really next to each other in preview
2153 Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode );
2154 long nOffsetOneX = aOffsetOnePixel.Width();
2155 nInnerStartX += nOffsetOneX / 2;
2158 long nFrameStartX = nInnerStartX;
2159 long nFrameStartY = nInnerStartY;
2161 long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign; // widths/heights are 0 if not used
2162 long nRepStartY = nInnerStartY + nHeaderHeight;
2163 long nDataX = nRepStartX + nRepeatWidth * nLayoutSign;
2164 long nDataY = nRepStartY + nRepeatHeight;
2165 long nEndX = nDataX + nContentWidth * nLayoutSign;
2166 long nEndY = nDataY + nContentHeight;
2167 long nFrameEndX = nEndX;
2168 long nFrameEndY = nEndY;
2170 if ( bLayoutRTL )
2172 // each element's start position is its left edge
2173 //! subtract one pixel less?
2174 nInnerStartX -= nHeaderWidth; // used for header
2175 nRepStartX -= nRepeatWidth;
2176 nDataX -= nContentWidth;
2178 // continue right of the main elements again
2179 nEndX += nHeaderWidth + nRepeatWidth + nContentWidth;
2182 // Page frame / background
2184 //! adjust nEndX/Y
2186 long nBorderEndX = nEndX;
2187 long nBorderEndY = nEndY;
2188 if (pBorderItem)
2190 nBorderEndX += (long) ( ( lcl_LineTotal(pBorderItem->GetRight()) +
2191 pBorderItem->GetDistance(BOX_LINE_RIGHT) ) * nScaleX );
2192 nBorderEndY += (long) ( ( lcl_LineTotal(pBorderItem->GetBottom()) +
2193 pBorderItem->GetDistance(BOX_LINE_BOTTOM) ) * nScaleY );
2195 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2197 nBorderEndX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
2198 nBorderEndY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
2201 if ( bDoPrint )
2203 pDev->SetMapMode( aOffsetMode );
2204 DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY,
2205 pBorderItem, pBackgroundItem, pShadowItem );
2207 pDev->SetMapMode( aTwipMode );
2210 pDev->SetMapMode( aOffsetMode );
2212 // Output repeating rows/columns
2214 if (bDoRepCol && bDoRepRow)
2216 if ( bDoPrint )
2217 PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2218 nRepStartX,nRepStartY, sal_True,sal_True,false,false );
2219 if ( pLocationData )
2220 LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2221 nRepStartX,nRepStartY, sal_True,sal_True, *pLocationData );
2223 if (bDoRepCol)
2225 if ( bDoPrint )
2226 PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY,
2227 sal_True,!bDoRepRow,false,sal_True );
2228 if ( pLocationData )
2229 LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, sal_True,false, *pLocationData );
2231 if (bDoRepRow)
2233 if ( bDoPrint )
2234 PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY,
2235 !bDoRepCol,sal_True,sal_True,false );
2236 if ( pLocationData )
2237 LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, false,sal_True, *pLocationData );
2240 // output data
2242 if ( bDoPrint )
2243 PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow,sal_True,sal_True );
2244 if ( pLocationData )
2245 LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, false,false, *pLocationData );
2247 // output column/row headers
2248 // after data (throug probably shadow)
2250 Color aGridColor( COL_BLACK );
2251 if ( bUseStyleColor )
2252 aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2254 if (aTableParam.bHeaders)
2256 if ( bDoPrint )
2258 pDev->SetLineColor( aGridColor );
2259 pDev->SetFillColor();
2260 pDev->SetMapMode(aOffsetMode);
2263 ScPatternAttr aPattern( pDoc->GetPool() );
2264 Font aFont;
2265 ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
2266 aPattern.GetFont( aFont, eColorMode, pDev );
2267 pDev->SetFont( aFont );
2269 if (bDoRepCol)
2271 if ( bDoPrint )
2272 PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY );
2273 if ( pLocationData )
2274 LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, sal_True, *pLocationData );
2276 if ( bDoPrint )
2277 PrintColHdr( nX1,nX2, nDataX,nInnerStartY );
2278 if ( pLocationData )
2279 LocateColHdr( nX1,nX2, nDataX,nInnerStartY, false, *pLocationData );
2280 if (bDoRepRow)
2282 if ( bDoPrint )
2283 PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY );
2284 if ( pLocationData )
2285 LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, sal_True, *pLocationData );
2287 if ( bDoPrint )
2288 PrintRowHdr( nY1,nY2, nInnerStartX,nDataY );
2289 if ( pLocationData )
2290 LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, false, *pLocationData );
2293 // simple frame
2295 if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) )
2297 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
2298 long nOneX = aOnePixel.Width();
2299 long nOneY = aOnePixel.Height();
2301 long nLeftX = nFrameStartX;
2302 long nTopY = nFrameStartY - nOneY;
2303 long nRightX = nFrameEndX;
2304 long nBottomY = nFrameEndY - nOneY;
2305 if ( !bLayoutRTL )
2307 nLeftX -= nOneX;
2308 nRightX -= nOneX;
2310 pDev->SetMapMode(aOffsetMode);
2311 pDev->SetLineColor( aGridColor );
2312 pDev->SetFillColor();
2313 pDev->DrawRect( Rectangle( nLeftX, nTopY, nRightX, nBottomY ) );
2314 // nEndX/Y without frame-adaption
2317 if ( pPrinter && bDoPrint )
2319 OSL_FAIL( "EndPage does not exist anymore" );
2322 aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab );
2323 bSourceRangeValid = sal_True;
2326 void ScPrintFunc::SetOffset( const Point& rOfs )
2328 aSrcOffset = rOfs;
2331 void ScPrintFunc::SetManualZoom( sal_uInt16 nNewZoom )
2333 nManualZoom = nNewZoom;
2336 void ScPrintFunc::SetClearFlag( sal_Bool bFlag )
2338 bClearWin = bFlag;
2341 void ScPrintFunc::SetUseStyleColor( sal_Bool bFlag )
2343 bUseStyleColor = bFlag;
2344 if (pEditEngine)
2345 pEditEngine->EnableAutoColor( bUseStyleColor );
2348 void ScPrintFunc::SetRenderFlag( sal_Bool bFlag )
2350 bIsRender = bFlag; // set when using XRenderable (PDF)
2353 void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects()
2355 aTableParam.bCellContent = false;
2356 aTableParam.bNotes = false;
2357 aTableParam.bGrid = false;
2358 aTableParam.bHeaders = false;
2359 aTableParam.bFormulas = false;
2360 aTableParam.bNullVals = false;
2364 // UpdatePages is only called from outside to set the breaks correctly for viewing
2365 // - always without UserArea
2368 sal_Bool ScPrintFunc::UpdatePages()
2370 if (!pParamSet)
2371 return false;
2373 // Zoom
2375 nZoom = 100;
2376 if (aTableParam.bScalePageNum || aTableParam.bScaleTo)
2377 nZoom = ZOOM_MIN; // correct for breaks
2378 else if (aTableParam.bScaleAll)
2380 nZoom = aTableParam.nScaleAll;
2381 if ( nZoom <= ZOOM_MIN )
2382 nZoom = ZOOM_MIN;
2385 OUString aName = pDoc->GetPageStyle( nPrintTab );
2386 SCTAB nTabCount = pDoc->GetTableCount();
2387 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
2388 if ( nTab==nPrintTab || pDoc->GetPageStyle(nTab)==aName )
2390 // Repeating rows/columns
2391 pDoc->SetRepeatArea( nTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2393 // set breaks
2394 ResetBreaks(nTab);
2395 pDocShell->PostPaint(0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID);
2398 return sal_True;
2401 long ScPrintFunc::CountPages() // sets also nPagesX, nPagesY
2403 sal_Bool bAreaOk = false;
2405 if (pDoc->HasTable( nPrintTab ))
2407 if (aAreaParam.bPrintArea) // Specify print area?
2409 if ( bPrintCurrentTable )
2411 ScRange& rRange = aAreaParam.aPrintArea;
2413 // Here, no comparison of the tables any more. Area is always valid for this table
2414 // If comparison should be done here, the table of print ranges must be adjusted
2415 // when inserting tables etc.!
2417 nStartCol = rRange.aStart.Col();
2418 nStartRow = rRange.aStart.Row();
2419 nEndCol = rRange.aEnd .Col();
2420 nEndRow = rRange.aEnd .Row();
2421 bAreaOk = AdjustPrintArea(false); // limit
2423 else
2424 bAreaOk = false;
2426 else // search from document
2427 bAreaOk = AdjustPrintArea(sal_True);
2430 if (bAreaOk)
2432 long nPages = 0;
2433 size_t nY;
2434 if (bMultiArea)
2436 sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
2437 for (sal_uInt16 i=0; i<nRCount; i++)
2439 CalcZoom(i);
2440 if ( aTableParam.bSkipEmpty )
2441 for (nY=0; nY<nPagesY; nY++)
2442 nPages += pPageRows[nY].CountVisible();
2443 else
2444 nPages += ((long) nPagesX) * nPagesY;
2445 if ( pPageData )
2446 FillPageData();
2449 else
2451 CalcZoom(RANGENO_NORANGE); // calculate Zoom
2452 if ( aTableParam.bSkipEmpty )
2453 for (nY=0; nY<nPagesY; nY++)
2454 nPages += pPageRows[nY].CountVisible();
2455 else
2456 nPages += ((long) nPagesX) * nPagesY;
2457 if ( pPageData )
2458 FillPageData();
2460 return nPages;
2462 else
2464 nPagesX = nPagesY = nTotalY = 0;
2465 return 0;
2469 long ScPrintFunc::CountNotePages()
2471 if ( !aTableParam.bNotes || !bPrintCurrentTable )
2472 return 0;
2474 sal_Bool bError = false;
2475 if (!aAreaParam.bPrintArea)
2476 bError = !AdjustPrintArea(sal_True); // completely search in Doc
2478 sal_uInt16 nRepeats = 1; // how often go through it ?
2479 if (bMultiArea)
2480 nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2481 if (bError)
2482 nRepeats = 0;
2484 for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2486 sal_Bool bDoThis = sal_True;
2487 if (bMultiArea) // go through all Areas
2489 const ScRange* pThisRange = pDoc->GetPrintRange( nPrintTab, nStep );
2490 if ( pThisRange )
2492 nStartCol = pThisRange->aStart.Col();
2493 nStartRow = pThisRange->aStart.Row();
2494 nEndCol = pThisRange->aEnd .Col();
2495 nEndRow = pThisRange->aEnd .Row();
2496 bDoThis = AdjustPrintArea(false);
2500 if (bDoThis)
2502 for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
2504 if (pDoc->HasColNotes(nCol, nPrintTab))
2506 for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
2508 if ( pDoc->HasNote(nCol, nRow, nPrintTab) )
2509 aNotePosList.push_back( ScAddress( nCol, nRow, nPrintTab ) );
2516 long nPages = 0;
2517 long nNoteNr = 0;
2518 long nNoteAdd;
2521 nNoteAdd = PrintNotes( nPages, nNoteNr, false, NULL );
2522 if (nNoteAdd)
2524 nNoteNr += nNoteAdd;
2525 ++nPages;
2528 while (nNoteAdd);
2530 return nPages;
2533 void ScPrintFunc::InitModes() // set MapModes from nZoom etc.
2535 aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom );
2537 long nEffZoom = nZoom * (long) nManualZoom;
2538 nScaleX = nScaleY = HMM_PER_TWIPS; // output in 1/100 mm
2540 Fraction aZoomFract( nEffZoom,10000 );
2541 Fraction aHorFract = aZoomFract;
2543 if ( !pPrinter && !bIsRender ) // adjust scale for preview
2545 double nFact = pDocShell->GetOutputFactor();
2546 aHorFract = Fraction( (long)( nEffZoom / nFact ), 10000 );
2549 aLogicMode = MapMode( MAP_100TH_MM, Point(), aHorFract, aZoomFract );
2551 Point aLogicOfs( -aOffset.X(), -aOffset.Y() );
2552 aOffsetMode = MapMode( MAP_100TH_MM, aLogicOfs, aHorFract, aZoomFract );
2554 Point aTwipsOfs( (long) ( -aOffset.X() / nScaleX + 0.5 ), (long) ( -aOffset.Y() / nScaleY + 0.5 ) );
2555 aTwipMode = MapMode( MAP_TWIP, aTwipsOfs, aHorFract, aZoomFract );
2558 //--------------------------------------------------------------------
2560 void ScPrintFunc::ApplyPrintSettings()
2562 if ( pPrinter )
2565 // Configure Printer to Printing
2568 Size aEnumSize = aPageSize;
2571 pPrinter->SetOrientation( bLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT );
2572 if ( bLandscape )
2574 // landscape is always interpreted as a rotation by 90 degrees !
2575 // this leads to non WYSIWIG but at least it prints!
2576 // #i21775#
2577 long nTemp = aEnumSize.Width();
2578 aEnumSize.Width() = aEnumSize.Height();
2579 aEnumSize.Height() = nTemp;
2581 Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, sal_True );
2582 sal_uInt16 nPaperBin = ((const SvxPaperBinItem&)pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue();
2584 pPrinter->SetPaper( ePaper );
2585 if ( PAPER_USER == ePaper )
2587 MapMode aPrinterMode = pPrinter->GetMapMode();
2588 MapMode aLocalMode( MAP_TWIP );
2589 pPrinter->SetMapMode( aLocalMode );
2590 pPrinter->SetPaperSizeUser( aEnumSize );
2591 pPrinter->SetMapMode( aPrinterMode );
2594 pPrinter->SetPaperBin( nPaperBin );
2598 //--------------------------------------------------------------------
2599 // rPageRanges = range for all tables
2600 // nStartPage = rPageRanges starts at nStartPage
2601 // nDisplayStart = continious number for displaying the page number
2603 long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges,
2604 long nStartPage, long nDisplayStart, bool bDoPrint,
2605 ScPreviewLocationData* pLocationData )
2607 OSL_ENSURE(pDev,"Device == NULL");
2608 if (!pParamSet)
2609 return 0;
2611 if ( pPrinter && bDoPrint )
2612 ApplyPrintSettings();
2614 //--------------------------------------------------------------------
2616 InitModes();
2617 if ( pLocationData )
2619 pLocationData->SetCellMapMode( aOffsetMode );
2620 pLocationData->SetPrintTab( nPrintTab );
2623 MakeTableString();
2625 //--------------------------------------------------------------------
2627 long nPageNo = 0;
2628 long nPrinted = 0;
2629 long nEndPage = rPageRanges.GetTotalRange().Max();
2631 sal_uInt16 nRepeats = 1;
2632 if (bMultiArea)
2633 nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2634 for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2636 if (bMultiArea) // replace area
2638 CalcZoom(nStep); // also sets nStartCol etc. new
2639 InitModes();
2642 SCCOL nX1;
2643 SCROW nY1;
2644 SCCOL nX2;
2645 SCROW nY2;
2646 size_t nCountX;
2647 size_t nCountY;
2649 if (aTableParam.bTopDown) // top-bottom
2651 nX1 = nStartCol;
2652 for (nCountX=0; nCountX<nPagesX; nCountX++)
2654 nX2 = pPageEndX[nCountX];
2655 for (nCountY=0; nCountY<nPagesY; nCountY++)
2657 nY1 = pPageRows[nCountY].GetStartRow();
2658 nY2 = pPageRows[nCountY].GetEndRow();
2659 if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
2661 if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2663 PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2664 bDoPrint, pLocationData );
2665 ++nPrinted;
2667 ++nPageNo;
2670 nX1 = nX2 + 1;
2673 else // left to right
2675 for (nCountY=0; nCountY<nPagesY; nCountY++)
2677 nY1 = pPageRows[nCountY].GetStartRow();
2678 nY2 = pPageRows[nCountY].GetEndRow();
2679 nX1 = nStartCol;
2680 for (nCountX=0; nCountX<nPagesX; nCountX++)
2682 nX2 = pPageEndX[nCountX];
2683 if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
2685 if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2687 PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2688 bDoPrint, pLocationData );
2689 ++nPrinted;
2691 ++nPageNo;
2693 nX1 = nX2 + 1;
2699 aFieldData.aTabName = ScGlobal::GetRscString( STR_NOTES );
2701 long nNoteNr = 0;
2702 long nNoteAdd;
2705 if ( nPageNo+nStartPage <= nEndPage )
2707 sal_Bool bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 );
2708 nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected,
2709 ( bPageSelected ? pLocationData : NULL ) );
2710 if ( nNoteAdd )
2712 nNoteNr += nNoteAdd;
2713 if (bPageSelected)
2715 ++nPrinted;
2716 bSourceRangeValid = false; // last page was no cell range
2718 ++nPageNo;
2721 else
2722 nNoteAdd = 0;
2724 while (nNoteAdd);
2726 if ( bMultiArea )
2727 ResetBreaks(nPrintTab); //breaks correct for displaying
2729 return nPrinted;
2732 void ScPrintFunc::CalcZoom( sal_uInt16 nRangeNo ) // calculate zoom
2734 sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
2735 const ScRange* pThisRange = NULL;
2736 if ( nRangeNo != RANGENO_NORANGE || nRangeNo < nRCount )
2737 pThisRange = pDoc->GetPrintRange( nPrintTab, nRangeNo );
2738 if ( pThisRange )
2740 nStartCol = pThisRange->aStart.Col();
2741 nStartRow = pThisRange->aStart.Row();
2742 nEndCol = pThisRange->aEnd .Col();
2743 nEndRow = pThisRange->aEnd .Row();
2746 if (!AdjustPrintArea(false)) // empty
2748 nZoom = 100;
2749 nPagesX = nPagesY = nTotalY = 0;
2750 return;
2753 pDoc->SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2755 if (aTableParam.bScalePageNum)
2757 nZoom = 100;
2758 sal_uInt16 nPagesToFit = aTableParam.nScalePageNum;
2760 // If manual breaks are forced, calculate minimum # pages required
2761 if (aTableParam.bForceBreaks)
2763 sal_uInt16 nMinPages = 0;
2764 std::set<SCROW> aRowBreaks;
2765 std::set<SCCOL> aColBreaks;
2766 pDoc->GetAllRowBreaks(aRowBreaks, nPrintTab, false, true);
2767 pDoc->GetAllColBreaks(aColBreaks, nPrintTab, false, true);
2768 nMinPages = (aRowBreaks.size() + 1) * (aColBreaks.size() + 1);
2770 // #i54993# use min forced by breaks if it's > # pages in
2771 // scale parameter to avoid bottoming out at <= ZOOM_MIN
2772 nPagesToFit = nMinPages > nPagesToFit ? nMinPages : nPagesToFit;
2775 sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2776 while (true)
2778 if (nZoom <= ZOOM_MIN)
2779 break;
2781 CalcPages();
2782 bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit);
2784 if (bFitsPage)
2786 if (nZoom == 100)
2787 // If it fits at 100 %, it's good enough for me.
2788 break;
2790 nLastFitZoom = nZoom;
2791 nZoom = (nLastNonFitZoom + nZoom) / 2;
2793 if (nLastFitZoom == nZoom)
2794 // It converged. Use this zoom level.
2795 break;
2797 else
2799 if (nZoom - nLastFitZoom <= 1)
2801 nZoom = nLastFitZoom;
2802 CalcPages();
2803 break;
2806 nLastNonFitZoom = nZoom;
2807 nZoom = (nLastFitZoom + nZoom) / 2;
2811 else if (aTableParam.bScaleTo)
2813 nZoom = 100;
2814 sal_uInt16 nW = aTableParam.nScaleWidth;
2815 sal_uInt16 nH = aTableParam.nScaleHeight;
2817 // If manual breaks are forced, calculate minimum # pages required
2818 if (aTableParam.bForceBreaks)
2820 sal_uInt16 nMinPagesW = 0, nMinPagesH = 0;
2821 std::set<SCROW> aRowBreaks;
2822 std::set<SCCOL> aColBreaks;
2823 pDoc->GetAllRowBreaks(aRowBreaks, nPrintTab, false, true);
2824 pDoc->GetAllColBreaks(aColBreaks, nPrintTab, false, true);
2825 nMinPagesW = aColBreaks.size() + 1;
2826 nMinPagesH = aRowBreaks.size() + 1;
2828 // #i54993# use min forced by breaks if it's > # pages in
2829 // scale parameters to avoid bottoming out at <= ZOOM_MIN
2830 nW = nMinPagesW > nW ? nMinPagesW : nW;
2831 nH = nMinPagesH > nH ? nMinPagesH : nH;
2834 sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2835 while (true)
2837 if (nZoom <= ZOOM_MIN)
2838 break;
2840 CalcPages();
2841 bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH)));
2843 if (bFitsPage)
2845 if (nZoom == 100)
2846 // If it fits at 100 %, it's good enough for me.
2847 break;
2849 nLastFitZoom = nZoom;
2850 nZoom = (nLastNonFitZoom + nZoom) / 2;
2852 if (nLastFitZoom == nZoom)
2853 // It converged. Use this zoom level.
2854 break;
2856 else
2858 if (nZoom - nLastFitZoom <= 1)
2860 nZoom = nLastFitZoom;
2861 CalcPages();
2862 break;
2865 nLastNonFitZoom = nZoom;
2866 nZoom = (nLastFitZoom + nZoom) / 2;
2870 else if (aTableParam.bScaleAll)
2872 nZoom = aTableParam.nScaleAll;
2873 if ( nZoom <= ZOOM_MIN )
2874 nZoom = ZOOM_MIN;
2875 CalcPages();
2877 else
2879 OSL_ENSURE( aTableParam.bScaleNone, "kein Scale-Flag gesetzt" );
2880 nZoom = 100;
2881 CalcPages();
2885 Size ScPrintFunc::GetDocPageSize()
2887 // Adjust height of head/foot line
2889 InitModes(); // initialize aTwipMode from nZoom
2890 pDev->SetMapMode( aTwipMode ); // head/foot line in Twips
2891 UpdateHFHeight( aHdr );
2892 UpdateHFHeight( aFtr );
2894 // Page size in Document-Twips
2895 // Calculating Left / Right also in PrintPage
2897 aPageRect = Rectangle( Point(), aPageSize );
2898 aPageRect.Left() = ( aPageRect.Left() + nLeftMargin ) * 100 / nZoom;
2899 aPageRect.Right() = ( aPageRect.Right() - nRightMargin ) * 100 / nZoom;
2900 aPageRect.Top() = ( aPageRect.Top() + nTopMargin ) * 100 / nZoom + aHdr.nHeight;
2901 aPageRect.Bottom() = ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight;
2903 Size aDocPageSize = aPageRect.GetSize();
2904 if (aTableParam.bHeaders)
2906 aDocPageSize.Width() -= (long) PRINT_HEADER_WIDTH;
2907 aDocPageSize.Height() -= (long) PRINT_HEADER_HEIGHT;
2909 if (pBorderItem)
2911 aDocPageSize.Width() -= lcl_LineTotal(pBorderItem->GetLeft()) +
2912 lcl_LineTotal(pBorderItem->GetRight()) +
2913 pBorderItem->GetDistance(BOX_LINE_LEFT) +
2914 pBorderItem->GetDistance(BOX_LINE_RIGHT);
2915 aDocPageSize.Height() -= lcl_LineTotal(pBorderItem->GetTop()) +
2916 lcl_LineTotal(pBorderItem->GetBottom()) +
2917 pBorderItem->GetDistance(BOX_LINE_TOP) +
2918 pBorderItem->GetDistance(BOX_LINE_BOTTOM);
2920 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2922 aDocPageSize.Width() -= pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
2923 pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
2924 aDocPageSize.Height() -= pShadowItem->CalcShadowSpace(SHADOW_TOP) +
2925 pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
2927 return aDocPageSize;
2930 void ScPrintFunc::ResetBreaks( SCTAB nTab ) // Set Breaks correctly for view
2932 pDoc->SetPageSize( nTab, GetDocPageSize() );
2933 pDoc->UpdatePageBreaks( nTab, NULL );
2936 static void lcl_SetHidden( ScDocument* pDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry,
2937 SCCOL nStartCol, const SCCOL* pPageEndX )
2939 size_t nPagesX = rPageRowEntry.GetPagesX();
2940 SCROW nStartRow = rPageRowEntry.GetStartRow();
2941 SCROW nEndRow = rPageRowEntry.GetEndRow();
2943 sal_Bool bLeftIsEmpty = false;
2944 ScRange aTempRange;
2945 Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 );
2947 for (size_t i=0; i<nPagesX; i++)
2949 SCCOL nEndCol = pPageEndX[i];
2950 if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow,
2951 bLeftIsEmpty, &aTempRange, &aTempRect ) )
2953 rPageRowEntry.SetHidden(i);
2954 bLeftIsEmpty = sal_True;
2956 else
2957 bLeftIsEmpty = false;
2959 nStartCol = nEndCol+1;
2963 void ScPrintFunc::CalcPages() // calculates aPageRect and pages from nZoom
2965 if (!pPageEndX) pPageEndX = new SCCOL[MAXCOL+1];
2966 //performance impact
2967 // if (!pPageEndY) pPageEndY = new SCROW[MAXROW+1];
2968 // if (!pPageRows) pPageRows = new ScPageRowEntry[MAXROW+1]; //! count before !!!!
2970 pDoc->SetPageSize( nPrintTab, GetDocPageSize() );
2971 if (aAreaParam.bPrintArea)
2973 ScRange aRange( nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab );
2974 pDoc->UpdatePageBreaks( nPrintTab, &aRange );
2976 else
2977 pDoc->UpdatePageBreaks( nPrintTab, NULL ); // else, end is marked
2978 SCROW nRealCnt = nEndRow-nStartRow+1;
2979 if (!pPageEndY) pPageEndY = new SCROW[nRealCnt+1];
2980 if (!pPageRows) pPageRows = new ScPageRowEntry[nRealCnt+1]; //! vorher zaehlen !!!!
2982 // Page alignment/splitting after breaks in Col/RowFlags
2983 // Of several breaks in a hidden area, only one counts.
2986 nPagesX = 0;
2987 nPagesY = 0;
2988 nTotalY = 0;
2990 bool bVisCol = false;
2991 for (SCCOL i=nStartCol; i<=nEndCol; i++)
2993 bool bHidden = pDoc->ColHidden(i, nPrintTab);
2994 bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE);
2995 if ( i>nStartCol && bVisCol && bPageBreak )
2997 pPageEndX[nPagesX] = i-1;
2998 ++nPagesX;
2999 bVisCol = false;
3001 if (!bHidden)
3002 bVisCol = true;
3004 if (bVisCol) // also at the end, no empty pages
3006 pPageEndX[nPagesX] = nEndCol;
3007 ++nPagesX;
3010 bool bVisRow = false;
3011 SCROW nPageStartRow = nStartRow;
3012 SCROW nLastVisibleRow = -1;
3014 ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab));
3015 SCROW nNextPageBreak = pRowBreakIter->first();
3016 while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow)
3017 // Skip until the page break position is at the start row or greater.
3018 nNextPageBreak = pRowBreakIter->next();
3020 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
3022 bool bPageBreak = (nNextPageBreak == nRow);
3023 if (bPageBreak)
3024 nNextPageBreak = pRowBreakIter->next();
3026 if (nRow > nStartRow && bVisRow && bPageBreak )
3028 pPageEndY[nTotalY] = nRow-1;
3029 ++nTotalY;
3031 if ( !aTableParam.bSkipEmpty ||
3032 !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) )
3034 pPageRows[nPagesY].SetStartRow( nPageStartRow );
3035 pPageRows[nPagesY].SetEndRow( nRow-1 );
3036 pPageRows[nPagesY].SetPagesX( nPagesX );
3037 if (aTableParam.bSkipEmpty)
3038 lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX );
3039 ++nPagesY;
3042 nPageStartRow = nRow;
3043 bVisRow = false;
3046 if (nRow <= nLastVisibleRow)
3048 // This row is still visible. Don't bother calling RowHidden() to
3049 // find out, for speed optimization.
3050 bVisRow = true;
3051 continue;
3054 SCROW nLastRow = -1;
3055 if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow))
3057 bVisRow = true;
3058 nLastVisibleRow = nLastRow;
3060 else
3061 // skip all hidden rows.
3062 nRow = nLastRow;
3065 if (bVisRow)
3067 pPageEndY[nTotalY] = nEndRow;
3068 ++nTotalY;
3070 if ( !aTableParam.bSkipEmpty ||
3071 !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) )
3073 pPageRows[nPagesY].SetStartRow( nPageStartRow );
3074 pPageRows[nPagesY].SetEndRow( nEndRow );
3075 pPageRows[nPagesY].SetPagesX( nPagesX );
3076 if (aTableParam.bSkipEmpty)
3077 lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX );
3078 ++nPagesY;
3083 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */