fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / view / printfun.cxx
blob1e9f4d0c2f0b2c607631bb2cd77a1c2397cb20f9
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) static_cast<const SfxBoolItem&>((set)->Get((which))).GetValue()
79 #define GET_USHORT(set,which) static_cast<const SfxUInt16Item&>((set)->Get((which))).GetValue()
80 #define GET_SHOW(set,which) ( VOBJ_MODE_SHOW == ScVObjMode( static_cast<const ScViewObjectModeItem&>((set)->Get((which))).GetValue()) )
82 ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r)
84 nStartRow = r.nStartRow;
85 nEndRow = r.nEndRow;
86 nPagesX = r.nPagesX;
87 if (r.pHidden && nPagesX)
89 pHidden = new bool[nPagesX];
90 memcpy( pHidden, r.pHidden, nPagesX * sizeof(bool) );
92 else
93 pHidden = NULL;
96 const ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r)
98 delete[] pHidden;
100 nStartRow = r.nStartRow;
101 nEndRow = r.nEndRow;
102 nPagesX = r.nPagesX;
103 if (r.pHidden && nPagesX)
105 pHidden = new bool[nPagesX];
106 memcpy( pHidden, r.pHidden, nPagesX * sizeof(bool) );
108 else
109 pHidden = NULL;
111 return *this;
114 void ScPageRowEntry::SetPagesX(size_t nNew)
116 if (pHidden)
118 OSL_FAIL("SetPagesX nicht nach SetHidden");
119 delete[] pHidden;
120 pHidden = NULL;
122 nPagesX = nNew;
125 void ScPageRowEntry::SetHidden(size_t nX)
127 if ( nX < nPagesX )
129 if ( nX+1 == nPagesX ) // last page?
130 --nPagesX;
131 else
133 if (!pHidden)
135 pHidden = new bool[nPagesX];
136 memset( pHidden, false, nPagesX * sizeof(bool) );
138 pHidden[nX] = true;
143 bool ScPageRowEntry::IsHidden(size_t nX) const
145 return nX>=nPagesX || ( pHidden && pHidden[nX] ); //! inline?
148 size_t ScPageRowEntry::CountVisible() const
150 if ( pHidden )
152 size_t nVis = 0;
153 for (size_t i=0; i<nPagesX; i++)
154 if (!pHidden[i])
155 ++nVis;
156 return nVis;
158 else
159 return nPagesX;
162 static long lcl_LineTotal(const ::editeng::SvxBorderLine* pLine)
164 return pLine ? ( pLine->GetScaledWidth() ) : 0;
167 void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
169 pDocShell->UpdatePendingRowHeights( nPrintTab );
170 pDoc = &pDocShell->GetDocument();
172 SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // use the printer, even for preview
173 if (pDocPrinter)
174 aOldPrinterMode = pDocPrinter->GetMapMode();
176 // unified MapMode for all calls (e.g. Repaint!!!)
177 // else, EditEngine outputs different text heights
178 pDev->SetMapMode(MAP_PIXEL);
180 pBorderItem = NULL;
181 pBackgroundItem = NULL;
182 pShadowItem = NULL;
184 pEditEngine = NULL;
185 pEditDefaults = NULL;
187 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
188 SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
189 pDoc->GetPageStyle( nPrintTab ),
190 SFX_STYLE_FAMILY_PAGE );
191 if (pStyleSheet)
192 pParamSet = &pStyleSheet->GetItemSet();
193 else
195 OSL_FAIL("Seitenvorlage nicht gefunden" );
196 pParamSet = NULL;
199 if (!bState)
200 nZoom = 100;
201 nManualZoom = 100;
202 bClearWin = false;
203 bUseStyleColor = false;
204 bIsRender = false;
206 InitParam(pOptions);
208 pPageData = NULL; // wird nur zur Initialisierung gebraucht
211 ScPrintFunc::ScPrintFunc( ScDocShell* pShell, SfxPrinter* pNewPrinter, SCTAB nTab,
212 long nPage, long nDocP, const ScRange* pArea,
213 const ScPrintOptions* pOptions,
214 ScPageBreakData* pData )
215 : pDocShell ( pShell ),
216 pPrinter ( pNewPrinter ),
217 pDrawView ( NULL ),
218 nPrintTab ( nTab ),
219 nPageStart ( nPage ),
220 nDocPages ( nDocP ),
221 pUserArea ( pArea ),
222 bState ( false ),
223 bSourceRangeValid ( false ),
224 bPrintCurrentTable ( false ),
225 bMultiArea ( false ),
226 mbHasPrintRange(true),
227 nTabPages ( 0 ),
228 nTotalPages ( 0 ),
229 nPagesX(0),
230 nPagesY(0),
231 nTotalY(0),
232 pPageData ( pData )
234 pDev = pPrinter.get();
235 aSrcOffset = pPrinter->PixelToLogic( pPrinter->GetPageOffsetPixel(), MAP_100TH_MM );
236 Construct( pOptions );
239 ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, SCTAB nTab,
240 long nPage, long nDocP, const ScRange* pArea,
241 const ScPrintOptions* pOptions )
242 : pDocShell ( pShell ),
243 pPrinter ( NULL ),
244 pDrawView ( NULL ),
245 nPrintTab ( nTab ),
246 nPageStart ( nPage ),
247 nDocPages ( nDocP ),
248 pUserArea ( pArea ),
249 bState ( false ),
250 bSourceRangeValid ( false ),
251 bPrintCurrentTable ( false ),
252 bMultiArea ( false ),
253 mbHasPrintRange(true),
254 nTabPages ( 0 ),
255 nTotalPages ( 0 ),
256 nPagesX(0),
257 nPagesY(0),
258 nTotalY(0),
259 pPageData ( NULL )
261 pDev = pOutDev;
262 Construct( pOptions );
265 ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell,
266 const ScPrintState& rState, const ScPrintOptions* pOptions )
267 : pDocShell ( pShell ),
268 pPrinter ( NULL ),
269 pDrawView ( NULL ),
270 pUserArea ( NULL ),
271 bSourceRangeValid ( false ),
272 bPrintCurrentTable ( false ),
273 bMultiArea ( false ),
274 mbHasPrintRange(true),
275 nPagesX(0),
276 nPagesY(0),
277 nTotalY(0),
278 pPageData ( NULL )
280 pDev = pOutDev;
282 nPrintTab = rState.nPrintTab;
283 nStartCol = rState.nStartCol;
284 nStartRow = rState.nStartRow;
285 nEndCol = rState.nEndCol;
286 nEndRow = rState.nEndRow;
287 nZoom = rState.nZoom;
288 nPagesX = rState.nPagesX;
289 nPagesY = rState.nPagesY;
290 nTabPages = rState.nTabPages;
291 nTotalPages = rState.nTotalPages;
292 nPageStart = rState.nPageStart;
293 nDocPages = rState.nDocPages;
294 bState = true;
296 Construct( pOptions );
299 void ScPrintFunc::GetPrintState( ScPrintState& rState )
301 rState.nPrintTab = nPrintTab;
302 rState.nStartCol = nStartCol;
303 rState.nStartRow = nStartRow;
304 rState.nEndCol = nEndCol;
305 rState.nEndRow = nEndRow;
306 rState.nZoom = nZoom;
307 rState.nPagesX = nPagesX;
308 rState.nPagesY = nPagesY;
309 rState.nTabPages = nTabPages;
310 rState.nTotalPages = nTotalPages;
311 rState.nPageStart = nPageStart;
312 rState.nDocPages = nDocPages;
315 bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const
317 rRange = aLastSourceRange;
318 return bSourceRangeValid;
321 void ScPrintFunc::FillPageData()
323 if (pPageData)
325 sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
326 ScPrintRangeData& rData = pPageData->GetData(nCount); // count up
328 rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab,
329 nEndCol, nEndRow, nPrintTab ) );
330 // #i123672#
331 if(maPageEndX.empty())
333 OSL_ENSURE(false, "vector access error for maPageEndX (!)");
335 else
337 rData.SetPagesX( nPagesX, &maPageEndX[0]);
340 // #i123672#
341 if(maPageEndY.empty())
343 OSL_ENSURE(false, "vector access error for maPageEndY (!)");
345 else
347 rData.SetPagesY( nTotalY, &maPageEndY[0]);
350 // Settings
351 rData.SetTopDown( aTableParam.bTopDown );
352 rData.SetAutomatic( !aAreaParam.bPrintArea );
356 ScPrintFunc::~ScPrintFunc()
358 delete pEditDefaults;
359 delete pEditEngine;
361 // Printer settings are now restored from outside
363 // For DrawingLayer/Charts, the MapMode of the printer (RefDevice) must always be correct
364 SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // use Preview also for the printer
365 if (pDocPrinter)
366 pDocPrinter->SetMapMode(aOldPrinterMode);
369 void ScPrintFunc::SetDrawView( FmFormView* pNew )
371 pDrawView = pNew;
374 static void lcl_HidePrint( ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 )
376 for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++)
378 RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY];
379 for (SCCOL nX=nX1; nX<=nX2; nX++)
381 const CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1];
382 if (!rCellInfo.bEmptyCellText)
383 if (static_cast<const ScProtectionAttr&>(rCellInfo.pPatternAttr->
384 GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet)).GetHidePrint())
386 pThisRowInfo->pCellInfo[nX+1].maCell.clear();
387 pThisRowInfo->pCellInfo[nX+1].bEmptyCellText = true;
393 // output to Device (static)
395 // us used for:
396 // - Clipboard/Bitmap
397 // - Ole-Object (DocShell::Draw)
398 // - Preview of templates
400 void ScPrintFunc::DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double /* nPrintFactor */,
401 const Rectangle& rBound, ScViewData* pViewData, bool bMetaFile )
403 //! evaluate nPrintFactor !!!
405 SCTAB nTab = 0;
406 if (pViewData)
407 nTab = pViewData->GetTabNo();
409 bool bDoGrid, bNullVal, bFormula;
410 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
411 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
412 if (pStyleSheet)
414 SfxItemSet& rSet = pStyleSheet->GetItemSet();
415 bDoGrid = static_cast<const SfxBoolItem&>(rSet.Get(ATTR_PAGE_GRID)).GetValue();
416 bNullVal = static_cast<const SfxBoolItem&>(rSet.Get(ATTR_PAGE_NULLVALS)).GetValue();
417 bFormula = static_cast<const SfxBoolItem&>(rSet.Get(ATTR_PAGE_FORMULAS)).GetValue();
419 else
421 const ScViewOptions& rOpt = pDoc->GetViewOptions();
422 bDoGrid = rOpt.GetOption(VOPT_GRID);
423 bNullVal = rOpt.GetOption(VOPT_NULLVALS);
424 bFormula = rOpt.GetOption(VOPT_FORMULAS);
427 MapMode aMode = pDev->GetMapMode();
429 Rectangle aRect = rBound;
431 if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top())
432 aRect = Rectangle( Point(), pDev->GetOutputSize() );
434 SCCOL nX1 = 0;
435 SCROW nY1 = 0;
436 SCCOL nX2 = OLE_STD_CELLS_X - 1;
437 SCROW nY2 = OLE_STD_CELLS_Y - 1;
438 if (bMetaFile)
440 ScRange aRange = pDoc->GetRange( nTab, rBound );
441 nX1 = aRange.aStart.Col();
442 nY1 = aRange.aStart.Row();
443 nX2 = aRange.aEnd.Col();
444 nY2 = aRange.aEnd.Row();
446 else if (pViewData)
448 ScSplitPos eWhich = pViewData->GetActivePart();
449 ScHSplitPos eHWhich = WhichH(eWhich);
450 ScVSplitPos eVWhich = WhichV(eWhich);
451 nX1 = pViewData->GetPosX(eHWhich);
452 nY1 = pViewData->GetPosY(eVWhich);
453 nX2 = nX1 + pViewData->VisibleCellsX(eHWhich);
454 if (nX2>nX1) --nX2;
455 nY2 = nY1 + pViewData->VisibleCellsY(eVWhich);
456 if (nY2>nY1) --nY2;
459 if (nX1 > MAXCOL) nX1 = MAXCOL;
460 if (nX2 > MAXCOL) nX2 = MAXCOL;
461 if (nY1 > MAXROW) nY1 = MAXROW;
462 if (nY2 > MAXROW) nY2 = MAXROW;
464 long nDevSizeX = aRect.Right()-aRect.Left()+1;
465 long nDevSizeY = aRect.Bottom()-aRect.Top()+1;
467 Rectangle aLines;
468 ScRange aRange( nX1,nY1,nTab, nX2,nY2,nTab );
470 long nTwipsSizeX = 0;
471 for (SCCOL i=nX1; i<=nX2; i++)
472 nTwipsSizeX += pDoc->GetColWidth( i, nTab );
473 long nTwipsSizeY = (long) pDoc->GetRowHeight( nY1, nY2, nTab );
475 // if no lines, still space for the outline frame (20 Twips = 1pt)
476 // (HasLines initalizes aLines to 0,0,0,0)
477 nTwipsSizeX += aLines.Left() + std::max( aLines.Right(), 20L );
478 nTwipsSizeY += aLines.Top() + std::max( aLines.Bottom(), 20L );
480 double nScaleX = (double) nDevSizeX / nTwipsSizeX;
481 double nScaleY = (double) nDevSizeY / nTwipsSizeY;
483 //! hand over Flag at FillInfo !!!!!
484 ScRange aERange;
485 bool bEmbed = pDoc->IsEmbedded();
486 if (bEmbed)
488 pDoc->GetEmbedded(aERange);
489 pDoc->ResetEmbedded();
492 // Assemble data
494 ScTableInfo aTabInfo;
495 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
496 nScaleX, nScaleY, false, bFormula );
497 lcl_HidePrint( aTabInfo, nX1, nX2 );
499 if (bEmbed)
500 pDoc->SetEmbedded(aERange);
502 long nScrX = aRect.Left();
503 long nScrY = aRect.Top();
505 // If no lines, still leave space for grid lines
506 // (would be elseways cut away)
507 long nAddX = (long)( aLines.Left() * nScaleX );
508 nScrX += ( nAddX ? nAddX : 1 );
509 long nAddY = (long)( aLines.Top() * nScaleY );
510 nScrY += ( nAddY ? nAddY : 1 );
512 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nTab,
513 nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
514 aOutputData.SetMetaFileMode(bMetaFile);
515 aOutputData.SetShowNullValues(bNullVal);
516 aOutputData.SetShowFormulas(bFormula);
518 // #114135#
519 ScDrawLayer* pModel = pDoc->GetDrawLayer();
520 boost::scoped_ptr<FmFormView> pDrawView;
522 if( pModel )
524 pDrawView.reset(new FmFormView( pModel, pDev ));
525 pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
526 pDrawView->SetPrintPreview( true );
527 aOutputData.SetDrawView( pDrawView.get() );
530 //! SetUseStyleColor ??
532 if ( bMetaFile && pDev->GetOutDevType() == OUTDEV_VIRDEV )
533 aOutputData.SetSnapPixel();
535 Point aLogStart = pDev->PixelToLogic( Point(nScrX,nScrY), MAP_100TH_MM );
536 long nLogStX = aLogStart.X();
537 long nLogStY = aLogStart.Y();
539 //! nZoom for GetFont in OutputData ???
541 if (!bMetaFile && pViewData)
542 pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
544 // #i72502#
545 const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
546 aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
548 if (!bMetaFile && pViewData)
549 pDev->SetMapMode(aMode);
551 aOutputData.DrawBackground();
552 aOutputData.DrawShadow();
553 aOutputData.DrawFrame();
554 aOutputData.DrawStrings();
556 if (!bMetaFile && pViewData)
557 pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
559 aOutputData.DrawEdit(!bMetaFile);
561 if (bDoGrid)
563 if (!bMetaFile && pViewData)
564 pDev->SetMapMode(aMode);
566 aOutputData.DrawGrid( true, false ); // no page breaks
568 pDev->SetLineColor( COL_BLACK );
570 Size aOne = pDev->PixelToLogic( Size(1,1) );
571 if (bMetaFile)
572 aOne = Size(1,1); // compatible with DrawGrid
573 long nRight = nScrX + aOutputData.GetScrW() - aOne.Width();
574 long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height();
576 bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
578 // extra line at the left edge for left-to-right, right for right-to-left
579 if ( bLayoutRTL )
580 pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) );
581 else
582 pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) );
583 // extra line at the top in both cases
584 pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) );
587 // #i72502#
588 aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
589 aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
590 aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
593 // Printing
595 static void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet )
597 // nDistance must be initialized differently before
599 if ( pHFSet == NULL )
601 rParam.bEnable = false;
602 rParam.pBorder = NULL;
603 rParam.pBack = NULL;
604 rParam.pShadow = NULL;
606 else
608 rParam.bEnable = static_cast<const SfxBoolItem&>( pHFSet->Get(ATTR_PAGE_ON)).GetValue();
609 rParam.bDynamic = static_cast<const SfxBoolItem&>( pHFSet->Get(ATTR_PAGE_DYNAMIC)).GetValue();
610 rParam.bShared = static_cast<const SfxBoolItem&>( pHFSet->Get(ATTR_PAGE_SHARED)).GetValue();
611 rParam.nHeight = static_cast<const SvxSizeItem&>( pHFSet->Get(ATTR_PAGE_SIZE)).GetSize().Height();
612 const SvxLRSpaceItem* pHFLR = &static_cast<const SvxLRSpaceItem&>(pHFSet->Get(ATTR_LRSPACE));
613 long nTmp;
614 nTmp = pHFLR->GetLeft();
615 rParam.nLeft = nTmp < 0 ? 0 : sal_uInt16(nTmp);
616 nTmp = pHFLR->GetRight();
617 rParam.nRight = nTmp < 0 ? 0 : sal_uInt16(nTmp);
618 rParam.pBorder = static_cast<const SvxBoxItem*> (&pHFSet->Get(ATTR_BORDER));
619 rParam.pBack = static_cast<const SvxBrushItem*> (&pHFSet->Get(ATTR_BACKGROUND));
620 rParam.pShadow = static_cast<const SvxShadowItem*>(&pHFSet->Get(ATTR_SHADOW));
622 // now back in the dialog:
623 // rParam.nHeight += rParam.nDistance; // not in the dialog any more ???
625 if (rParam.pBorder)
626 rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
627 lcl_LineTotal( rParam.pBorder->GetBottom() );
629 rParam.nManHeight = rParam.nHeight;
632 if (!rParam.bEnable)
633 rParam.nHeight = 0;
636 // bNew = TRUE: search for used part of the document
637 // bNew = FALSE: only limit whole lines/columns
639 bool ScPrintFunc::AdjustPrintArea( bool bNew )
641 SCCOL nOldEndCol = nEndCol; // only important for !bNew
642 SCROW nOldEndRow = nEndRow;
643 bool bChangeCol = true; // at bNew both are being adjusted
644 bool bChangeRow = true;
646 bool bNotes = aTableParam.bNotes;
647 if ( bNew )
649 nStartCol = 0;
650 nStartRow = 0;
651 if (!pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ))
652 return false; // nix
654 else
656 bool bFound = true;
657 bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL );
658 bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW );
659 bool bForcedChangeRow = false;
661 // #i53558# Crop entire column of old row limit to real print area with
662 // some fuzzyness.
663 if (!bChangeRow && nStartRow == 0)
665 SCROW nPAEndRow;
666 bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nPAEndRow, bNotes );
667 // Say we don't want to print more than ~1000 empty rows, which are
668 // about 14 pages intentionally left blank..
669 const SCROW nFuzzy = 23*42;
670 if (nPAEndRow + nFuzzy < nEndRow)
672 bForcedChangeRow = true;
673 nEndRow = nPAEndRow;
675 else
676 bFound = true; // user seems to _want_ to print some empty rows
678 // TODO: in case we extend the number of columns we may have to do the
679 // same for horizontal cropping.
681 if ( bChangeCol && bChangeRow )
682 bFound = pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes );
683 else if ( bChangeCol )
684 bFound = pDoc->GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol, bNotes );
685 else if ( bChangeRow )
686 bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes );
688 if (!bFound)
689 return false; // empty
691 if (bForcedChangeRow)
692 bChangeRow = true;
695 pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab,
696 false ); // no Refresh, incl. Attrs
698 if ( bChangeCol )
700 OutputDevice* pRefDev = pDoc->GetPrinter(); // use the printer also for Preview
701 pRefDev->SetMapMode( MAP_PIXEL ); // important for GetNeededSize
703 pDoc->ExtendPrintArea( pRefDev,
704 nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow );
705 // changing nEndCol
708 if ( nEndCol < MAXCOL && pDoc->HasAttrib(
709 nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_RIGHT ) )
710 ++nEndCol;
711 if ( nEndRow < MAXROW && pDoc->HasAttrib(
712 nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_DOWN ) )
713 ++nEndRow;
715 if (!bChangeCol) nEndCol = nOldEndCol;
716 if (!bChangeRow) nEndRow = nOldEndRow;
718 return true;
721 long ScPrintFunc::TextHeight( const EditTextObject* pObject )
723 if (!pObject)
724 return 0;
726 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
728 return (long) pEditEngine->GetTextHeight();
731 // nZoom must be set !!!
732 // and the respective Twip-MapMode configured
734 void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam )
736 OSL_ENSURE( aPageSize.Width(), "UpdateHFHeight ohne aPageSize");
738 if (rParam.bEnable && rParam.bDynamic)
740 // calculate nHeight from content
742 MakeEditEngine();
743 long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin -
744 rParam.nLeft - rParam.nRight ) * 100 / nZoom;
745 if (rParam.pBorder)
746 nPaperWidth -= ( rParam.pBorder->GetDistance(SvxBoxItemLine::LEFT) +
747 rParam.pBorder->GetDistance(SvxBoxItemLine::RIGHT) +
748 lcl_LineTotal(rParam.pBorder->GetLeft()) +
749 lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom;
751 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
752 nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::LEFT) +
753 rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::RIGHT) ) * 100L / nZoom;
755 pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) );
757 long nMaxHeight = 0;
758 if ( rParam.pLeft )
760 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) );
761 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) );
762 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) );
764 if ( rParam.pRight )
766 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) );
767 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) );
768 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) );
771 rParam.nHeight = nMaxHeight + rParam.nDistance;
772 if (rParam.pBorder)
773 rParam.nHeight += rParam.pBorder->GetDistance(SvxBoxItemLine::TOP) +
774 rParam.pBorder->GetDistance(SvxBoxItemLine::BOTTOM) +
775 lcl_LineTotal( rParam.pBorder->GetTop() ) +
776 lcl_LineTotal( rParam.pBorder->GetBottom() );
777 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
778 rParam.nHeight += rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::TOP) +
779 rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::BOTTOM);
781 if (rParam.nHeight < rParam.nManHeight)
782 rParam.nHeight = rParam.nManHeight; // configured minimum
786 void ScPrintFunc::InitParam( const ScPrintOptions* pOptions )
788 if (!pParamSet)
789 return;
791 // TabPage "Page"
792 const SvxLRSpaceItem* pLRItem = static_cast<const SvxLRSpaceItem*>( &pParamSet->Get( ATTR_LRSPACE ) );
793 long nTmp;
794 nTmp = pLRItem->GetLeft();
795 nLeftMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
796 nTmp = pLRItem->GetRight();
797 nRightMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
798 const SvxULSpaceItem* pULItem = static_cast<const SvxULSpaceItem*>( &pParamSet->Get( ATTR_ULSPACE ) );
799 nTopMargin = pULItem->GetUpper();
800 nBottomMargin = pULItem->GetLower();
802 const SvxPageItem* pPageItem = static_cast<const SvxPageItem*>( &pParamSet->Get( ATTR_PAGE ) );
803 nPageUsage = pPageItem->GetPageUsage();
804 bLandscape = pPageItem->IsLandscape();
805 aFieldData.eNumType = pPageItem->GetNumType();
807 bCenterHor = static_cast<const SfxBoolItem&>( pParamSet->Get(ATTR_PAGE_HORCENTER)).GetValue();
808 bCenterVer = static_cast<const SfxBoolItem&>( pParamSet->Get(ATTR_PAGE_VERCENTER)).GetValue();
810 aPageSize = static_cast<const SvxSizeItem&>( pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
811 if ( !aPageSize.Width() || !aPageSize.Height() )
813 OSL_FAIL("PageSize Null ?!?!?");
814 aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
817 pBorderItem = static_cast<const SvxBoxItem*> (&pParamSet->Get(ATTR_BORDER) );
818 pBackgroundItem = static_cast<const SvxBrushItem*> (&pParamSet->Get(ATTR_BACKGROUND) );
819 pShadowItem = static_cast<const SvxShadowItem*>(&pParamSet->Get(ATTR_SHADOW) );
821 // TabPage "Headline"
823 aHdr.pLeft = static_cast<const ScPageHFItem*>( &pParamSet->Get(ATTR_PAGE_HEADERLEFT) ); // Content
824 aHdr.pRight = static_cast<const ScPageHFItem*>( &pParamSet->Get(ATTR_PAGE_HEADERRIGHT) );
826 const SvxSetItem* pHeaderSetItem;
827 const SfxItemSet* pHeaderSet = NULL;
828 if ( pParamSet->GetItemState( ATTR_PAGE_HEADERSET, false,
829 reinterpret_cast<const SfxPoolItem**>(&pHeaderSetItem) ) == SfxItemState::SET )
831 pHeaderSet = &pHeaderSetItem->GetItemSet();
832 // Headline has space below
833 aHdr.nDistance = static_cast<const SvxULSpaceItem&>(pHeaderSet->Get(ATTR_ULSPACE)).GetLower();
835 lcl_FillHFParam( aHdr, pHeaderSet );
837 // TabPage "Footline"
839 aFtr.pLeft = static_cast<const ScPageHFItem*>( &pParamSet->Get(ATTR_PAGE_FOOTERLEFT) ); // Content
840 aFtr.pRight = static_cast<const ScPageHFItem*>( &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT) );
842 const SvxSetItem* pFooterSetItem;
843 const SfxItemSet* pFooterSet = NULL;
844 if ( pParamSet->GetItemState( ATTR_PAGE_FOOTERSET, false,
845 reinterpret_cast<const SfxPoolItem**>(&pFooterSetItem) ) == SfxItemState::SET )
847 pFooterSet = &pFooterSetItem->GetItemSet();
848 // Footline has space above
849 aFtr.nDistance = static_cast<const SvxULSpaceItem&>(pFooterSet->Get(ATTR_ULSPACE)).GetUpper();
851 lcl_FillHFParam( aFtr, pFooterSet );
853 // Compile Table-/Area-Params from single Items
855 // TabPage "Table"
857 const SfxUInt16Item* pScaleItem = NULL;
858 const ScPageScaleToItem* pScaleToItem = NULL;
859 const SfxUInt16Item* pScaleToPagesItem = NULL;
860 SfxItemState eState;
862 eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, false,
863 reinterpret_cast<const SfxPoolItem**>(&pScaleItem) );
864 if ( SfxItemState::DEFAULT == eState )
865 pScaleItem = static_cast<const SfxUInt16Item*>(
866 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE ));
868 eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, false,
869 reinterpret_cast<const SfxPoolItem**>(&pScaleToItem) );
870 if ( SfxItemState::DEFAULT == eState )
871 pScaleToItem = static_cast<const ScPageScaleToItem*>(
872 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO ));
874 eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, false,
875 reinterpret_cast<const SfxPoolItem**>(&pScaleToPagesItem) );
876 if ( SfxItemState::DEFAULT == eState )
877 pScaleToPagesItem = static_cast<const SfxUInt16Item*>(
878 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETOPAGES ));
880 OSL_ENSURE( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" );
882 aTableParam.bCellContent = true;
883 aTableParam.bNotes = GET_BOOL(pParamSet,ATTR_PAGE_NOTES);
884 aTableParam.bGrid = GET_BOOL(pParamSet,ATTR_PAGE_GRID);
885 aTableParam.bHeaders = GET_BOOL(pParamSet,ATTR_PAGE_HEADERS);
886 aTableParam.bFormulas = GET_BOOL(pParamSet,ATTR_PAGE_FORMULAS);
887 aTableParam.bNullVals = GET_BOOL(pParamSet,ATTR_PAGE_NULLVALS);
888 aTableParam.bCharts = GET_SHOW(pParamSet,ATTR_PAGE_CHARTS);
889 aTableParam.bObjects = GET_SHOW(pParamSet,ATTR_PAGE_OBJECTS);
890 aTableParam.bDrawings = GET_SHOW(pParamSet,ATTR_PAGE_DRAWINGS);
891 aTableParam.bTopDown = GET_BOOL(pParamSet,ATTR_PAGE_TOPDOWN);
892 aTableParam.bLeftRight = !aTableParam.bLeftRight;
893 aTableParam.nFirstPageNo = GET_USHORT(pParamSet,ATTR_PAGE_FIRSTPAGENO);
894 if (!aTableParam.nFirstPageNo)
895 aTableParam.nFirstPageNo = (sal_uInt16) nPageStart; // from previous table
897 if ( pScaleItem && pScaleToItem && pScaleToPagesItem )
899 sal_uInt16 nScaleAll = pScaleItem->GetValue();
900 sal_uInt16 nScaleToPages = pScaleToPagesItem->GetValue();
902 aTableParam.bScaleNone = (nScaleAll == 100);
903 aTableParam.bScaleAll = (nScaleAll > 0 );
904 aTableParam.bScaleTo = pScaleToItem->IsValid();
905 aTableParam.bScalePageNum = (nScaleToPages > 0 );
906 aTableParam.nScaleAll = nScaleAll;
907 aTableParam.nScaleWidth = pScaleToItem->GetWidth();
908 aTableParam.nScaleHeight = pScaleToItem->GetHeight();
909 aTableParam.nScalePageNum = nScaleToPages;
911 else
913 aTableParam.bScaleNone = true;
914 aTableParam.bScaleAll = false;
915 aTableParam.bScaleTo = false;
916 aTableParam.bScalePageNum = false;
917 aTableParam.nScaleAll = 0;
918 aTableParam.nScaleWidth = 0;
919 aTableParam.nScaleHeight = 0;
920 aTableParam.nScalePageNum = 0;
923 // skip empty pages only if options with that flag are passed
924 aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty();
925 if ( pPageData )
926 aTableParam.bSkipEmpty = false;
927 // If pPageData is set, only the breaks are interesting for the
928 // pagebreak preview, empty pages are not addressed separately.
930 aTableParam.bForceBreaks = pOptions && pOptions->GetForceBreaks();
932 // TabPage "Parts":
934 //! walk through all PrintAreas of the table !!!
935 const ScRange* pPrintArea = pDoc->GetPrintRange( nPrintTab, 0 );
936 const ScRange* pRepeatCol = pDoc->GetRepeatColRange( nPrintTab );
937 const ScRange* pRepeatRow = pDoc->GetRepeatRowRange( nPrintTab );
939 // ignoring ATTR_PAGE_PRINTTABLES
941 bool bHasPrintRange = pDoc->HasPrintRange();
942 sal_uInt16 nPrintRangeCount = pDoc->GetPrintRangeCount(nPrintTab);
943 bool bPrintEntireSheet = pDoc->IsPrintEntireSheet(nPrintTab);
945 if (!bPrintEntireSheet && !nPrintRangeCount)
946 mbHasPrintRange = false;
948 if ( pUserArea ) // UserArea (selection) has prority
950 bPrintCurrentTable =
951 aAreaParam.bPrintArea = true; // Selection
952 aAreaParam.aPrintArea = *pUserArea;
954 // The table-query is already in DocShell::Print, here always
955 aAreaParam.aPrintArea.aStart.SetTab(nPrintTab);
956 aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab);
958 else if (bHasPrintRange)
960 if ( pPrintArea ) // at least one set?
962 bPrintCurrentTable =
963 aAreaParam.bPrintArea = true;
964 aAreaParam.aPrintArea = *pPrintArea;
966 bMultiArea = nPrintRangeCount > 1;
968 else
970 // do not print hidden sheets with "Print entire sheet" flag
971 bPrintCurrentTable = pDoc->IsPrintEntireSheet( nPrintTab ) && pDoc->IsVisible( nPrintTab );
972 aAreaParam.bPrintArea = !bPrintCurrentTable; // otherwise the table is always counted
975 else
977 // don't print hidden tables if there's no print range defined there
978 if ( pDoc->IsVisible( nPrintTab ) )
980 aAreaParam.bPrintArea = false;
981 bPrintCurrentTable = true;
983 else
985 aAreaParam.bPrintArea = true; // otherwise the table is always counted
986 bPrintCurrentTable = false;
990 if ( pRepeatCol )
992 aAreaParam.bRepeatCol = true;
993 aAreaParam.aRepeatCol = *pRepeatCol;
994 nRepeatStartCol = pRepeatCol->aStart.Col();
995 nRepeatEndCol = pRepeatCol->aEnd .Col();
997 else
999 aAreaParam.bRepeatCol = false;
1000 nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE;
1003 if ( pRepeatRow )
1005 aAreaParam.bRepeatRow = true;
1006 aAreaParam.aRepeatRow = *pRepeatRow;
1007 nRepeatStartRow = pRepeatRow->aStart.Row();
1008 nRepeatEndRow = pRepeatRow->aEnd .Row();
1010 else
1012 aAreaParam.bRepeatRow = false;
1013 nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE;
1016 // Split pages
1018 if (!bState)
1020 nTabPages = CountPages(); // also calculates zoom
1021 nTotalPages = nTabPages;
1022 nTotalPages += CountNotePages();
1024 else
1026 CalcPages(); // search breaks only
1027 CountNotePages(); // Count notes, even if number of pages is already known
1030 if (nDocPages)
1031 aFieldData.nTotalPages = nDocPages;
1032 else
1033 aFieldData.nTotalPages = nTotalPages;
1035 SetDateTime( Date( Date::SYSTEM ), tools::Time( tools::Time::SYSTEM ) );
1037 if( pDocShell->getDocProperties()->getTitle().getLength() != 0 )
1038 aFieldData.aTitle = pDocShell->getDocProperties()->getTitle();
1039 else
1040 aFieldData.aTitle = pDocShell->GetTitle();
1042 const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
1043 aFieldData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
1044 if ( !aFieldData.aLongDocName.isEmpty() )
1045 aFieldData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
1046 else
1047 aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle;
1049 // Printer settings (Orientation, Paper) at DoPrint
1052 Size ScPrintFunc::GetDataSize() const
1054 Size aSize = aPageSize;
1055 aSize.Width() -= nLeftMargin + nRightMargin;
1056 aSize.Height() -= nTopMargin + nBottomMargin;
1057 aSize.Height() -= aHdr.nHeight + aFtr.nHeight;
1058 return aSize;
1061 void ScPrintFunc::GetScaleData( Size& rPhysSize, long& rDocHdr, long& rDocFtr )
1063 rPhysSize = aPageSize;
1064 rPhysSize.Width() -= nLeftMargin + nRightMargin;
1065 rPhysSize.Height() -= nTopMargin + nBottomMargin;
1067 rDocHdr = aHdr.nHeight;
1068 rDocFtr = aFtr.nHeight;
1071 void ScPrintFunc::SetDateTime( const Date& rDate, const tools::Time& rTime )
1073 aFieldData.aDate = rDate;
1074 aFieldData.aTime = rTime;
1077 static void lcl_DrawGraphic( const Graphic &rGraphic, vcl::RenderContext *pOut,
1078 const Rectangle &rGrf, const Rectangle &rOut )
1080 const bool bNotInside = !rOut.IsInside( rGrf );
1081 if ( bNotInside )
1083 pOut->Push();
1084 pOut->IntersectClipRegion( rOut );
1087 ((Graphic&)rGraphic).Draw( pOut, rGrf.TopLeft(), rGrf.GetSize() );
1089 if ( bNotInside )
1090 pOut->Pop();
1093 static void lcl_DrawGraphic( const SvxBrushItem &rBrush, vcl::RenderContext *pOut, OutputDevice* pRefDev,
1094 const Rectangle &rOrg, const Rectangle &rOut,
1095 OUString const & referer )
1097 Size aGrfSize(0,0);
1098 const Graphic *pGraphic = rBrush.GetGraphic(referer);
1099 SvxGraphicPosition ePos;
1100 if ( pGraphic && pGraphic->IsSupportedGraphic() )
1102 const MapMode aMapMM( MAP_100TH_MM );
1103 if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1104 aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM );
1105 else
1106 aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1107 pGraphic->GetPrefMapMode(), aMapMM );
1108 ePos = rBrush.GetGraphicPos();
1110 else
1111 ePos = GPOS_NONE;
1113 Point aPos;
1114 Size aDrawSize = aGrfSize;
1116 bool bDraw = true;
1117 switch ( ePos )
1119 case GPOS_LT: aPos = rOrg.TopLeft();
1120 break;
1121 case GPOS_MT: aPos.Y() = rOrg.Top();
1122 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1123 break;
1124 case GPOS_RT: aPos.Y() = rOrg.Top();
1125 aPos.X() = rOrg.Right() - aGrfSize.Width();
1126 break;
1128 case GPOS_LM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1129 aPos.X() = rOrg.Left();
1130 break;
1131 case GPOS_MM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1132 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1133 break;
1134 case GPOS_RM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1135 aPos.X() = rOrg.Right() - aGrfSize.Width();
1136 break;
1138 case GPOS_LB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1139 aPos.X() = rOrg.Left();
1140 break;
1141 case GPOS_MB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1142 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1143 break;
1144 case GPOS_RB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1145 aPos.X() = rOrg.Right() - aGrfSize.Width();
1146 break;
1148 case GPOS_AREA:
1149 aPos = rOrg.TopLeft();
1150 aDrawSize = rOrg.GetSize();
1151 break;
1152 case GPOS_TILED:
1154 // use GraphicObject::DrawTiled instead of an own loop
1155 // (pixel rounding is handled correctly, and a very small bitmap
1156 // is duplicated into a bigger one for better performance)
1158 GraphicObject aObject( *pGraphic );
1160 if( pOut->GetPDFWriter() &&
1161 (aObject.GetType() == GRAPHIC_BITMAP || aObject.GetType() == GRAPHIC_DEFAULT) )
1163 // For PDF export, every draw
1164 // operation for bitmaps takes a noticeable
1165 // amount of place (~50 characters). Thus,
1166 // optimize between tile bitmap size and
1167 // number of drawing operations here.
1169 // A_out
1170 // n_chars = k1 * ---------- + k2 * A_bitmap
1171 // A_bitmap
1173 // minimum n_chars is obtained for (derive for
1174 // A_bitmap, set to 0, take positive
1175 // solution):
1176 // k1
1177 // A_bitmap = Sqrt( ---- A_out )
1178 // k2
1180 // where k1 is the number of chars per draw
1181 // operation, and k2 is the number of chars
1182 // per bitmap pixel. This is approximately 50
1183 // and 7 for current PDF writer, respectively.
1185 const double k1( 50 );
1186 const double k2( 7 );
1187 const Size aSize( rOrg.GetSize() );
1188 const double Abitmap( k1/k2 * aSize.Width()*aSize.Height() );
1190 aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0),
1191 NULL, GraphicManagerDrawFlags::STANDARD,
1192 ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
1194 else
1196 aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0) );
1199 bDraw = false;
1201 break;
1203 case GPOS_NONE:
1204 bDraw = false;
1205 break;
1207 default: OSL_ENSURE( !pOut, "new Graphic position?" );
1209 Rectangle aGrf( aPos,aDrawSize );
1210 if ( bDraw && aGrf.IsOver( rOut ) )
1212 lcl_DrawGraphic( *pGraphic, pOut, aGrf, rOut );
1216 // Rahmen wird nach innen gezeichnet
1218 void ScPrintFunc::DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH,
1219 const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground,
1220 const SvxShadowItem* pShadow )
1222 //! direkte Ausgabe aus SvxBoxItem !!!
1224 if (pBorderData)
1225 if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() &&
1226 !pBorderData->GetRight() )
1227 pBorderData = NULL;
1229 if (!pBorderData && !pBackground && !pShadow)
1230 return; // nichts zu tun
1232 long nLeft = 0;
1233 long nRight = 0;
1234 long nTop = 0;
1235 long nBottom = 0;
1237 // aFrameRect - ouside around frame, without shadow
1238 if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1240 nLeft += (long) ( pShadow->CalcShadowSpace(SvxShadowItemSide::LEFT) * nScaleX );
1241 nRight += (long) ( pShadow->CalcShadowSpace(SvxShadowItemSide::RIGHT) * nScaleX );
1242 nTop += (long) ( pShadow->CalcShadowSpace(SvxShadowItemSide::TOP) * nScaleY );
1243 nBottom += (long) ( pShadow->CalcShadowSpace(SvxShadowItemSide::BOTTOM) * nScaleY );
1245 Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop),
1246 Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) );
1248 // center of frame, to paint lines through OutputData
1249 if (pBorderData)
1251 nLeft += (long) ( lcl_LineTotal(pBorderData->GetLeft()) * nScaleX / 2 );
1252 nRight += (long) ( lcl_LineTotal(pBorderData->GetRight()) * nScaleX / 2 );
1253 nTop += (long) ( lcl_LineTotal(pBorderData->GetTop()) * nScaleY / 2 );
1254 nBottom += (long) ( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 );
1256 long nEffHeight = nScrH - nTop - nBottom;
1257 long nEffWidth = nScrW - nLeft - nRight;
1258 if (nEffHeight<=0 || nEffWidth<=0)
1259 return; // enmpty
1261 if ( pBackground )
1263 if (pBackground->GetGraphicPos() != GPOS_NONE)
1265 OutputDevice* pRefDev;
1266 if ( bIsRender )
1267 pRefDev = pDev; // don't use printer for PDF
1268 else
1269 pRefDev = pDoc->GetPrinter(); // use printer also for preview
1270 OUString referer;
1271 if (pDocShell->HasName()) {
1272 referer = pDocShell->GetMedium()->GetName();
1274 lcl_DrawGraphic( *pBackground, pDev, pRefDev, aFrameRect, aFrameRect, referer );
1276 else
1278 pDev->SetFillColor(pBackground->GetColor());
1279 pDev->SetLineColor();
1280 pDev->DrawRect(aFrameRect);
1284 if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1286 pDev->SetFillColor(pShadow->GetColor());
1287 pDev->SetLineColor();
1288 long nShadowX = (long) ( pShadow->GetWidth() * nScaleX );
1289 long nShadowY = (long) ( pShadow->GetWidth() * nScaleY );
1290 switch (pShadow->GetLocation())
1292 case SVX_SHADOW_TOPLEFT:
1293 pDev->DrawRect( Rectangle(
1294 aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1295 aFrameRect.Right()-nShadowX, aFrameRect.Top() ) );
1296 pDev->DrawRect( Rectangle(
1297 aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1298 aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) );
1299 break;
1300 case SVX_SHADOW_TOPRIGHT:
1301 pDev->DrawRect( Rectangle(
1302 aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY,
1303 aFrameRect.Right()+nShadowX, aFrameRect.Top() ) );
1304 pDev->DrawRect( Rectangle(
1305 aFrameRect.Right(), aFrameRect.Top()-nShadowY,
1306 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) );
1307 break;
1308 case SVX_SHADOW_BOTTOMLEFT:
1309 pDev->DrawRect( Rectangle(
1310 aFrameRect.Left()-nShadowX, aFrameRect.Bottom(),
1311 aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) );
1312 pDev->DrawRect( Rectangle(
1313 aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY,
1314 aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) );
1315 break;
1316 case SVX_SHADOW_BOTTOMRIGHT:
1317 pDev->DrawRect( Rectangle(
1318 aFrameRect.Left()+nShadowX, aFrameRect.Bottom(),
1319 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1320 pDev->DrawRect( Rectangle(
1321 aFrameRect.Right(), aFrameRect.Top()+nShadowY,
1322 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1323 break;
1324 default:
1326 // added to avoid warnings
1331 if (pBorderData)
1333 boost::scoped_ptr<ScDocument> pBorderDoc(new ScDocument( SCDOCMODE_UNDO ));
1334 pBorderDoc->InitUndo( pDoc, 0,0, true,true );
1335 if (pBorderData)
1336 pBorderDoc->ApplyAttr( 0,0,0, *pBorderData );
1338 ScTableInfo aTabInfo;
1339 pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0,
1340 nScaleX, nScaleY, false, false );
1341 OSL_ENSURE(aTabInfo.mnArrCount,"nArrCount == 0");
1343 aTabInfo.mpRowInfo[1].nHeight = (sal_uInt16) nEffHeight;
1344 aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth =
1345 aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = (sal_uInt16) nEffWidth;
1347 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc.get(), 0,
1348 nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY );
1349 aOutputData.SetUseStyleColor( bUseStyleColor );
1351 if (pBorderData)
1352 aOutputData.DrawFrame();
1356 void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY )
1358 bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1359 long nLayoutSign = bLayoutRTL ? -1 : 1;
1361 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1362 long nOneX = aOnePixel.Width();
1363 long nOneY = aOnePixel.Height();
1364 SCCOL nCol;
1366 long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1367 long nEndY = nScrY + nHeight - nOneY;
1369 long nPosX = nScrX;
1370 if ( bLayoutRTL )
1372 for (nCol=nX1; nCol<=nX2; nCol++)
1373 nPosX += (long)( pDoc->GetColWidth( nCol, nPrintTab ) * nScaleX );
1375 else
1376 nPosX -= nOneX;
1377 long nPosY = nScrY - nOneY;
1378 OUString aText;
1380 for (nCol=nX1; nCol<=nX2; nCol++)
1382 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1383 if (nDocW)
1385 long nWidth = (long) (nDocW * nScaleX);
1386 long nEndX = nPosX + nWidth * nLayoutSign;
1388 pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1390 aText = ::ScColToAlpha( nCol);
1391 long nTextWidth = pDev->GetTextWidth(aText);
1392 long nTextHeight = pDev->GetTextHeight();
1393 long nAddX = ( nWidth - nTextWidth ) / 2;
1394 long nAddY = ( nHeight - nTextHeight ) / 2;
1395 long nTextPosX = nPosX+nAddX;
1396 if ( bLayoutRTL )
1397 nTextPosX -= nWidth;
1398 pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText );
1400 nPosX = nEndX;
1405 void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY )
1407 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1408 long nOneX = aOnePixel.Width();
1409 long nOneY = aOnePixel.Height();
1411 bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1413 long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1414 long nEndX = nScrX + nWidth;
1415 long nPosX = nScrX;
1416 if ( !bLayoutRTL )
1418 nEndX -= nOneX;
1419 nPosX -= nOneX;
1421 long nPosY = nScrY - nOneY;
1422 OUString aText;
1424 for (SCROW nRow=nY1; nRow<=nY2; nRow++)
1426 sal_uInt16 nDocH = pDoc->GetRowHeight( nRow, nPrintTab );
1427 if (nDocH)
1429 long nHeight = (long) (nDocH * nScaleY);
1430 long nEndY = nPosY + nHeight;
1432 pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1434 aText = OUString::number( nRow+1 );
1435 long nTextWidth = pDev->GetTextWidth(aText);
1436 long nTextHeight = pDev->GetTextHeight();
1437 long nAddX = ( nWidth - nTextWidth ) / 2;
1438 long nAddY = ( nHeight - nTextHeight ) / 2;
1439 pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText );
1441 nPosY = nEndY;
1446 void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY,
1447 bool bRepCol, ScPreviewLocationData& rLocationData )
1449 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1450 long nOneX = aOnePixel.Width();
1451 long nOneY = aOnePixel.Height();
1453 long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1454 long nEndY = nScrY + nHeight - nOneY;
1456 long nPosX = nScrX - nOneX;
1457 for (SCCOL nCol=nX1; nCol<=nX2; nCol++)
1459 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1460 if (nDocW)
1461 nPosX += (long) (nDocW * nScaleX);
1463 Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY );
1464 rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol );
1467 void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY,
1468 bool bRepRow, ScPreviewLocationData& rLocationData )
1470 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1471 long nOneX = aOnePixel.Width();
1472 long nOneY = aOnePixel.Height();
1474 bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1476 long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1477 long nEndX = nScrX + nWidth;
1478 if ( !bLayoutRTL )
1479 nEndX -= nOneX;
1481 long nPosY = nScrY - nOneY;
1482 nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1483 Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY );
1484 rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow );
1487 void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1488 long nScrX, long nScrY, bool bRepCol, bool bRepRow,
1489 ScPreviewLocationData& rLocationData )
1491 // get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer)
1493 Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1494 long nLogStX = aLogPos.X();
1495 long nLogStY = aLogPos.Y();
1497 SCCOL nCol;
1498 Point aTwipOffset;
1499 for (nCol=0; nCol<nX1; nCol++)
1500 aTwipOffset.X() -= pDoc->GetColWidth( nCol, nPrintTab );
1501 aTwipOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nPrintTab );
1503 Point aMMOffset( aTwipOffset );
1504 aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS);
1505 aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS);
1506 aMMOffset += Point( nLogStX, nLogStY );
1507 MapMode aDrawMapMode( MAP_100TH_MM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() );
1509 // get pixel rectangle
1511 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1512 long nOneX = aOnePixel.Width();
1513 long nOneY = aOnePixel.Height();
1515 long nPosX = nScrX - nOneX;
1516 for (nCol=nX1; nCol<=nX2; nCol++)
1518 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1519 if (nDocW)
1520 nPosX += (long) (nDocW * nScaleX);
1523 long nPosY = nScrY - nOneY;
1524 nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1525 Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY );
1526 rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ),
1527 bRepCol, bRepRow, aDrawMapMode );
1530 void ScPrintFunc::PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1531 long nScrX, long nScrY,
1532 bool bShLeft, bool bShTop, bool bShRight, bool bShBottom )
1534 // #i47547# nothing to do if the end of the print area is before the end of
1535 // the repeat columns/rows (don't use negative size for ScOutputData)
1536 if ( nX2 < nX1 || nY2 < nY1 )
1537 return;
1539 //! hand over Flag at FillInfo !!!!!
1540 ScRange aERange;
1541 bool bEmbed = pDoc->IsEmbedded();
1542 if (bEmbed)
1544 pDoc->GetEmbedded(aERange);
1545 pDoc->ResetEmbedded();
1548 Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1549 long nLogStX = aPos.X();
1550 long nLogStY = aPos.Y();
1552 // Assemble data
1554 ScTableInfo aTabInfo;
1555 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab,
1556 nScaleX, nScaleY, true, aTableParam.bFormulas );
1557 lcl_HidePrint( aTabInfo, nX1, nX2 );
1559 if (bEmbed)
1560 pDoc->SetEmbedded(aERange);
1562 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nPrintTab,
1563 nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
1565 // #114135#
1566 aOutputData.SetDrawView( pDrawView );
1568 // test if all paint parts are hidden, then a paint is not necessary at all
1569 const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
1570 const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart()
1571 && pDrawView->getHideDraw() && pDrawView->getHideFormControl() );
1573 if(!bHideAllDrawingLayer)
1575 pDev->SetMapMode(aLogicMode);
1576 // don's set Clipping here (Mapmode is being moved)
1578 // #i72502#
1579 aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
1582 pDev->SetMapMode(aOffsetMode);
1584 aOutputData.SetShowFormulas( aTableParam.bFormulas );
1585 aOutputData.SetShowNullValues( aTableParam.bNullVals );
1586 aOutputData.SetUseStyleColor( bUseStyleColor );
1588 Color aGridColor( COL_BLACK );
1589 if ( bUseStyleColor )
1590 aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
1591 aOutputData.SetGridColor( aGridColor );
1593 if ( !pPrinter )
1595 OutputDevice* pRefDev = pDoc->GetPrinter(); // use the printer also for Preview
1596 Fraction aPrintFrac( nZoom, 100 ); // without nManualZoom
1597 // MapMode, as it would arrive at the printer:
1598 pRefDev->SetMapMode( MapMode( MAP_100TH_MM, Point(), aPrintFrac, aPrintFrac ) );
1600 // when rendering (PDF), don't use printer as ref device, but printer's MapMode
1601 // has to be set anyway, as charts still use it (#106409#)
1602 if ( !bIsRender )
1603 aOutputData.SetRefDevice( pRefDev );
1606 if( aTableParam.bCellContent )
1607 aOutputData.DrawBackground();
1609 pDev->SetClipRegion(vcl::Region(Rectangle(
1610 aPos, Size(aOutputData.GetScrW(), aOutputData.GetScrH()))));
1611 pDev->SetClipRegion();
1613 if( aTableParam.bCellContent )
1615 aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom );
1616 aOutputData.DrawFrame();
1617 aOutputData.DrawStrings();
1618 aOutputData.DrawEdit(false);
1621 if (aTableParam.bGrid)
1622 aOutputData.DrawGrid( true, false ); // no page breaks
1624 aOutputData.AddPDFNotes(); // has no effect if not rendering PDF with notes enabled
1626 // test if all paint parts are hidden, then a paint is not necessary at all
1627 if(!bHideAllDrawingLayer)
1629 // #i72502#
1630 aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
1633 // #i72502#
1634 aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
1635 aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
1638 bool ScPrintFunc::IsMirror( long nPageNo ) // Mirror margins?
1640 SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1641 return ( eUsage == SVX_PAGE_MIRROR && (nPageNo & 1) );
1644 bool ScPrintFunc::IsLeft( long nPageNo ) // left foot notes?
1646 SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1647 bool bLeft;
1648 if (eUsage == SVX_PAGE_LEFT)
1649 bLeft = true;
1650 else if (eUsage == SVX_PAGE_RIGHT)
1651 bLeft = false;
1652 else
1653 bLeft = (nPageNo & 1) != 0;
1654 return bLeft;
1657 void ScPrintFunc::MakeTableString()
1659 OUString aTmp;
1660 pDoc->GetName(nPrintTab, aTmp);
1661 aFieldData.aTabName = aTmp;
1664 void ScPrintFunc::MakeEditEngine()
1666 if (!pEditEngine)
1668 // can't use document's edit engine pool here,
1669 // because pool must have twips as default metric
1670 pEditEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), true );
1672 pEditEngine->EnableUndo(false);
1673 //fdo#45869 we want text to be positioned as it would be for the
1674 //high dpi printed output, not as would be ideal for the 96dpi preview
1675 //window itself
1676 pEditEngine->SetRefDevice(pPrinter ? pPrinter : pDoc->GetRefDevice());
1677 pEditEngine->SetWordDelimiters(
1678 ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
1679 pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EEControlBits::RTFSTYLESHEETS );
1680 pDoc->ApplyAsianEditSettings( *pEditEngine );
1681 pEditEngine->EnableAutoColor( bUseStyleColor );
1683 // Default-Set for alignment
1684 pEditDefaults = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
1686 const ScPatternAttr& rPattern = static_cast<const ScPatternAttr&>(pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN));
1687 rPattern.FillEditItemSet( pEditDefaults );
1688 // FillEditItemSet adjusts font height to 1/100th mm,
1689 // but for header/footer twips is needed, as in the PatternAttr:
1690 pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
1691 pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
1692 pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
1693 // dont use font color, because background color is not used
1694 //! there's no way to set the background for note pages
1695 pEditDefaults->ClearItem( EE_CHAR_COLOR );
1696 if (ScGlobal::IsSystemRTL())
1697 pEditDefaults->Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
1700 pEditEngine->SetData( aFieldData ); // Set page count etc.
1703 // nStartY = logic
1704 void ScPrintFunc::PrintHF( long nPageNo, bool bHeader, long nStartY,
1705 bool bDoPrint, ScPreviewLocationData* pLocationData )
1707 const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr;
1709 pDev->SetMapMode( aTwipMode ); // Head-/Footlines in Twips
1711 bool bLeft = IsLeft(nPageNo) && !rParam.bShared;
1712 const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight;
1714 long nLineStartX = aPageRect.Left() + rParam.nLeft;
1715 long nLineEndX = aPageRect.Right() - rParam.nRight;
1716 long nLineWidth = nLineEndX - nLineStartX + 1;
1718 // Edit-Engine
1720 Point aStart( nLineStartX, nStartY );
1721 Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1722 if ( rParam.pBorder )
1724 long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(SvxBoxItemLine::LEFT);
1725 long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(SvxBoxItemLine::TOP);
1726 aStart.X() += nLeft;
1727 aStart.Y() += nTop;
1728 aPaperSize.Width() -= nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(SvxBoxItemLine::RIGHT);
1729 aPaperSize.Height() -= nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(SvxBoxItemLine::BOTTOM);
1732 if ( rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE )
1734 long nLeft = rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::LEFT);
1735 long nTop = rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::TOP);
1736 aStart.X() += nLeft;
1737 aStart.Y() += nTop;
1738 aPaperSize.Width() -= nLeft + rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::RIGHT);
1739 aPaperSize.Height() -= nTop + rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::BOTTOM);
1742 aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo;
1743 MakeEditEngine();
1745 pEditEngine->SetPaperSize(aPaperSize);
1747 // Frame / Background
1749 Point aBorderStart( nLineStartX, nStartY );
1750 Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1751 if ( rParam.bDynamic )
1753 // adjust here again, for even/odd head-/footlines
1754 // and probably other breaks by variable (page number etc.)
1756 long nMaxHeight = 0;
1757 nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) );
1758 nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) );
1759 nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) );
1760 if (rParam.pBorder)
1761 nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
1762 lcl_LineTotal( rParam.pBorder->GetBottom() ) +
1763 rParam.pBorder->GetDistance(SvxBoxItemLine::TOP) +
1764 rParam.pBorder->GetDistance(SvxBoxItemLine::BOTTOM);
1765 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
1766 nMaxHeight += rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::TOP) +
1767 rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::BOTTOM);
1769 if (nMaxHeight < rParam.nManHeight-rParam.nDistance)
1770 nMaxHeight = rParam.nManHeight-rParam.nDistance; // configured Minimum
1772 aBorderSize.Height() = nMaxHeight;
1775 if ( bDoPrint )
1777 double nOldScaleX = nScaleX;
1778 double nOldScaleY = nScaleY;
1779 nScaleX = nScaleY = 1.0; // output directly in Twips
1780 DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(),
1781 rParam.pBorder, rParam.pBack, rParam.pShadow );
1782 nScaleX = nOldScaleX;
1783 nScaleY = nOldScaleY;
1785 // Clipping for Text
1787 pDev->SetClipRegion(vcl::Region(Rectangle(aStart, aPaperSize)));
1789 // left
1791 const EditTextObject* pObject = pHFItem->GetLeftArea();
1792 if (pObject)
1794 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1795 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1796 Point aDraw = aStart;
1797 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1798 if (nDif > 0)
1799 aDraw.Y() += nDif / 2;
1800 pEditEngine->Draw( pDev, aDraw, 0 );
1803 // center
1805 pObject = pHFItem->GetCenterArea();
1806 if (pObject)
1808 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
1809 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1810 Point aDraw = aStart;
1811 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1812 if (nDif > 0)
1813 aDraw.Y() += nDif / 2;
1814 pEditEngine->Draw( pDev, aDraw, 0 );
1817 // right
1819 pObject = pHFItem->GetRightArea();
1820 if (pObject)
1822 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
1823 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1824 Point aDraw = aStart;
1825 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1826 if (nDif > 0)
1827 aDraw.Y() += nDif / 2;
1828 pEditEngine->Draw( pDev, aDraw, 0 );
1831 pDev->SetClipRegion();
1834 if ( pLocationData )
1836 Rectangle aHeaderRect( aBorderStart, aBorderSize );
1837 pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft );
1841 long ScPrintFunc::DoNotes( long nNoteStart, bool bDoPrint, ScPreviewLocationData* pLocationData )
1843 if (bDoPrint)
1844 pDev->SetMapMode(aTwipMode);
1846 MakeEditEngine();
1847 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1848 pEditEngine->SetDefaults( *pEditDefaults );
1850 vcl::Font aMarkFont;
1851 ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
1852 static_cast<const ScPatternAttr&>(pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).GetFont( aMarkFont, eColorMode );
1853 pDev->SetFont( aMarkFont );
1854 long nMarkLen = pDev->GetTextWidth(OUString("GW99999:"));
1855 // without Space-Char, because it rarle arrives there
1857 Size aDataSize = aPageRect.GetSize();
1858 if ( nMarkLen > aDataSize.Width() / 2 ) // everything much too small?
1859 nMarkLen = aDataSize.Width() / 2; // split the page appropriately
1860 aDataSize.Width() -= nMarkLen;
1862 pEditEngine->SetPaperSize( aDataSize );
1863 long nPosX = aPageRect.Left() + nMarkLen;
1864 long nPosY = aPageRect.Top();
1866 long nCount = 0;
1867 long nSize = aNotePosList.size();
1868 bool bOk;
1871 bOk = false;
1872 if ( nNoteStart + nCount < nSize)
1874 ScAddress &rPos = aNotePosList[ nNoteStart + nCount ];
1876 if( const ScPostIt* pNote = pDoc->GetNote( rPos ) )
1878 if(const EditTextObject *pEditText = pNote->GetEditTextObject())
1879 pEditEngine->SetText(*pEditText);
1880 long nTextHeight = pEditEngine->GetTextHeight();
1881 if ( nPosY + nTextHeight < aPageRect.Bottom() )
1883 if (bDoPrint)
1885 pEditEngine->Draw( pDev, Point( nPosX, nPosY ), 0 );
1887 OUString aMarkStr(rPos.Format(SCA_VALID, pDoc, pDoc->GetAddressConvention()));
1888 aMarkStr += ":";
1890 // cell position also via EditEngine, for correct positioning
1891 pEditEngine->SetText(aMarkStr);
1892 pEditEngine->Draw( pDev, Point( aPageRect.Left(), nPosY ), 0 );
1895 if ( pLocationData )
1897 Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) );
1898 pLocationData->AddNoteText( aTextRect, rPos );
1899 Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) );
1900 pLocationData->AddNoteMark( aMarkRect, rPos );
1903 nPosY += nTextHeight;
1904 nPosY += 200; // Distance
1905 ++nCount;
1906 bOk = true;
1911 while (bOk);
1913 return nCount;
1916 long ScPrintFunc::PrintNotes( long nPageNo, long nNoteStart, bool bDoPrint, ScPreviewLocationData* pLocationData )
1918 if ( nNoteStart >= (long) aNotePosList.size() || !aTableParam.bNotes )
1919 return 0;
1921 if ( bDoPrint && bClearWin )
1923 //! aggregate PrintPage !!!
1925 Color aBackgroundColor( COL_WHITE );
1926 if ( bUseStyleColor )
1927 aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1929 pDev->SetMapMode(aOffsetMode);
1930 pDev->SetLineColor();
1931 pDev->SetFillColor(aBackgroundColor);
1932 pDev->DrawRect(Rectangle(Point(),
1933 Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
1934 (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
1937 // adjust aPageRect for left/right page
1939 Rectangle aTempRect = Rectangle( Point(), aPageSize );
1940 if (IsMirror(nPageNo))
1942 aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
1943 aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
1945 else
1947 aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
1948 aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
1951 if ( pPrinter && bDoPrint )
1953 OSL_FAIL( "StartPage does not exist anymore" );
1956 if ( bDoPrint || pLocationData )
1958 // Head and foot lines
1960 if (aHdr.bEnable)
1962 long nHeaderY = aPageRect.Top()-aHdr.nHeight;
1963 PrintHF( nPageNo, true, nHeaderY, bDoPrint, pLocationData );
1965 if (aFtr.bEnable)
1967 long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
1968 PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
1972 long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData );
1974 if ( pPrinter && bDoPrint )
1976 OSL_FAIL( "EndPage does not exist anymore" );
1979 return nCount;
1982 void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1983 bool bDoPrint, ScPreviewLocationData* pLocationData )
1985 bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1986 long nLayoutSign = bLayoutRTL ? -1 : 1;
1988 // nPageNo is the page number within all sheets of one "start page" setting
1990 if ( bClearWin && bDoPrint )
1992 // must exactly fit to painting the frame in preview.cxx !!!
1994 Color aBackgroundColor( COL_WHITE );
1995 if ( bUseStyleColor )
1996 aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1998 pDev->SetMapMode(aOffsetMode);
1999 pDev->SetLineColor();
2000 pDev->SetFillColor(aBackgroundColor);
2001 pDev->DrawRect(Rectangle(Point(),
2002 Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
2003 (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
2006 // adjust aPageRect for left/right page
2008 Rectangle aTempRect = Rectangle( Point(), aPageSize );
2009 if (IsMirror(nPageNo))
2011 aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
2012 aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
2014 else
2016 aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
2017 aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
2020 if ( aAreaParam.bRepeatCol )
2021 if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol )
2022 nX1 = nRepeatEndCol + 1;
2023 bool bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol);
2024 if ( aAreaParam.bRepeatRow )
2025 if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow )
2026 nY1 = nRepeatEndRow + 1;
2027 bool bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow);
2029 // use new object hide flags in SdrPaintView
2030 if(pDrawView)
2032 pDrawView->setHideOle(!aTableParam.bObjects);
2033 pDrawView->setHideChart(!aTableParam.bCharts);
2034 pDrawView->setHideDraw(!aTableParam.bDrawings);
2035 pDrawView->setHideFormControl(!aTableParam.bDrawings);
2038 if ( pPrinter && bDoPrint )
2040 OSL_FAIL( "StartPage does not exist anymore" );
2043 // head and foot lines (without centering)
2045 if (aHdr.bEnable)
2047 long nHeaderY = aPageRect.Top()-aHdr.nHeight;
2048 PrintHF( nPageNo, true, nHeaderY, bDoPrint, pLocationData );
2050 if (aFtr.bEnable)
2052 long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
2053 PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
2056 // Position ( margins / centering )
2058 long nLeftSpace = aPageRect.Left(); // Document-Twips
2059 long nTopSpace = aPageRect.Top();
2060 if ( bCenterHor || bLayoutRTL )
2062 long nDataWidth = 0;
2063 SCCOL i;
2064 for (i=nX1; i<=nX2; i++)
2065 nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2066 if (bDoRepCol)
2067 for (i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2068 nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2069 if (aTableParam.bHeaders)
2070 nDataWidth += (long) PRINT_HEADER_WIDTH;
2071 if (pBorderItem)
2072 nDataWidth += pBorderItem->GetDistance(SvxBoxItemLine::LEFT) +
2073 pBorderItem->GetDistance(SvxBoxItemLine::RIGHT); //! Line width?
2074 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2075 nDataWidth += pShadowItem->CalcShadowSpace(SvxShadowItemSide::LEFT) +
2076 pShadowItem->CalcShadowSpace(SvxShadowItemSide::RIGHT);
2077 if ( bCenterHor )
2079 nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2; // LTR or RTL
2080 if (pBorderItem)
2081 nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft());
2083 else if ( bLayoutRTL )
2084 nLeftSpace += aPageRect.GetWidth() - nDataWidth; // align to the right edge of the page
2086 if ( bCenterVer )
2088 long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab);
2089 if (bDoRepRow)
2090 nDataHeight += pDoc->GetRowHeight( nRepeatStartRow,
2091 nRepeatEndRow, nPrintTab);
2092 if (aTableParam.bHeaders)
2093 nDataHeight += (long) PRINT_HEADER_HEIGHT;
2094 if (pBorderItem)
2095 nDataHeight += pBorderItem->GetDistance(SvxBoxItemLine::TOP) +
2096 pBorderItem->GetDistance(SvxBoxItemLine::BOTTOM); //! Line width?
2097 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2098 nDataHeight += pShadowItem->CalcShadowSpace(SvxShadowItemSide::TOP) +
2099 pShadowItem->CalcShadowSpace(SvxShadowItemSide::BOTTOM);
2100 nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2;
2101 if (pBorderItem)
2102 nTopSpace -= lcl_LineTotal(pBorderItem->GetTop());
2105 // calculate sizes of the elements for partitioning
2106 // (header, repeat, data)
2108 long nHeaderWidth = 0;
2109 long nHeaderHeight = 0;
2110 long nRepeatWidth = 0;
2111 long nRepeatHeight = 0;
2112 long nContentWidth = 0; // scaled - not the same as nDataWidth above
2113 long nContentHeight = 0;
2114 if (aTableParam.bHeaders)
2116 nHeaderWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
2117 nHeaderHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
2119 if (bDoRepCol)
2120 for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2121 nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2122 if (bDoRepRow)
2123 nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow,
2124 nRepeatEndRow, nPrintTab, nScaleY);
2125 for (SCCOL i=nX1; i<=nX2; i++)
2126 nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2127 nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab,
2128 nScaleY);
2130 // partition the page
2132 long nStartX = ((long) ( nLeftSpace * nScaleX ));
2133 long nStartY = ((long) ( nTopSpace * nScaleY ));
2134 long nInnerStartX = nStartX;
2135 long nInnerStartY = nStartY;
2136 if (pBorderItem)
2138 nInnerStartX += (long) ( ( lcl_LineTotal(pBorderItem->GetLeft()) +
2139 pBorderItem->GetDistance(SvxBoxItemLine::LEFT) ) * nScaleX );
2140 nInnerStartY += (long) ( ( lcl_LineTotal(pBorderItem->GetTop()) +
2141 pBorderItem->GetDistance(SvxBoxItemLine::TOP) ) * nScaleY );
2143 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2145 nInnerStartX += (long) ( pShadowItem->CalcShadowSpace(SvxShadowItemSide::LEFT) * nScaleX );
2146 nInnerStartY += (long) ( pShadowItem->CalcShadowSpace(SvxShadowItemSide::TOP) * nScaleY );
2149 if ( bLayoutRTL )
2151 // arrange elements starting from the right edge
2152 nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth;
2154 // make rounding easier so the elements are really next to each other in preview
2155 Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode );
2156 long nOffsetOneX = aOffsetOnePixel.Width();
2157 nInnerStartX += nOffsetOneX / 2;
2160 long nFrameStartX = nInnerStartX;
2161 long nFrameStartY = nInnerStartY;
2163 long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign; // widths/heights are 0 if not used
2164 long nRepStartY = nInnerStartY + nHeaderHeight;
2165 long nDataX = nRepStartX + nRepeatWidth * nLayoutSign;
2166 long nDataY = nRepStartY + nRepeatHeight;
2167 long nEndX = nDataX + nContentWidth * nLayoutSign;
2168 long nEndY = nDataY + nContentHeight;
2169 long nFrameEndX = nEndX;
2170 long nFrameEndY = nEndY;
2172 if ( bLayoutRTL )
2174 // each element's start position is its left edge
2175 //! subtract one pixel less?
2176 nInnerStartX -= nHeaderWidth; // used for header
2177 nRepStartX -= nRepeatWidth;
2178 nDataX -= nContentWidth;
2180 // continue right of the main elements again
2181 nEndX += nHeaderWidth + nRepeatWidth + nContentWidth;
2184 // Page frame / background
2186 //! adjust nEndX/Y
2188 long nBorderEndX = nEndX;
2189 long nBorderEndY = nEndY;
2190 if (pBorderItem)
2192 nBorderEndX += (long) ( ( lcl_LineTotal(pBorderItem->GetRight()) +
2193 pBorderItem->GetDistance(SvxBoxItemLine::RIGHT) ) * nScaleX );
2194 nBorderEndY += (long) ( ( lcl_LineTotal(pBorderItem->GetBottom()) +
2195 pBorderItem->GetDistance(SvxBoxItemLine::BOTTOM) ) * nScaleY );
2197 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2199 nBorderEndX += (long) ( pShadowItem->CalcShadowSpace(SvxShadowItemSide::RIGHT) * nScaleX );
2200 nBorderEndY += (long) ( pShadowItem->CalcShadowSpace(SvxShadowItemSide::BOTTOM) * nScaleY );
2203 if ( bDoPrint )
2205 pDev->SetMapMode( aOffsetMode );
2206 DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY,
2207 pBorderItem, pBackgroundItem, pShadowItem );
2209 pDev->SetMapMode( aTwipMode );
2212 pDev->SetMapMode( aOffsetMode );
2214 // Output repeating rows/columns
2216 if (bDoRepCol && bDoRepRow)
2218 if ( bDoPrint )
2219 PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2220 nRepStartX,nRepStartY, true, true, false, false );
2221 if ( pLocationData )
2222 LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2223 nRepStartX,nRepStartY, true, true, *pLocationData );
2225 if (bDoRepCol)
2227 if ( bDoPrint )
2228 PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY,
2229 true, !bDoRepRow, false, true );
2230 if ( pLocationData )
2231 LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, true, false, *pLocationData );
2233 if (bDoRepRow)
2235 if ( bDoPrint )
2236 PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY,
2237 !bDoRepCol, true, true, false );
2238 if ( pLocationData )
2239 LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, false, true, *pLocationData );
2242 // output data
2244 if ( bDoPrint )
2245 PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow, true, true );
2246 if ( pLocationData )
2247 LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, false,false, *pLocationData );
2249 // output column/row headers
2250 // after data (through probably shadow)
2252 Color aGridColor( COL_BLACK );
2253 if ( bUseStyleColor )
2254 aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2256 if (aTableParam.bHeaders)
2258 if ( bDoPrint )
2260 pDev->SetLineColor( aGridColor );
2261 pDev->SetFillColor();
2262 pDev->SetMapMode(aOffsetMode);
2265 ScPatternAttr aPattern( pDoc->GetPool() );
2266 vcl::Font aFont;
2267 ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
2268 aPattern.GetFont( aFont, eColorMode, pDev );
2269 pDev->SetFont( aFont );
2271 if (bDoRepCol)
2273 if ( bDoPrint )
2274 PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY );
2275 if ( pLocationData )
2276 LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, true, *pLocationData );
2278 if ( bDoPrint )
2279 PrintColHdr( nX1,nX2, nDataX,nInnerStartY );
2280 if ( pLocationData )
2281 LocateColHdr( nX1,nX2, nDataX,nInnerStartY, false, *pLocationData );
2282 if (bDoRepRow)
2284 if ( bDoPrint )
2285 PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY );
2286 if ( pLocationData )
2287 LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, true, *pLocationData );
2289 if ( bDoPrint )
2290 PrintRowHdr( nY1,nY2, nInnerStartX,nDataY );
2291 if ( pLocationData )
2292 LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, false, *pLocationData );
2295 // simple frame
2297 if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) )
2299 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
2300 long nOneX = aOnePixel.Width();
2301 long nOneY = aOnePixel.Height();
2303 long nLeftX = nFrameStartX;
2304 long nTopY = nFrameStartY - nOneY;
2305 long nRightX = nFrameEndX;
2306 long nBottomY = nFrameEndY - nOneY;
2307 if ( !bLayoutRTL )
2309 nLeftX -= nOneX;
2310 nRightX -= nOneX;
2312 pDev->SetMapMode(aOffsetMode);
2313 pDev->SetLineColor( aGridColor );
2314 pDev->SetFillColor();
2315 pDev->DrawRect( Rectangle( nLeftX, nTopY, nRightX, nBottomY ) );
2316 // nEndX/Y without frame-adaption
2319 if ( pPrinter && bDoPrint )
2321 OSL_FAIL( "EndPage does not exist anymore" );
2324 aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab );
2325 bSourceRangeValid = true;
2328 void ScPrintFunc::SetOffset( const Point& rOfs )
2330 aSrcOffset = rOfs;
2333 void ScPrintFunc::SetManualZoom( sal_uInt16 nNewZoom )
2335 nManualZoom = nNewZoom;
2338 void ScPrintFunc::SetClearFlag( bool bFlag )
2340 bClearWin = bFlag;
2343 void ScPrintFunc::SetUseStyleColor( bool bFlag )
2345 bUseStyleColor = bFlag;
2346 if (pEditEngine)
2347 pEditEngine->EnableAutoColor( bUseStyleColor );
2350 void ScPrintFunc::SetRenderFlag( bool bFlag )
2352 bIsRender = bFlag; // set when using XRenderable (PDF)
2355 void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects()
2357 aTableParam.bCellContent = false;
2358 aTableParam.bNotes = false;
2359 aTableParam.bGrid = false;
2360 aTableParam.bHeaders = false;
2361 aTableParam.bFormulas = false;
2362 aTableParam.bNullVals = false;
2365 // UpdatePages is only called from outside to set the breaks correctly for viewing
2366 // - always without UserArea
2368 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 true;
2401 long ScPrintFunc::CountPages() // sets also nPagesX, nPagesY
2403 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(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++)
2443 OSL_ENSURE(nY < maPageRows.size(), "vector access error for maPageRows (!)");
2444 nPages += maPageRows[nY].CountVisible();
2446 else
2447 nPages += ((long) nPagesX) * nPagesY;
2448 if ( pPageData )
2449 FillPageData();
2452 else
2454 CalcZoom(RANGENO_NORANGE); // calculate Zoom
2455 if ( aTableParam.bSkipEmpty )
2456 for (nY=0; nY<nPagesY; nY++)
2458 OSL_ENSURE(nY < maPageRows.size(), "vector access error for maPageRows (!)");
2459 nPages += maPageRows[nY].CountVisible();
2461 else
2462 nPages += ((long) nPagesX) * nPagesY;
2463 if ( pPageData )
2464 FillPageData();
2466 return nPages;
2468 else
2470 nPagesX = nPagesY = nTotalY = 0;
2471 return 0;
2475 long ScPrintFunc::CountNotePages()
2477 if ( !aTableParam.bNotes || !bPrintCurrentTable )
2478 return 0;
2480 bool bError = false;
2481 if (!aAreaParam.bPrintArea)
2482 bError = !AdjustPrintArea(true); // completely search in Doc
2484 sal_uInt16 nRepeats = 1; // how often go through it ?
2485 if (bMultiArea)
2486 nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2487 if (bError)
2488 nRepeats = 0;
2490 for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2492 bool bDoThis = true;
2493 if (bMultiArea) // go through all Areas
2495 const ScRange* pThisRange = pDoc->GetPrintRange( nPrintTab, nStep );
2496 if ( pThisRange )
2498 nStartCol = pThisRange->aStart.Col();
2499 nStartRow = pThisRange->aStart.Row();
2500 nEndCol = pThisRange->aEnd .Col();
2501 nEndRow = pThisRange->aEnd .Row();
2502 bDoThis = AdjustPrintArea(false);
2506 if (bDoThis)
2508 for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
2510 if (pDoc->HasColNotes(nCol, nPrintTab))
2512 for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
2514 if ( pDoc->HasNote(nCol, nRow, nPrintTab) )
2515 aNotePosList.push_back( ScAddress( nCol, nRow, nPrintTab ) );
2522 long nPages = 0;
2523 long nNoteNr = 0;
2524 long nNoteAdd;
2527 nNoteAdd = PrintNotes( nPages, nNoteNr, false, NULL );
2528 if (nNoteAdd)
2530 nNoteNr += nNoteAdd;
2531 ++nPages;
2534 while (nNoteAdd);
2536 return nPages;
2539 void ScPrintFunc::InitModes() // set MapModes from nZoom etc.
2541 aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom );
2543 long nEffZoom = nZoom * (long) nManualZoom;
2544 nScaleX = nScaleY = HMM_PER_TWIPS; // output in 1/100 mm
2546 Fraction aZoomFract( nEffZoom,10000 );
2547 Fraction aHorFract = aZoomFract;
2549 if ( !pPrinter && !bIsRender ) // adjust scale for preview
2551 double nFact = pDocShell->GetOutputFactor();
2552 aHorFract = Fraction( (long)( nEffZoom / nFact ), 10000 );
2555 aLogicMode = MapMode( MAP_100TH_MM, Point(), aHorFract, aZoomFract );
2557 Point aLogicOfs( -aOffset.X(), -aOffset.Y() );
2558 aOffsetMode = MapMode( MAP_100TH_MM, aLogicOfs, aHorFract, aZoomFract );
2560 Point aTwipsOfs( (long) ( -aOffset.X() / nScaleX + 0.5 ), (long) ( -aOffset.Y() / nScaleY + 0.5 ) );
2561 aTwipMode = MapMode( MAP_TWIP, aTwipsOfs, aHorFract, aZoomFract );
2564 void ScPrintFunc::ApplyPrintSettings()
2566 if ( pPrinter )
2569 // Configure Printer to Printing
2571 Size aEnumSize = aPageSize;
2573 pPrinter->SetOrientation( bLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT );
2574 if ( bLandscape )
2576 // landscape is always interpreted as a rotation by 90 degrees !
2577 // this leads to non WYSIWIG but at least it prints!
2578 // #i21775#
2579 long nTemp = aEnumSize.Width();
2580 aEnumSize.Width() = aEnumSize.Height();
2581 aEnumSize.Height() = nTemp;
2583 Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, true );
2584 sal_uInt16 nPaperBin = static_cast<const SvxPaperBinItem&>(pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue();
2586 pPrinter->SetPaper( ePaper );
2587 if ( PAPER_USER == ePaper )
2589 MapMode aPrinterMode = pPrinter->GetMapMode();
2590 MapMode aLocalMode( MAP_TWIP );
2591 pPrinter->SetMapMode( aLocalMode );
2592 pPrinter->SetPaperSizeUser( aEnumSize );
2593 pPrinter->SetMapMode( aPrinterMode );
2596 pPrinter->SetPaperBin( nPaperBin );
2600 // rPageRanges = range for all tables
2601 // nStartPage = rPageRanges starts at nStartPage
2602 // nDisplayStart = continuous number for displaying the page number
2604 long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges,
2605 long nStartPage, long nDisplayStart, bool bDoPrint,
2606 ScPreviewLocationData* pLocationData )
2608 OSL_ENSURE(pDev,"Device == NULL");
2609 if (!pParamSet)
2610 return 0;
2612 if ( pPrinter && bDoPrint )
2613 ApplyPrintSettings();
2615 InitModes();
2616 if ( pLocationData )
2618 pLocationData->SetCellMapMode( aOffsetMode );
2619 pLocationData->SetPrintTab( nPrintTab );
2622 MakeTableString();
2624 long nPageNo = 0;
2625 long nPrinted = 0;
2626 long nEndPage = rPageRanges.GetTotalRange().Max();
2628 sal_uInt16 nRepeats = 1;
2629 if (bMultiArea)
2630 nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2631 for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2633 if (bMultiArea) // replace area
2635 CalcZoom(nStep); // also sets nStartCol etc. new
2636 InitModes();
2639 SCCOL nX1;
2640 SCROW nY1;
2641 SCCOL nX2;
2642 SCROW nY2;
2643 size_t nCountX;
2644 size_t nCountY;
2646 if (aTableParam.bTopDown) // top-bottom
2648 nX1 = nStartCol;
2649 for (nCountX=0; nCountX<nPagesX; nCountX++)
2651 OSL_ENSURE(nCountX < maPageEndX.size(), "vector access error for maPageEndX (!)");
2652 nX2 = maPageEndX[nCountX];
2653 for (nCountY=0; nCountY<nPagesY; nCountY++)
2655 OSL_ENSURE(nCountY < maPageRows.size(), "vector access error for maPageRows (!)");
2656 nY1 = maPageRows[nCountY].GetStartRow();
2657 nY2 = maPageRows[nCountY].GetEndRow();
2658 if ( !aTableParam.bSkipEmpty || !maPageRows[nCountY].IsHidden(nCountX) )
2660 if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2662 PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2663 bDoPrint, pLocationData );
2664 ++nPrinted;
2666 ++nPageNo;
2669 nX1 = nX2 + 1;
2672 else // left to right
2674 for (nCountY=0; nCountY<nPagesY; nCountY++)
2676 OSL_ENSURE(nCountY < maPageRows.size(), "vector access error for maPageRows (!)");
2677 nY1 = maPageRows[nCountY].GetStartRow();
2678 nY2 = maPageRows[nCountY].GetEndRow();
2679 nX1 = nStartCol;
2680 for (nCountX=0; nCountX<nPagesX; nCountX++)
2682 OSL_ENSURE(nCountX < maPageEndX.size(), "vector access error for maPageEndX (!)");
2683 nX2 = maPageEndX[nCountX];
2684 if ( !aTableParam.bSkipEmpty || !maPageRows[nCountY].IsHidden(nCountX) )
2686 if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2688 PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2689 bDoPrint, pLocationData );
2690 ++nPrinted;
2692 ++nPageNo;
2694 nX1 = nX2 + 1;
2700 aFieldData.aTabName = ScGlobal::GetRscString( STR_NOTES );
2702 long nNoteNr = 0;
2703 long nNoteAdd;
2706 if ( nPageNo+nStartPage <= nEndPage )
2708 bool bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 );
2709 nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected,
2710 ( bPageSelected ? pLocationData : NULL ) );
2711 if ( nNoteAdd )
2713 nNoteNr += nNoteAdd;
2714 if (bPageSelected)
2716 ++nPrinted;
2717 bSourceRangeValid = false; // last page was no cell range
2719 ++nPageNo;
2722 else
2723 nNoteAdd = 0;
2725 while (nNoteAdd);
2727 if ( bMultiArea )
2728 ResetBreaks(nPrintTab); //breaks correct for displaying
2730 return nPrinted;
2733 void ScPrintFunc::CalcZoom( sal_uInt16 nRangeNo ) // calculate zoom
2735 sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
2736 const ScRange* pThisRange = NULL;
2737 if ( nRangeNo != RANGENO_NORANGE || nRangeNo < nRCount )
2738 pThisRange = pDoc->GetPrintRange( nPrintTab, nRangeNo );
2739 if ( pThisRange )
2741 nStartCol = pThisRange->aStart.Col();
2742 nStartRow = pThisRange->aStart.Row();
2743 nEndCol = pThisRange->aEnd .Col();
2744 nEndRow = pThisRange->aEnd .Row();
2747 if (!AdjustPrintArea(false)) // empty
2749 nZoom = 100;
2750 nPagesX = nPagesY = nTotalY = 0;
2751 return;
2754 pDoc->SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2756 if (aTableParam.bScalePageNum)
2758 nZoom = 100;
2759 sal_uInt16 nPagesToFit = aTableParam.nScalePageNum;
2761 // If manual breaks are forced, calculate minimum # pages required
2762 if (aTableParam.bForceBreaks)
2764 sal_uInt16 nMinPages = 0;
2765 std::set<SCROW> aRowBreaks;
2766 std::set<SCCOL> aColBreaks;
2767 pDoc->GetAllRowBreaks(aRowBreaks, nPrintTab, false, true);
2768 pDoc->GetAllColBreaks(aColBreaks, nPrintTab, false, true);
2769 nMinPages = (aRowBreaks.size() + 1) * (aColBreaks.size() + 1);
2771 // #i54993# use min forced by breaks if it's > # pages in
2772 // scale parameter to avoid bottoming out at <= ZOOM_MIN
2773 nPagesToFit = nMinPages > nPagesToFit ? nMinPages : nPagesToFit;
2776 sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2777 while (true)
2779 if (nZoom <= ZOOM_MIN)
2780 break;
2782 CalcPages();
2783 bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit);
2785 if (bFitsPage)
2787 if (nZoom == 100)
2788 // If it fits at 100%, it's good enough for me.
2789 break;
2791 nLastFitZoom = nZoom;
2792 nZoom = (nLastNonFitZoom + nZoom) / 2;
2794 if (nLastFitZoom == nZoom)
2795 // It converged. Use this zoom level.
2796 break;
2798 else
2800 if (nZoom - nLastFitZoom <= 1)
2802 nZoom = nLastFitZoom;
2803 CalcPages();
2804 break;
2807 nLastNonFitZoom = nZoom;
2808 nZoom = (nLastFitZoom + nZoom) / 2;
2812 else if (aTableParam.bScaleTo)
2814 nZoom = 100;
2815 sal_uInt16 nW = aTableParam.nScaleWidth;
2816 sal_uInt16 nH = aTableParam.nScaleHeight;
2818 // If manual breaks are forced, calculate minimum # pages required
2819 if (aTableParam.bForceBreaks)
2821 sal_uInt16 nMinPagesW = 0, nMinPagesH = 0;
2822 std::set<SCROW> aRowBreaks;
2823 std::set<SCCOL> aColBreaks;
2824 pDoc->GetAllRowBreaks(aRowBreaks, nPrintTab, false, true);
2825 pDoc->GetAllColBreaks(aColBreaks, nPrintTab, false, true);
2826 nMinPagesW = aColBreaks.size() + 1;
2827 nMinPagesH = aRowBreaks.size() + 1;
2829 // #i54993# use min forced by breaks if it's > # pages in
2830 // scale parameters to avoid bottoming out at <= ZOOM_MIN
2831 nW = nMinPagesW > nW ? nMinPagesW : nW;
2832 nH = nMinPagesH > nH ? nMinPagesH : nH;
2835 sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2836 while (true)
2838 if (nZoom <= ZOOM_MIN)
2839 break;
2841 CalcPages();
2842 bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH)));
2844 if (bFitsPage)
2846 if (nZoom == 100)
2847 // If it fits at 100%, it's good enough for me.
2848 break;
2850 nLastFitZoom = nZoom;
2851 nZoom = (nLastNonFitZoom + nZoom) / 2;
2853 if (nLastFitZoom == nZoom)
2854 // It converged. Use this zoom level.
2855 break;
2857 else
2859 if (nZoom - nLastFitZoom <= 1)
2861 nZoom = nLastFitZoom;
2862 CalcPages();
2863 break;
2866 nLastNonFitZoom = nZoom;
2867 nZoom = (nLastFitZoom + nZoom) / 2;
2871 else if (aTableParam.bScaleAll)
2873 nZoom = aTableParam.nScaleAll;
2874 if ( nZoom <= ZOOM_MIN )
2875 nZoom = ZOOM_MIN;
2876 CalcPages();
2878 else
2880 OSL_ENSURE( aTableParam.bScaleNone, "kein Scale-Flag gesetzt" );
2881 nZoom = 100;
2882 CalcPages();
2886 Size ScPrintFunc::GetDocPageSize()
2888 // Adjust height of head/foot line
2890 InitModes(); // initialize aTwipMode from nZoom
2891 pDev->SetMapMode( aTwipMode ); // head/foot line in Twips
2892 UpdateHFHeight( aHdr );
2893 UpdateHFHeight( aFtr );
2895 // Page size in Document-Twips
2896 // Calculating Left / Right also in PrintPage
2898 aPageRect = Rectangle( Point(), aPageSize );
2899 aPageRect.Left() = ( aPageRect.Left() + nLeftMargin ) * 100 / nZoom;
2900 aPageRect.Right() = ( aPageRect.Right() - nRightMargin ) * 100 / nZoom;
2901 aPageRect.Top() = ( aPageRect.Top() + nTopMargin ) * 100 / nZoom + aHdr.nHeight;
2902 aPageRect.Bottom() = ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight;
2904 Size aDocPageSize = aPageRect.GetSize();
2905 if (aTableParam.bHeaders)
2907 aDocPageSize.Width() -= (long) PRINT_HEADER_WIDTH;
2908 aDocPageSize.Height() -= (long) PRINT_HEADER_HEIGHT;
2910 if (pBorderItem)
2912 aDocPageSize.Width() -= lcl_LineTotal(pBorderItem->GetLeft()) +
2913 lcl_LineTotal(pBorderItem->GetRight()) +
2914 pBorderItem->GetDistance(SvxBoxItemLine::LEFT) +
2915 pBorderItem->GetDistance(SvxBoxItemLine::RIGHT);
2916 aDocPageSize.Height() -= lcl_LineTotal(pBorderItem->GetTop()) +
2917 lcl_LineTotal(pBorderItem->GetBottom()) +
2918 pBorderItem->GetDistance(SvxBoxItemLine::TOP) +
2919 pBorderItem->GetDistance(SvxBoxItemLine::BOTTOM);
2921 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2923 aDocPageSize.Width() -= pShadowItem->CalcShadowSpace(SvxShadowItemSide::LEFT) +
2924 pShadowItem->CalcShadowSpace(SvxShadowItemSide::RIGHT);
2925 aDocPageSize.Height() -= pShadowItem->CalcShadowSpace(SvxShadowItemSide::TOP) +
2926 pShadowItem->CalcShadowSpace(SvxShadowItemSide::BOTTOM);
2928 return aDocPageSize;
2931 void ScPrintFunc::ResetBreaks( SCTAB nTab ) // Set Breaks correctly for view
2933 pDoc->SetPageSize( nTab, GetDocPageSize() );
2934 pDoc->UpdatePageBreaks( nTab, NULL );
2937 static void lcl_SetHidden( ScDocument* pDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry,
2938 SCCOL nStartCol, const std::vector< SCCOL >& rPageEndX )
2940 size_t nPagesX = rPageRowEntry.GetPagesX();
2941 SCROW nStartRow = rPageRowEntry.GetStartRow();
2942 SCROW nEndRow = rPageRowEntry.GetEndRow();
2944 bool bLeftIsEmpty = false;
2945 ScRange aTempRange;
2946 Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 );
2948 for (size_t i=0; i<nPagesX; i++)
2950 OSL_ENSURE(i < rPageEndX.size(), "vector access error for maPageEndX (!)");
2951 SCCOL nEndCol = rPageEndX[i];
2952 if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow,
2953 bLeftIsEmpty, &aTempRange, &aTempRect ) )
2955 rPageRowEntry.SetHidden(i);
2956 bLeftIsEmpty = true;
2958 else
2959 bLeftIsEmpty = false;
2961 nStartCol = nEndCol+1;
2965 void ScPrintFunc::CalcPages() // calculates aPageRect and pages from nZoom
2967 // #i123672# use dynamic mem to react on size changes
2968 if (maPageEndX.size() < MAXCOL+1)
2970 maPageEndX.resize(MAXCOL+1, SCCOL());
2973 pDoc->SetPageSize( nPrintTab, GetDocPageSize() );
2974 if (aAreaParam.bPrintArea)
2976 ScRange aRange( nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab );
2977 pDoc->UpdatePageBreaks( nPrintTab, &aRange );
2979 else
2981 pDoc->UpdatePageBreaks( nPrintTab, NULL ); // else, end is marked
2984 const size_t nRealCnt = nEndRow-nStartRow+1;
2986 // #i123672# use dynamic mem to react on size changes
2987 if (maPageEndY.size() < nRealCnt+1)
2989 maPageEndY.resize(nRealCnt+1, SCROW());
2992 // #i123672# use dynamic mem to react on size changes
2993 if (maPageRows.size() < nRealCnt+1)
2995 maPageRows.resize(nRealCnt+1, ScPageRowEntry());
2998 // Page alignment/splitting after breaks in Col/RowFlags
2999 // Of several breaks in a hidden area, only one counts.
3001 nPagesX = 0;
3002 nPagesY = 0;
3003 nTotalY = 0;
3005 bool bVisCol = false;
3006 for (SCCOL i=nStartCol; i<=nEndCol; i++)
3008 bool bHidden = pDoc->ColHidden(i, nPrintTab);
3009 bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE);
3010 if ( i>nStartCol && bVisCol && bPageBreak )
3012 OSL_ENSURE(nPagesX < maPageEndX.size(), "vector access error for maPageEndX (!)");
3013 maPageEndX[nPagesX] = i-1;
3014 ++nPagesX;
3015 bVisCol = false;
3017 if (!bHidden)
3018 bVisCol = true;
3020 if (bVisCol) // also at the end, no empty pages
3022 OSL_ENSURE(nPagesX < maPageEndX.size(), "vector access error for maPageEndX (!)");
3023 maPageEndX[nPagesX] = nEndCol;
3024 ++nPagesX;
3027 bool bVisRow = false;
3028 SCROW nPageStartRow = nStartRow;
3029 SCROW nLastVisibleRow = -1;
3031 ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab));
3032 SCROW nNextPageBreak = pRowBreakIter->first();
3033 while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow)
3034 // Skip until the page break position is at the start row or greater.
3035 nNextPageBreak = pRowBreakIter->next();
3037 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
3039 bool bPageBreak = (nNextPageBreak == nRow);
3040 if (bPageBreak)
3041 nNextPageBreak = pRowBreakIter->next();
3043 if (nRow > nStartRow && bVisRow && bPageBreak )
3045 OSL_ENSURE(nTotalY < maPageEndY.size(), "vector access error for maPageEndY (!)");
3046 maPageEndY[nTotalY] = nRow-1;
3047 ++nTotalY;
3049 if ( !aTableParam.bSkipEmpty ||
3050 !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) )
3052 OSL_ENSURE(nPagesY < maPageRows.size(), "vector access error for maPageRows (!)");
3053 maPageRows[nPagesY].SetStartRow( nPageStartRow );
3054 maPageRows[nPagesY].SetEndRow( nRow-1 );
3055 maPageRows[nPagesY].SetPagesX( nPagesX );
3056 if (aTableParam.bSkipEmpty)
3057 lcl_SetHidden( pDoc, nPrintTab, maPageRows[nPagesY], nStartCol, maPageEndX );
3058 ++nPagesY;
3061 nPageStartRow = nRow;
3062 bVisRow = false;
3065 if (nRow <= nLastVisibleRow)
3067 // This row is still visible. Don't bother calling RowHidden() to
3068 // find out, for speed optimization.
3069 bVisRow = true;
3070 continue;
3073 SCROW nLastRow = -1;
3074 if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow))
3076 bVisRow = true;
3077 nLastVisibleRow = nLastRow;
3079 else
3080 // skip all hidden rows.
3081 nRow = nLastRow;
3084 if (bVisRow)
3086 OSL_ENSURE(nTotalY < maPageEndY.size(), "vector access error for maPageEndY (!)");
3087 maPageEndY[nTotalY] = nEndRow;
3088 ++nTotalY;
3090 if ( !aTableParam.bSkipEmpty ||
3091 !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) )
3093 OSL_ENSURE(nPagesY < maPageRows.size(), "vector access error for maPageRows (!)");
3094 maPageRows[nPagesY].SetStartRow( nPageStartRow );
3095 maPageRows[nPagesY].SetEndRow( nEndRow );
3096 maPageRows[nPagesY].SetPagesX( nPagesX );
3097 if (aTableParam.bSkipEmpty)
3098 lcl_SetHidden( pDoc, nPrintTab, maPageRows[nPagesY], nStartCol, maPageEndX );
3099 ++nPagesY;
3104 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */