dr78: #i88468# merge page margin display back into DoPrint
[LibreOffice.git] / sc / source / ui / view / printfun.cxx
blob48d95153cfe15efe15a0ca96cb16b032ba5d986e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 // INCLUDE ---------------------------------------------------------------
32 #include "scitems.hxx"
33 #include <editeng/eeitem.hxx>
35 #include "printfun.hxx"
37 #include <svx/svxids.hrc>
38 #include <editeng/adjitem.hxx>
39 #include <editeng/boxitem.hxx>
40 #include <editeng/brshitem.hxx>
41 #include <svtools/colorcfg.hxx>
42 #include <editeng/editstat.hxx> // EE_CNTRL_RTFSTYLESHEETS
43 #include <svx/fmview.hxx>
44 #include <editeng/frmdiritem.hxx>
45 #include <editeng/lrspitem.hxx>
46 #include <editeng/paperinf.hxx>
47 #include <editeng/pbinitem.hxx>
48 #include <editeng/shaditem.hxx>
49 #include <editeng/sizeitem.hxx>
50 #include <svx/svdpagv.hxx>
51 #include <editeng/ulspitem.hxx>
52 #include <sfx2/app.hxx>
53 #include <sfx2/printer.hxx>
54 #include <sfx2/progress.hxx>
55 #include <tools/multisel.hxx>
56 #include <sfx2/docfile.hxx>
57 #include <tools/urlobj.hxx>
58 #include <svx/xoutbmp.hxx>
60 #include "editutil.hxx"
61 #include "docsh.hxx"
62 #include "output.hxx"
63 #include "viewdata.hxx"
64 #include "viewopti.hxx"
65 #include "stlpool.hxx"
66 #include "pagepar.hxx"
67 #include "attrib.hxx"
68 #include "patattr.hxx"
69 #include "docpool.hxx"
70 #include "dociter.hxx"
71 #include "cell.hxx"
72 #include "drawutil.hxx"
73 #include "globstr.hrc"
74 #include "scresid.hxx"
75 #include "sc.hrc"
76 #include "pagedata.hxx"
77 #include "printopt.hxx"
78 #include "prevloc.hxx"
79 #include "scmod.hxx"
80 #include "drwlayer.hxx"
81 #include "fillinfo.hxx"
82 #include "postit.hxx"
84 #include <vcl/lineinfo.hxx>
86 #include <boost/scoped_ptr.hpp>
88 #define ZOOM_MIN 10
90 #define GET_BOOL(set,which) ((const SfxBoolItem&)(set)->Get((which))).GetValue()
91 #define GET_USHORT(set,which) ((const SfxUInt16Item&)(set)->Get((which))).GetValue()
92 #define GET_SHOW(set,which) ( VOBJ_MODE_SHOW == ScVObjMode( ((const ScViewObjectModeItem&)(set)->Get((which))).GetValue()) )
94 //------------------------------------------------------------------------
96 ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r)
98 nStartRow = r.nStartRow;
99 nEndRow = r.nEndRow;
100 nPagesX = r.nPagesX;
101 if (r.pHidden && nPagesX)
103 pHidden = new sal_Bool[nPagesX];
104 memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
106 else
107 pHidden = NULL;
110 const ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r)
112 delete[] pHidden;
114 nStartRow = r.nStartRow;
115 nEndRow = r.nEndRow;
116 nPagesX = r.nPagesX;
117 if (r.pHidden && nPagesX)
119 pHidden = new sal_Bool[nPagesX];
120 memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
122 else
123 pHidden = NULL;
125 return *this;
128 void ScPageRowEntry::SetPagesX(size_t nNew)
130 if (pHidden)
132 OSL_FAIL("SetPagesX nicht nach SetHidden");
133 delete[] pHidden;
134 pHidden = NULL;
136 nPagesX = nNew;
139 void ScPageRowEntry::SetHidden(size_t nX)
141 if ( nX < nPagesX )
143 if ( nX+1 == nPagesX ) // letzte Seite?
144 --nPagesX;
145 else
147 if (!pHidden)
149 pHidden = new sal_Bool[nPagesX];
150 memset( pHidden, false, nPagesX * sizeof(sal_Bool) );
152 pHidden[nX] = sal_True;
157 sal_Bool ScPageRowEntry::IsHidden(size_t nX) const
159 return nX>=nPagesX || ( pHidden && pHidden[nX] ); //! inline?
162 size_t ScPageRowEntry::CountVisible() const
164 if ( pHidden )
166 size_t nVis = 0;
167 for (size_t i=0; i<nPagesX; i++)
168 if (!pHidden[i])
169 ++nVis;
170 return nVis;
172 else
173 return nPagesX;
176 //------------------------------------------------------------------------
178 long lcl_LineTotal(const ::editeng::SvxBorderLine* pLine)
180 return pLine ? ( pLine->GetOutWidth() + pLine->GetInWidth() + pLine->GetDistance() ) : 0;
183 void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
185 pDocShell->UpdatePendingRowHeights( nPrintTab );
186 pDoc = pDocShell->GetDocument();
188 SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
189 if (pDocPrinter)
190 aOldPrinterMode = pDocPrinter->GetMapMode();
192 // einheitlicher MapMode ueber alle Aufrufe (z.B. Repaint !!!),
193 // weil die EditEngine sonst unterschiedliche Texthoehen liefert
194 pDev->SetMapMode(MAP_PIXEL);
196 pPageEndX = NULL;
197 pPageEndY = NULL;
198 pPageRows = NULL;
199 pBorderItem = NULL;
200 pBackgroundItem = NULL;
201 pShadowItem = NULL;
203 pEditEngine = NULL;
204 pEditDefaults = NULL;
206 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
207 SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
208 pDoc->GetPageStyle( nPrintTab ),
209 SFX_STYLE_FAMILY_PAGE );
210 if (pStyleSheet)
211 pParamSet = &pStyleSheet->GetItemSet();
212 else
214 OSL_FAIL("Seitenvorlage nicht gefunden" );
215 pParamSet = NULL;
218 if (!bState)
219 nZoom = 100;
220 nManualZoom = 100;
221 bClearWin = false;
222 bUseStyleColor = false;
223 bIsRender = false;
225 InitParam(pOptions);
227 pPageData = NULL; // wird nur zur Initialisierung gebraucht
230 ScPrintFunc::ScPrintFunc( ScDocShell* pShell, SfxPrinter* pNewPrinter, SCTAB nTab,
231 long nPage, long nDocP, const ScRange* pArea,
232 const ScPrintOptions* pOptions,
233 ScPageBreakData* pData )
234 : pDocShell ( pShell ),
235 pPrinter ( pNewPrinter ),
236 pDrawView ( NULL ),
237 nPrintTab ( nTab ),
238 nPageStart ( nPage ),
239 nDocPages ( nDocP ),
240 pUserArea ( pArea ),
241 bState ( false ),
242 bSourceRangeValid ( false ),
243 bPrintCurrentTable ( false ),
244 bMultiArea ( false ),
245 nTabPages ( 0 ),
246 nTotalPages ( 0 ),
247 nPagesX(0),
248 nPagesY(0),
249 nTotalY(0),
250 pPageData ( pData )
252 pDev = pPrinter;
253 aSrcOffset = pPrinter->PixelToLogic( pPrinter->GetPageOffsetPixel(), MAP_100TH_MM );
254 Construct( pOptions );
257 ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, SCTAB nTab,
258 long nPage, long nDocP, const ScRange* pArea,
259 const ScPrintOptions* pOptions )
260 : pDocShell ( pShell ),
261 pPrinter ( NULL ),
262 pDrawView ( NULL ),
263 nPrintTab ( nTab ),
264 nPageStart ( nPage ),
265 nDocPages ( nDocP ),
266 pUserArea ( pArea ),
267 bState ( false ),
268 bSourceRangeValid ( false ),
269 bPrintCurrentTable ( false ),
270 bMultiArea ( false ),
271 nTabPages ( 0 ),
272 nTotalPages ( 0 ),
273 nPagesX(0),
274 nPagesY(0),
275 nTotalY(0),
276 pPageData ( NULL )
278 pDev = pOutDev;
279 Construct( pOptions );
282 ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell,
283 const ScPrintState& rState, const ScPrintOptions* pOptions )
284 : pDocShell ( pShell ),
285 pPrinter ( NULL ),
286 pDrawView ( NULL ),
287 pUserArea ( NULL ),
288 bSourceRangeValid ( false ),
289 bPrintCurrentTable ( false ),
290 bMultiArea ( false ),
291 nPagesX(0),
292 nPagesY(0),
293 nTotalY(0),
294 pPageData ( NULL )
296 pDev = pOutDev;
298 nPrintTab = rState.nPrintTab;
299 nStartCol = rState.nStartCol;
300 nStartRow = rState.nStartRow;
301 nEndCol = rState.nEndCol;
302 nEndRow = rState.nEndRow;
303 nZoom = rState.nZoom;
304 nPagesX = rState.nPagesX;
305 nPagesY = rState.nPagesY;
306 nTabPages = rState.nTabPages;
307 nTotalPages = rState.nTotalPages;
308 nPageStart = rState.nPageStart;
309 nDocPages = rState.nDocPages;
310 bState = sal_True;
312 Construct( pOptions );
315 void ScPrintFunc::GetPrintState( ScPrintState& rState )
317 rState.nPrintTab = nPrintTab;
318 rState.nStartCol = nStartCol;
319 rState.nStartRow = nStartRow;
320 rState.nEndCol = nEndCol;
321 rState.nEndRow = nEndRow;
322 rState.nZoom = nZoom;
323 rState.nPagesX = nPagesX;
324 rState.nPagesY = nPagesY;
325 rState.nTabPages = nTabPages;
326 rState.nTotalPages = nTotalPages;
327 rState.nPageStart = nPageStart;
328 rState.nDocPages = nDocPages;
331 sal_Bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const
333 rRange = aLastSourceRange;
334 return bSourceRangeValid;
337 void ScPrintFunc::FillPageData()
339 if (pPageData)
341 sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
342 ScPrintRangeData& rData = pPageData->GetData(nCount); // hochzaehlen
344 rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab,
345 nEndCol, nEndRow, nPrintTab ) );
346 rData.SetPagesX( nPagesX, pPageEndX );
347 rData.SetPagesY( nTotalY, pPageEndY );
349 // Einstellungen
350 rData.SetTopDown( aTableParam.bTopDown );
351 rData.SetAutomatic( !aAreaParam.bPrintArea );
355 ScPrintFunc::~ScPrintFunc()
357 delete[] pPageEndX;
358 delete[] pPageEndY;
359 delete[] pPageRows;
360 delete pEditDefaults;
361 delete pEditEngine;
363 // Druckereinstellungen werden jetzt von aussen wiederhergestellt
365 // Fuer DrawingLayer/Charts muss der MapMode am Drucker (RefDevice) immer stimmen
366 SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
367 if (pDocPrinter)
368 pDocPrinter->SetMapMode(aOldPrinterMode);
371 void ScPrintFunc::SetDrawView( FmFormView* pNew )
373 pDrawView = pNew;
376 void lcl_HidePrint( ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 )
378 for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++)
380 RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY];
381 for (SCCOL nX=nX1; nX<=nX2; nX++)
383 const CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1];
384 if (!rCellInfo.bEmptyCellText)
385 if (((const ScProtectionAttr&)rCellInfo.pPatternAttr->
386 GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet)).GetHidePrint())
388 pThisRowInfo->pCellInfo[nX+1].pCell = NULL;
389 pThisRowInfo->pCellInfo[nX+1].bEmptyCellText = sal_True;
396 // Ausgabe auf Device (static)
398 // wird benutzt fuer:
399 // - Clipboard/Bitmap
400 // - Ole-Object (DocShell::Draw)
401 // - Vorschau bei Vorlagen
403 void ScPrintFunc::DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double /* nPrintFactor */,
404 const Rectangle& rBound, ScViewData* pViewData, sal_Bool bMetaFile )
406 //! nPrintFactor auswerten !!!
408 SCTAB nTab = 0;
409 if (pViewData)
410 nTab = pViewData->GetTabNo();
412 sal_Bool bDoGrid, bNullVal, bFormula;
413 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
414 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
415 if (pStyleSheet)
417 SfxItemSet& rSet = pStyleSheet->GetItemSet();
418 bDoGrid = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_GRID)).GetValue();
419 bNullVal = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_NULLVALS)).GetValue();
420 bFormula = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_FORMULAS)).GetValue();
422 else
424 const ScViewOptions& rOpt = pDoc->GetViewOptions();
425 bDoGrid = rOpt.GetOption(VOPT_GRID);
426 bNullVal = rOpt.GetOption(VOPT_NULLVALS);
427 bFormula = rOpt.GetOption(VOPT_FORMULAS);
430 MapMode aMode = pDev->GetMapMode();
432 Rectangle aRect = rBound;
434 if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top())
435 aRect = Rectangle( Point(), pDev->GetOutputSize() );
437 SCCOL nX1 = 0;
438 SCROW nY1 = 0;
439 SCCOL nX2 = OLE_STD_CELLS_X - 1;
440 SCROW nY2 = OLE_STD_CELLS_Y - 1;
441 if (bMetaFile)
443 ScRange aRange = pDoc->GetRange( nTab, rBound );
444 nX1 = aRange.aStart.Col();
445 nY1 = aRange.aStart.Row();
446 nX2 = aRange.aEnd.Col();
447 nY2 = aRange.aEnd.Row();
449 else if (pViewData)
451 ScSplitPos eWhich = pViewData->GetActivePart();
452 ScHSplitPos eHWhich = WhichH(eWhich);
453 ScVSplitPos eVWhich = WhichV(eWhich);
454 nX1 = pViewData->GetPosX(eHWhich);
455 nY1 = pViewData->GetPosY(eVWhich);
456 nX2 = nX1 + pViewData->VisibleCellsX(eHWhich);
457 if (nX2>nX1) --nX2;
458 nY2 = nY1 + pViewData->VisibleCellsY(eVWhich);
459 if (nY2>nY1) --nY2;
462 if (nX1 > MAXCOL) nX1 = MAXCOL;
463 if (nX2 > MAXCOL) nX2 = MAXCOL;
464 if (nY1 > MAXROW) nY1 = MAXROW;
465 if (nY2 > MAXROW) nY2 = MAXROW;
467 long nDevSizeX = aRect.Right()-aRect.Left()+1;
468 long nDevSizeY = aRect.Bottom()-aRect.Top()+1;
470 Rectangle aLines;
471 ScRange aRange( nX1,nY1,nTab, nX2,nY2,nTab );
473 long nTwipsSizeX = 0;
474 for (SCCOL i=nX1; i<=nX2; i++)
475 nTwipsSizeX += pDoc->GetColWidth( i, nTab );
476 long nTwipsSizeY = (long) pDoc->GetRowHeight( nY1, nY2, nTab );
478 // wenn keine Linien, dann trotzdem Platz fuer den Aussenrahmen (20 Twips = 1pt)
479 // (HasLines initalisiert aLines auf 0,0,0,0)
480 nTwipsSizeX += aLines.Left() + Max( aLines.Right(), 20L );
481 nTwipsSizeY += aLines.Top() + Max( aLines.Bottom(), 20L );
483 double nScaleX = (double) nDevSizeX / nTwipsSizeX;
484 double nScaleY = (double) nDevSizeY / nTwipsSizeY;
486 //! Flag bei FillInfo uebergeben !!!!!
487 ScRange aERange;
488 sal_Bool bEmbed = pDoc->IsEmbedded();
489 if (bEmbed)
491 pDoc->GetEmbedded(aERange);
492 pDoc->ResetEmbedded();
495 // Daten zusammenstellen
497 ScTableInfo aTabInfo;
498 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
499 nScaleX, nScaleY, false, bFormula );
500 lcl_HidePrint( aTabInfo, nX1, nX2 );
502 if (bEmbed)
503 pDoc->SetEmbedded(aERange);
505 long nScrX = aRect.Left();
506 long nScrY = aRect.Top();
508 // Wenn keine Linien, trotzdem Platz fuer Gitterlinien lassen
509 // (werden sonst abgeschnitten)
510 long nAddX = (long)( aLines.Left() * nScaleX );
511 nScrX += ( nAddX ? nAddX : 1 );
512 long nAddY = (long)( aLines.Top() * nScaleY );
513 nScrY += ( nAddY ? nAddY : 1 );
515 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nTab,
516 nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
517 aOutputData.SetMetaFileMode(bMetaFile);
518 aOutputData.SetShowNullValues(bNullVal);
519 aOutputData.SetShowFormulas(bFormula);
521 // #114135#
522 ScDrawLayer* pModel = pDoc->GetDrawLayer();
523 FmFormView* pDrawView = NULL;
525 if( pModel )
527 pDrawView = new FmFormView( pModel, pDev );
528 pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
529 pDrawView->SetPrintPreview( sal_True );
530 aOutputData.SetDrawView( pDrawView );
533 //! SetUseStyleColor ??
535 if ( bMetaFile && pDev->GetOutDevType() == OUTDEV_VIRDEV )
536 aOutputData.SetSnapPixel();
538 Point aLogStart = pDev->PixelToLogic( Point(nScrX,nScrY), MAP_100TH_MM );
539 long nLogStX = aLogStart.X();
540 long nLogStY = aLogStart.Y();
542 //! nZoom fuer GetFont in OutputData ???
544 if (!bMetaFile && pViewData)
545 pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
547 // #i72502#
548 const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
549 aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
551 if (!bMetaFile && pViewData)
552 pDev->SetMapMode(aMode);
554 aOutputData.DrawBackground();
555 aOutputData.DrawShadow();
556 aOutputData.DrawFrame();
557 aOutputData.DrawStrings();
559 if (!bMetaFile && pViewData)
560 pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
562 aOutputData.DrawEdit(!bMetaFile);
564 if (bDoGrid)
566 if (!bMetaFile && pViewData)
567 pDev->SetMapMode(aMode);
569 aOutputData.DrawGrid( sal_True, false ); // keine Seitenumbrueche
571 pDev->SetLineColor( COL_BLACK );
573 Size aOne = pDev->PixelToLogic( Size(1,1) );
574 if (bMetaFile)
575 aOne = Size(1,1); // compatible with DrawGrid
576 long nRight = nScrX + aOutputData.GetScrW() - aOne.Width();
577 long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height();
579 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
581 // extra line at the left edge for left-to-right, right for right-to-left
582 if ( bLayoutRTL )
583 pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) );
584 else
585 pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) );
586 // extra line at the top in both cases
587 pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) );
590 // #i72502#
591 aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
592 aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
593 aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
595 // #114135#
596 delete pDrawView;
600 // Drucken
603 void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet )
605 // nDistance muss vorher unterschiedlich initalisiert sein
607 if ( pHFSet == NULL )
609 rParam.bEnable = false;
610 rParam.pBorder = NULL;
611 rParam.pBack = NULL;
612 rParam.pShadow = NULL;
614 else
616 rParam.bEnable = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_ON)).GetValue();
617 rParam.bDynamic = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_DYNAMIC)).GetValue();
618 rParam.bShared = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_SHARED)).GetValue();
619 rParam.nHeight = ((const SvxSizeItem&) pHFSet->Get(ATTR_PAGE_SIZE)).GetSize().Height();
620 const SvxLRSpaceItem* pHFLR = &(const SvxLRSpaceItem&) pHFSet->Get(ATTR_LRSPACE);
621 long nTmp;
622 nTmp = pHFLR->GetLeft();
623 rParam.nLeft = nTmp < 0 ? 0 : sal_uInt16(nTmp);
624 nTmp = pHFLR->GetRight();
625 rParam.nRight = nTmp < 0 ? 0 : sal_uInt16(nTmp);
626 rParam.pBorder = (const SvxBoxItem*) &pHFSet->Get(ATTR_BORDER);
627 rParam.pBack = (const SvxBrushItem*) &pHFSet->Get(ATTR_BACKGROUND);
628 rParam.pShadow = (const SvxShadowItem*)&pHFSet->Get(ATTR_SHADOW);;
630 // jetzt doch wieder schon im Dialog:
631 // rParam.nHeight += rParam.nDistance; // nicht mehr im Dialog ???
633 if (rParam.pBorder)
634 rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
635 lcl_LineTotal( rParam.pBorder->GetBottom() );
637 rParam.nManHeight = rParam.nHeight;
640 if (!rParam.bEnable)
641 rParam.nHeight = 0;
644 // bNew = TRUE: benutzten Bereich aus dem Dokument suchen
645 // bNew = FALSE: nur ganze Zeilen/Spalten begrenzen
647 sal_Bool ScPrintFunc::AdjustPrintArea( sal_Bool bNew )
649 SCCOL nOldEndCol = nEndCol; // nur wichtig bei !bNew
650 SCROW nOldEndRow = nEndRow;
651 sal_Bool bChangeCol = sal_True; // bei bNew werden beide angepasst
652 sal_Bool bChangeRow = sal_True;
654 sal_Bool bNotes = aTableParam.bNotes;
655 if ( bNew )
657 nStartCol = 0;
658 nStartRow = 0;
659 if (!pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ))
660 return false; // nix
662 else
664 sal_Bool bFound = sal_True;
665 bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL );
666 bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW );
667 sal_Bool bForcedChangeRow = false;
669 // #i53558# Crop entire column of old row limit to real print area with
670 // some fuzzyness.
671 if (!bChangeRow && nStartRow == 0)
673 SCROW nPAEndRow;
674 bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nPAEndRow, bNotes );
675 // Say we don't want to print more than ~1000 empty rows, which are
676 // about 14 pages intentionally left blank..
677 const SCROW nFuzzy = 23*42;
678 if (nPAEndRow + nFuzzy < nEndRow)
680 bForcedChangeRow = sal_True;
681 nEndRow = nPAEndRow;
683 else
684 bFound = sal_True; // user seems to _want_ to print some empty rows
686 // TODO: in case we extend the number of columns we may have to do the
687 // same for horizontal cropping.
689 if ( bChangeCol && bChangeRow )
690 bFound = pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes );
691 else if ( bChangeCol )
692 bFound = pDoc->GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol, bNotes );
693 else if ( bChangeRow )
694 bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes );
696 if (!bFound)
697 return false; // leer
699 if (bForcedChangeRow)
700 bChangeRow = sal_True;
703 pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab,
704 false ); // kein Refresh, incl. Attrs
706 if ( bChangeCol )
708 OutputDevice* pRefDev = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
709 pRefDev->SetMapMode( MAP_PIXEL ); // wichtig fuer GetNeededSize
711 pDoc->ExtendPrintArea( pRefDev,
712 nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow );
713 // nEndCol wird veraendert
716 if ( nEndCol < MAXCOL && pDoc->HasAttrib(
717 nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_RIGHT ) )
718 ++nEndCol;
719 if ( nEndRow < MAXROW && pDoc->HasAttrib(
720 nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_DOWN ) )
721 ++nEndRow;
723 if (!bChangeCol) nEndCol = nOldEndCol;
724 if (!bChangeRow) nEndRow = nOldEndRow;
726 return sal_True;
729 long ScPrintFunc::TextHeight( const EditTextObject* pObject )
731 if (!pObject)
732 return 0;
734 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
736 return (long) pEditEngine->GetTextHeight();
739 // nZoom muss gesetzt sein !!!
740 // und der entsprechende Twip-MapMode eingestellt
742 void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam )
744 OSL_ENSURE( aPageSize.Width(), "UpdateHFHeight ohne aPageSize");
746 if (rParam.bEnable && rParam.bDynamic)
748 // nHeight aus Inhalten berechnen
750 MakeEditEngine();
751 long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin -
752 rParam.nLeft - rParam.nRight ) * 100 / nZoom;
753 if (rParam.pBorder)
754 nPaperWidth -= ( rParam.pBorder->GetDistance(BOX_LINE_LEFT) +
755 rParam.pBorder->GetDistance(BOX_LINE_RIGHT) +
756 lcl_LineTotal(rParam.pBorder->GetLeft()) +
757 lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom;
759 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
760 nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SHADOW_LEFT) +
761 rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT) ) * 100L / nZoom;
763 pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) );
765 long nMaxHeight = 0;
766 if ( rParam.pLeft )
768 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) );
769 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) );
770 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) );
772 if ( rParam.pRight )
774 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) );
775 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) );
776 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) );
779 rParam.nHeight = nMaxHeight + rParam.nDistance;
780 if (rParam.pBorder)
781 rParam.nHeight += rParam.pBorder->GetDistance(BOX_LINE_TOP) +
782 rParam.pBorder->GetDistance(BOX_LINE_BOTTOM) +
783 lcl_LineTotal( rParam.pBorder->GetTop() ) +
784 lcl_LineTotal( rParam.pBorder->GetBottom() );
785 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
786 rParam.nHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
787 rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
789 if (rParam.nHeight < rParam.nManHeight)
790 rParam.nHeight = rParam.nManHeight; // eingestelltes Minimum
794 void ScPrintFunc::InitParam( const ScPrintOptions* pOptions )
796 if (!pParamSet)
797 return;
799 // TabPage "Seite"
800 const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &pParamSet->Get( ATTR_LRSPACE );
801 long nTmp;
802 nTmp = pLRItem->GetLeft();
803 nLeftMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
804 nTmp = pLRItem->GetRight();
805 nRightMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
806 const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &pParamSet->Get( ATTR_ULSPACE );
807 nTopMargin = pULItem->GetUpper();
808 nBottomMargin = pULItem->GetLower();
810 const SvxPageItem* pPageItem = (const SvxPageItem*) &pParamSet->Get( ATTR_PAGE );
811 nPageUsage = pPageItem->GetPageUsage();
812 bLandscape = pPageItem->IsLandscape();
813 aFieldData.eNumType = pPageItem->GetNumType();
815 bCenterHor = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_HORCENTER)).GetValue();
816 bCenterVer = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_VERCENTER)).GetValue();
818 aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
819 if ( !aPageSize.Width() || !aPageSize.Height() )
821 OSL_FAIL("PageSize Null ?!?!?");
822 aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
825 pBorderItem = (const SvxBoxItem*) &pParamSet->Get(ATTR_BORDER);
826 pBackgroundItem = (const SvxBrushItem*) &pParamSet->Get(ATTR_BACKGROUND);
827 pShadowItem = (const SvxShadowItem*) &pParamSet->Get(ATTR_SHADOW);
829 // TabPage "Kopfzeile"
831 aHdr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERLEFT); // Inhalt
832 aHdr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERRIGHT);
834 const SvxSetItem* pHeaderSetItem;
835 const SfxItemSet* pHeaderSet = NULL;
836 if ( pParamSet->GetItemState( ATTR_PAGE_HEADERSET, false,
837 (const SfxPoolItem**)&pHeaderSetItem ) == SFX_ITEM_SET )
839 pHeaderSet = &pHeaderSetItem->GetItemSet();
840 // Kopfzeile hat unteren Abstand
841 aHdr.nDistance = ((const SvxULSpaceItem&) pHeaderSet->Get(ATTR_ULSPACE)).GetLower();
843 lcl_FillHFParam( aHdr, pHeaderSet );
845 // TabPage "Fusszeile"
847 aFtr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERLEFT); // Inhalt
848 aFtr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT);
850 const SvxSetItem* pFooterSetItem;
851 const SfxItemSet* pFooterSet = NULL;
852 if ( pParamSet->GetItemState( ATTR_PAGE_FOOTERSET, false,
853 (const SfxPoolItem**)&pFooterSetItem ) == SFX_ITEM_SET )
855 pFooterSet = &pFooterSetItem->GetItemSet();
856 // Fusszeile hat oberen Abstand
857 aFtr.nDistance = ((const SvxULSpaceItem&) pFooterSet->Get(ATTR_ULSPACE)).GetUpper();
859 lcl_FillHFParam( aFtr, pFooterSet );
861 //------------------------------------------------------
862 // Table-/Area-Params aus einzelnen Items zusammenbauen:
863 //------------------------------------------------------
864 // TabPage "Tabelle"
866 const SfxUInt16Item* pScaleItem = NULL;
867 const ScPageScaleToItem* pScaleToItem = NULL;
868 const SfxUInt16Item* pScaleToPagesItem = NULL;
869 SfxItemState eState;
871 eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, false,
872 (const SfxPoolItem**)&pScaleItem );
873 if ( SFX_ITEM_DEFAULT == eState )
874 pScaleItem = (const SfxUInt16Item*)
875 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE );
877 eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, false,
878 (const SfxPoolItem**)&pScaleToItem );
879 if ( SFX_ITEM_DEFAULT == eState )
880 pScaleToItem = (const ScPageScaleToItem*)
881 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO );
883 eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, false,
884 (const SfxPoolItem**)&pScaleToPagesItem );
885 if ( SFX_ITEM_DEFAULT == eState )
886 pScaleToPagesItem = (const SfxUInt16Item*)
887 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETOPAGES );
889 OSL_ENSURE( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" );
891 aTableParam.bCellContent = sal_True;
892 aTableParam.bNotes = GET_BOOL(pParamSet,ATTR_PAGE_NOTES);
893 aTableParam.bGrid = GET_BOOL(pParamSet,ATTR_PAGE_GRID);
894 aTableParam.bHeaders = GET_BOOL(pParamSet,ATTR_PAGE_HEADERS);
895 aTableParam.bFormulas = GET_BOOL(pParamSet,ATTR_PAGE_FORMULAS);
896 aTableParam.bNullVals = GET_BOOL(pParamSet,ATTR_PAGE_NULLVALS);
897 aTableParam.bCharts = GET_SHOW(pParamSet,ATTR_PAGE_CHARTS);
898 aTableParam.bObjects = GET_SHOW(pParamSet,ATTR_PAGE_OBJECTS);
899 aTableParam.bDrawings = GET_SHOW(pParamSet,ATTR_PAGE_DRAWINGS);
900 aTableParam.bTopDown = GET_BOOL(pParamSet,ATTR_PAGE_TOPDOWN);
901 aTableParam.bLeftRight = !aTableParam.bLeftRight;
902 aTableParam.nFirstPageNo = GET_USHORT(pParamSet,ATTR_PAGE_FIRSTPAGENO);
903 if (!aTableParam.nFirstPageNo)
904 aTableParam.nFirstPageNo = (sal_uInt16) nPageStart; // von vorheriger Tabelle
906 if ( pScaleItem && pScaleToItem && pScaleToPagesItem )
908 sal_uInt16 nScaleAll = pScaleItem->GetValue();
909 sal_uInt16 nScaleToPages = pScaleToPagesItem->GetValue();
911 aTableParam.bScaleNone = (nScaleAll == 100);
912 aTableParam.bScaleAll = (nScaleAll > 0 );
913 aTableParam.bScaleTo = pScaleToItem->IsValid();
914 aTableParam.bScalePageNum = (nScaleToPages > 0 );
915 aTableParam.nScaleAll = nScaleAll;
916 aTableParam.nScaleWidth = pScaleToItem->GetWidth();
917 aTableParam.nScaleHeight = pScaleToItem->GetHeight();
918 aTableParam.nScalePageNum = nScaleToPages;
920 else
922 aTableParam.bScaleNone = sal_True;
923 aTableParam.bScaleAll = false;
924 aTableParam.bScaleTo = false;
925 aTableParam.bScalePageNum = false;
926 aTableParam.nScaleAll = 0;
927 aTableParam.nScaleWidth = 0;
928 aTableParam.nScaleHeight = 0;
929 aTableParam.nScalePageNum = 0;
932 // skip empty pages only if options with that flag are passed
933 aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty();
934 if ( pPageData )
935 aTableParam.bSkipEmpty = false;
936 // Wenn pPageData gesetzt ist, interessieren fuer die Umbruch-Vorschau
937 // nur die Umbrueche, leere Seiten werden nicht speziell behandelt
939 //------------------------------------------------------
940 // TabPage "Bereiche":
941 //------------------------------------------------------
943 //! alle PrintAreas der Tabelle durchgehen !!!
944 const ScRange* pPrintArea = pDoc->GetPrintRange( nPrintTab, 0 );
945 const ScRange* pRepeatCol = pDoc->GetRepeatColRange( nPrintTab );
946 const ScRange* pRepeatRow = pDoc->GetRepeatRowRange( nPrintTab );
948 // ATTR_PAGE_PRINTTABLES wird ignoriert
950 if ( pUserArea ) // UserArea (Selektion) hat Vorrang
952 bPrintCurrentTable =
953 aAreaParam.bPrintArea = sal_True; // Selektion
954 aAreaParam.aPrintArea = *pUserArea;
956 // Die Tabellen-Abfrage ist schon in DocShell::Print, hier immer
957 aAreaParam.aPrintArea.aStart.SetTab(nPrintTab);
958 aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab);
960 else if ( pDoc->HasPrintRange() )
962 if ( pPrintArea ) // mindestens eine gesetzt ?
964 bPrintCurrentTable =
965 aAreaParam.bPrintArea = sal_True;
966 aAreaParam.aPrintArea = *pPrintArea;
968 bMultiArea = ( pDoc->GetPrintRangeCount(nPrintTab) > 1 );
970 else
972 // do not print hidden sheets with "Print entire sheet" flag
973 bPrintCurrentTable = pDoc->IsPrintEntireSheet( nPrintTab ) && pDoc->IsVisible( nPrintTab );
974 aAreaParam.bPrintArea = !bPrintCurrentTable; // otherwise the table is always counted
977 else
979 // don't print hidden tables if there's no print range defined there
980 if ( pDoc->IsVisible( nPrintTab ) )
982 aAreaParam.bPrintArea = false;
983 bPrintCurrentTable = sal_True;
985 else
987 aAreaParam.bPrintArea = sal_True; // otherwise the table is always counted
988 bPrintCurrentTable = false;
992 if ( pRepeatCol )
994 aAreaParam.bRepeatCol = sal_True;
995 aAreaParam.aRepeatCol = *pRepeatCol;
996 nRepeatStartCol = pRepeatCol->aStart.Col();
997 nRepeatEndCol = pRepeatCol->aEnd .Col();
999 else
1001 aAreaParam.bRepeatCol = false;
1002 nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE;
1005 if ( pRepeatRow )
1007 aAreaParam.bRepeatRow = sal_True;
1008 aAreaParam.aRepeatRow = *pRepeatRow;
1009 nRepeatStartRow = pRepeatRow->aStart.Row();
1010 nRepeatEndRow = pRepeatRow->aEnd .Row();
1012 else
1014 aAreaParam.bRepeatRow = false;
1015 nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE;
1019 // Seiten aufteilen
1022 if (!bState)
1024 nTabPages = CountPages(); // berechnet auch Zoom
1025 nTotalPages = nTabPages;
1026 nTotalPages += CountNotePages();
1028 else
1030 CalcPages(); // nur Umbrueche suchen
1031 CountNotePages(); // Notizen zaehlen, auch wenn Seitenzahl schon bekannt
1034 if (nDocPages)
1035 aFieldData.nTotalPages = nDocPages;
1036 else
1037 aFieldData.nTotalPages = nTotalPages;
1039 SetDateTime( Date(), Time() );
1041 aFieldData.aTitle = pDocShell->GetTitle();
1042 const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
1043 aFieldData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
1044 if ( aFieldData.aLongDocName.Len() )
1045 aFieldData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
1046 else
1047 aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle;
1049 // Druckereinstellungen (Orientation, Paper) jetzt erst bei 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 Time& rTime )
1073 aFieldData.aDate = rDate;
1074 aFieldData.aTime = rTime;
1077 void lcl_DrawGraphic( const Graphic &rGraphic, OutputDevice *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 void lcl_DrawGraphic( const SvxBrushItem &rBrush, OutputDevice *pOut, OutputDevice* pRefDev,
1094 const Rectangle &rOrg, const Rectangle &rOut )
1096 Size aGrfSize(0,0);
1097 const Graphic *pGraphic = rBrush.GetGraphic();
1098 SvxGraphicPosition ePos;
1099 if ( pGraphic && pGraphic->IsSupportedGraphic() )
1101 const MapMode aMapMM( MAP_100TH_MM );
1102 if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1103 aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM );
1104 else
1105 aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1106 pGraphic->GetPrefMapMode(), aMapMM );
1107 ePos = rBrush.GetGraphicPos();
1109 else
1110 ePos = GPOS_NONE;
1112 Point aPos;
1113 Size aDrawSize = aGrfSize;
1115 bool bDraw = true;
1116 switch ( ePos )
1118 case GPOS_LT: aPos = rOrg.TopLeft();
1119 break;
1120 case GPOS_MT: aPos.Y() = rOrg.Top();
1121 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1122 break;
1123 case GPOS_RT: aPos.Y() = rOrg.Top();
1124 aPos.X() = rOrg.Right() - aGrfSize.Width();
1125 break;
1127 case GPOS_LM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1128 aPos.X() = rOrg.Left();
1129 break;
1130 case GPOS_MM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1131 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1132 break;
1133 case GPOS_RM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1134 aPos.X() = rOrg.Right() - aGrfSize.Width();
1135 break;
1137 case GPOS_LB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1138 aPos.X() = rOrg.Left();
1139 break;
1140 case GPOS_MB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1141 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1142 break;
1143 case GPOS_RB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1144 aPos.X() = rOrg.Right() - aGrfSize.Width();
1145 break;
1147 case GPOS_AREA:
1148 aPos = rOrg.TopLeft();
1149 aDrawSize = rOrg.GetSize();
1150 break;
1151 case GPOS_TILED:
1153 // use GraphicObject::DrawTiled instead of an own loop
1154 // (pixel rounding is handled correctly, and a very small bitmap
1155 // is duplicated into a bigger one for better performance)
1157 GraphicObject aObject( *pGraphic );
1159 if( pOut->GetPDFWriter() &&
1160 (aObject.GetType() == GRAPHIC_BITMAP || aObject.GetType() == GRAPHIC_DEFAULT) )
1162 // For PDF export, every draw
1163 // operation for bitmaps takes a noticeable
1164 // amount of place (~50 characters). Thus,
1165 // optimize between tile bitmap size and
1166 // number of drawing operations here.
1168 // A_out
1169 // n_chars = k1 * ---------- + k2 * A_bitmap
1170 // A_bitmap
1172 // minimum n_chars is obtained for (derive for
1173 // A_bitmap, set to 0, take positive
1174 // solution):
1175 // k1
1176 // A_bitmap = Sqrt( ---- A_out )
1177 // k2
1179 // where k1 is the number of chars per draw
1180 // operation, and k2 is the number of chars
1181 // per bitmap pixel. This is approximately 50
1182 // and 7 for current PDF writer, respectively.
1184 const double k1( 50 );
1185 const double k2( 7 );
1186 const Size aSize( rOrg.GetSize() );
1187 const double Abitmap( k1/k2 * aSize.Width()*aSize.Height() );
1189 aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0),
1190 NULL, GRFMGR_DRAW_STANDARD,
1191 ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
1193 else
1195 aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0) );
1198 bDraw = false;
1200 break;
1202 case GPOS_NONE:
1203 bDraw = false;
1204 break;
1206 default: OSL_ENSURE( !pOut, "new Graphic position?" );
1208 Rectangle aGrf( aPos,aDrawSize );
1209 if ( bDraw && aGrf.IsOver( rOut ) )
1211 lcl_DrawGraphic( *pGraphic, pOut, aGrf, rOut );
1215 // Rahmen wird nach innen gezeichnet
1217 void ScPrintFunc::DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH,
1218 const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground,
1219 const SvxShadowItem* pShadow )
1221 //! direkte Ausgabe aus SvxBoxItem !!!
1223 if (pBorderData)
1224 if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() &&
1225 !pBorderData->GetRight() )
1226 pBorderData = NULL;
1228 if (!pBorderData && !pBackground && !pShadow)
1229 return; // nichts zu tun
1231 long nLeft = 0;
1232 long nRight = 0;
1233 long nTop = 0;
1234 long nBottom = 0;
1236 // aFrameRect - aussen um die Umrandung, ohne Schatten
1237 if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1239 nLeft += (long) ( pShadow->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
1240 nRight += (long) ( pShadow->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
1241 nTop += (long) ( pShadow->CalcShadowSpace(SHADOW_TOP) * nScaleY );
1242 nBottom += (long) ( pShadow->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
1244 Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop),
1245 Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) );
1247 // Mitte der Umrandung, um Linien ueber OutputData zu zeichnen:
1248 if (pBorderData)
1250 nLeft += (long) ( lcl_LineTotal(pBorderData->GetLeft()) * nScaleX / 2 );
1251 nRight += (long) ( lcl_LineTotal(pBorderData->GetRight()) * nScaleX / 2 );
1252 nTop += (long) ( lcl_LineTotal(pBorderData->GetTop()) * nScaleY / 2 );
1253 nBottom += (long) ( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 );
1255 long nEffHeight = nScrH - nTop - nBottom;
1256 long nEffWidth = nScrW - nLeft - nRight;
1257 if (nEffHeight<=0 || nEffWidth<=0)
1258 return; // leer
1260 if ( pBackground )
1262 if (pBackground->GetGraphicPos() != GPOS_NONE)
1264 OutputDevice* pRefDev;
1265 if ( bIsRender )
1266 pRefDev = pDev; // don't use printer for PDF
1267 else
1268 pRefDev = pDoc->GetPrinter(); // use printer also for preview
1270 lcl_DrawGraphic( *pBackground, pDev, pRefDev, aFrameRect, aFrameRect );
1272 else
1274 pDev->SetFillColor(pBackground->GetColor());
1275 pDev->SetLineColor();
1276 pDev->DrawRect(aFrameRect);
1280 if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1282 pDev->SetFillColor(pShadow->GetColor());
1283 pDev->SetLineColor();
1284 long nShadowX = (long) ( pShadow->GetWidth() * nScaleX );
1285 long nShadowY = (long) ( pShadow->GetWidth() * nScaleY );
1286 switch (pShadow->GetLocation())
1288 case SVX_SHADOW_TOPLEFT:
1289 pDev->DrawRect( Rectangle(
1290 aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1291 aFrameRect.Right()-nShadowX, aFrameRect.Top() ) );
1292 pDev->DrawRect( Rectangle(
1293 aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1294 aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) );
1295 break;
1296 case SVX_SHADOW_TOPRIGHT:
1297 pDev->DrawRect( Rectangle(
1298 aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY,
1299 aFrameRect.Right()+nShadowX, aFrameRect.Top() ) );
1300 pDev->DrawRect( Rectangle(
1301 aFrameRect.Right(), aFrameRect.Top()-nShadowY,
1302 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) );
1303 break;
1304 case SVX_SHADOW_BOTTOMLEFT:
1305 pDev->DrawRect( Rectangle(
1306 aFrameRect.Left()-nShadowX, aFrameRect.Bottom(),
1307 aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) );
1308 pDev->DrawRect( Rectangle(
1309 aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY,
1310 aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) );
1311 break;
1312 case SVX_SHADOW_BOTTOMRIGHT:
1313 pDev->DrawRect( Rectangle(
1314 aFrameRect.Left()+nShadowX, aFrameRect.Bottom(),
1315 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1316 pDev->DrawRect( Rectangle(
1317 aFrameRect.Right(), aFrameRect.Top()+nShadowY,
1318 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1319 break;
1320 default:
1322 // added to avoid warnings
1327 if (pBorderData)
1329 ScDocument* pBorderDoc = new ScDocument( SCDOCMODE_UNDO );
1330 pBorderDoc->InitUndo( pDoc, 0,0, sal_True,sal_True );
1331 if (pBorderData)
1332 pBorderDoc->ApplyAttr( 0,0,0, *pBorderData );
1334 ScTableInfo aTabInfo;
1335 pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0,
1336 nScaleX, nScaleY, false, false );
1337 OSL_ENSURE(aTabInfo.mnArrCount,"nArrCount == 0");
1339 aTabInfo.mpRowInfo[1].nHeight = (sal_uInt16) nEffHeight;
1340 aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth =
1341 aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = (sal_uInt16) nEffWidth;
1343 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc, 0,
1344 nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY );
1345 aOutputData.SetUseStyleColor( bUseStyleColor );
1347 if (pBorderData)
1348 aOutputData.DrawFrame();
1350 delete pBorderDoc;
1354 void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY )
1356 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1357 long nLayoutSign = bLayoutRTL ? -1 : 1;
1359 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1360 long nOneX = aOnePixel.Width();
1361 long nOneY = aOnePixel.Height();
1362 SCCOL nCol;
1364 long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1365 long nEndY = nScrY + nHeight - nOneY;
1367 long nPosX = nScrX;
1368 if ( bLayoutRTL )
1370 for (nCol=nX1; nCol<=nX2; nCol++)
1371 nPosX += (long)( pDoc->GetColWidth( nCol, nPrintTab ) * nScaleX );
1373 else
1374 nPosX -= nOneX;
1375 long nPosY = nScrY - nOneY;
1376 String aText;
1378 for (nCol=nX1; nCol<=nX2; nCol++)
1380 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1381 if (nDocW)
1383 long nWidth = (long) (nDocW * nScaleX);
1384 long nEndX = nPosX + nWidth * nLayoutSign;
1386 pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1388 aText = ::ScColToAlpha( nCol);
1389 long nTextWidth = pDev->GetTextWidth(aText);
1390 long nTextHeight = pDev->GetTextHeight();
1391 long nAddX = ( nWidth - nTextWidth ) / 2;
1392 long nAddY = ( nHeight - nTextHeight ) / 2;
1393 long nTextPosX = nPosX+nAddX;
1394 if ( bLayoutRTL )
1395 nTextPosX -= nWidth;
1396 pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText );
1398 nPosX = nEndX;
1403 void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY )
1405 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1406 long nOneX = aOnePixel.Width();
1407 long nOneY = aOnePixel.Height();
1409 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1411 long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1412 long nEndX = nScrX + nWidth;
1413 long nPosX = nScrX;
1414 if ( !bLayoutRTL )
1416 nEndX -= nOneX;
1417 nPosX -= nOneX;
1419 long nPosY = nScrY - nOneY;
1420 String aText;
1422 for (SCROW nRow=nY1; nRow<=nY2; nRow++)
1424 sal_uInt16 nDocH = pDoc->GetRowHeight( nRow, nPrintTab );
1425 if (nDocH)
1427 long nHeight = (long) (nDocH * nScaleY);
1428 long nEndY = nPosY + nHeight;
1430 pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1432 aText = String::CreateFromInt32( nRow+1 );
1433 long nTextWidth = pDev->GetTextWidth(aText);
1434 long nTextHeight = pDev->GetTextHeight();
1435 long nAddX = ( nWidth - nTextWidth ) / 2;
1436 long nAddY = ( nHeight - nTextHeight ) / 2;
1437 pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText );
1439 nPosY = nEndY;
1444 void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY,
1445 sal_Bool bRepCol, ScPreviewLocationData& rLocationData )
1447 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1448 long nOneX = aOnePixel.Width();
1449 long nOneY = aOnePixel.Height();
1451 long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1452 long nEndY = nScrY + nHeight - nOneY;
1454 long nPosX = nScrX - nOneX;
1455 for (SCCOL nCol=nX1; nCol<=nX2; nCol++)
1457 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1458 if (nDocW)
1459 nPosX += (long) (nDocW * nScaleX);
1461 Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY );
1462 rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol );
1465 void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY,
1466 sal_Bool bRepRow, ScPreviewLocationData& rLocationData )
1468 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1469 long nOneX = aOnePixel.Width();
1470 long nOneY = aOnePixel.Height();
1472 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1474 long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1475 long nEndX = nScrX + nWidth;
1476 if ( !bLayoutRTL )
1477 nEndX -= nOneX;
1479 long nPosY = nScrY - nOneY;
1480 nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1481 Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY );
1482 rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow );
1485 void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1486 long nScrX, long nScrY, sal_Bool bRepCol, sal_Bool bRepRow,
1487 ScPreviewLocationData& rLocationData )
1489 // get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer)
1491 Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1492 long nLogStX = aLogPos.X();
1493 long nLogStY = aLogPos.Y();
1495 SCCOL nCol;
1496 Point aTwipOffset;
1497 for (nCol=0; nCol<nX1; nCol++)
1498 aTwipOffset.X() -= pDoc->GetColWidth( nCol, nPrintTab );
1499 aTwipOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nPrintTab );
1501 Point aMMOffset( aTwipOffset );
1502 aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS);
1503 aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS);
1504 aMMOffset += Point( nLogStX, nLogStY );
1505 MapMode aDrawMapMode( MAP_100TH_MM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() );
1507 // get pixel rectangle
1509 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1510 long nOneX = aOnePixel.Width();
1511 long nOneY = aOnePixel.Height();
1513 long nPosX = nScrX - nOneX;
1514 for (nCol=nX1; nCol<=nX2; nCol++)
1516 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1517 if (nDocW)
1518 nPosX += (long) (nDocW * nScaleX);
1521 long nPosY = nScrY - nOneY;
1522 nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1523 Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY );
1524 rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ),
1525 bRepCol, bRepRow, aDrawMapMode );
1528 void ScPrintFunc::PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1529 long nScrX, long nScrY,
1530 sal_Bool bShLeft, sal_Bool bShTop, sal_Bool bShRight, sal_Bool bShBottom )
1532 // #i47547# nothing to do if the end of the print area is before the end of
1533 // the repeat columns/rows (don't use negative size for ScOutputData)
1534 if ( nX2 < nX1 || nY2 < nY1 )
1535 return;
1537 //! Flag bei FillInfo uebergeben !!!!!
1538 ScRange aERange;
1539 sal_Bool bEmbed = pDoc->IsEmbedded();
1540 if (bEmbed)
1542 pDoc->GetEmbedded(aERange);
1543 pDoc->ResetEmbedded();
1546 Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1547 long nLogStX = aPos.X();
1548 long nLogStY = aPos.Y();
1550 // Daten zusammenstellen
1552 ScTableInfo aTabInfo;
1553 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab,
1554 nScaleX, nScaleY, sal_True, aTableParam.bFormulas );
1555 lcl_HidePrint( aTabInfo, nX1, nX2 );
1557 if (bEmbed)
1558 pDoc->SetEmbedded(aERange);
1560 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nPrintTab,
1561 nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
1563 // #114135#
1564 aOutputData.SetDrawView( pDrawView );
1566 // test if all paint parts are hidden, then a paint is not necessary at all
1567 const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
1568 const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart()
1569 && pDrawView->getHideDraw() && pDrawView->getHideFormControl() );
1571 if(!bHideAllDrawingLayer)
1573 pDev->SetMapMode(aLogicMode);
1574 // hier kein Clipping setzen (Mapmode wird verschoben)
1576 // #i72502#
1577 aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
1580 pDev->SetMapMode(aOffsetMode);
1582 aOutputData.SetShowFormulas( aTableParam.bFormulas );
1583 aOutputData.SetShowNullValues( aTableParam.bNullVals );
1584 aOutputData.SetUseStyleColor( bUseStyleColor );
1586 Color aGridColor( COL_BLACK );
1587 if ( bUseStyleColor )
1588 aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
1589 aOutputData.SetGridColor( aGridColor );
1591 if ( !pPrinter )
1593 OutputDevice* pRefDev = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
1594 Fraction aPrintFrac( nZoom, 100 ); // ohne nManualZoom
1595 // MapMode, wie er beim Drucken herauskommen wuerde:
1596 pRefDev->SetMapMode( MapMode( MAP_100TH_MM, Point(), aPrintFrac, aPrintFrac ) );
1598 // when rendering (PDF), don't use printer as ref device, but printer's MapMode
1599 // has to be set anyway, as charts still use it (#106409#)
1600 if ( !bIsRender )
1601 aOutputData.SetRefDevice( pRefDev );
1604 if( aTableParam.bCellContent )
1605 aOutputData.DrawBackground();
1607 pDev->SetClipRegion( Rectangle( aPos, Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) );
1608 pDev->SetClipRegion();
1610 if( aTableParam.bCellContent )
1612 aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom );
1613 aOutputData.DrawFrame();
1614 aOutputData.DrawStrings();
1615 aOutputData.DrawEdit(false);
1618 if (aTableParam.bGrid)
1619 aOutputData.DrawGrid( sal_True, false ); // keine Seitenumbrueche
1621 aOutputData.AddPDFNotes(); // has no effect if not rendering PDF with notes enabled
1623 // test if all paint parts are hidden, then a paint is not necessary at all
1624 if(!bHideAllDrawingLayer)
1626 // #i72502#
1627 aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
1630 // #i72502#
1631 aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
1632 aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
1635 sal_Bool ScPrintFunc::IsMirror( long nPageNo ) // Raender spiegeln ?
1637 SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1638 return ( eUsage == SVX_PAGE_MIRROR && (nPageNo & 1) );
1641 sal_Bool ScPrintFunc::IsLeft( long nPageNo ) // linke Fussnoten ?
1643 SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1644 sal_Bool bLeft;
1645 if (eUsage == SVX_PAGE_LEFT)
1646 bLeft = sal_True;
1647 else if (eUsage == SVX_PAGE_RIGHT)
1648 bLeft = false;
1649 else
1650 bLeft = (nPageNo & 1) != 0;
1651 return bLeft;
1654 void ScPrintFunc::MakeTableString()
1656 rtl::OUString aTmp;
1657 pDoc->GetName(nPrintTab, aTmp);
1658 aFieldData.aTabName = aTmp;
1661 void ScPrintFunc::MakeEditEngine()
1663 if (!pEditEngine)
1665 // can't use document's edit engine pool here,
1666 // because pool must have twips as default metric
1667 pEditEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), sal_True );
1669 pEditEngine->EnableUndo(false);
1670 pEditEngine->SetRefDevice( pDev );
1671 pEditEngine->SetWordDelimiters(
1672 ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
1673 pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
1674 pEditEngine->EnableAutoColor( bUseStyleColor );
1676 // Default-Set fuer Ausrichtung
1677 pEditDefaults = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
1679 const ScPatternAttr& rPattern = (const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN);
1680 rPattern.FillEditItemSet( pEditDefaults );
1681 // FillEditItemSet adjusts font height to 1/100th mm,
1682 // but for header/footer twips is needed, as in the PatternAttr:
1683 pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
1684 pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
1685 pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
1686 // dont use font color, because background color is not used
1687 //! there's no way to set the background for note pages
1688 pEditDefaults->ClearItem( EE_CHAR_COLOR );
1689 if (ScGlobal::IsSystemRTL())
1690 pEditDefaults->Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
1693 pEditEngine->SetData( aFieldData ); // Seitennummer etc. setzen
1696 // nStartY = logic
1697 void ScPrintFunc::PrintHF( long nPageNo, sal_Bool bHeader, long nStartY,
1698 sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1700 const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr;
1702 pDev->SetMapMode( aTwipMode ); // Kopf-/Fusszeilen in Twips
1704 sal_Bool bLeft = IsLeft(nPageNo) && !rParam.bShared;
1705 const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight;
1707 long nLineStartX = aPageRect.Left() + rParam.nLeft;
1708 long nLineEndX = aPageRect.Right() - rParam.nRight;
1709 long nLineWidth = nLineEndX - nLineStartX + 1;
1711 // Edit-Engine
1713 Point aStart( nLineStartX, nStartY );
1714 Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1715 if ( rParam.pBorder )
1717 long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(BOX_LINE_LEFT);
1718 long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(BOX_LINE_TOP);
1719 aStart.X() += nLeft;
1720 aStart.Y() += nTop;
1721 aPaperSize.Width() -= nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(BOX_LINE_RIGHT);
1722 aPaperSize.Height() -= nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
1725 if ( rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE )
1727 long nLeft = rParam.pShadow->CalcShadowSpace(SHADOW_LEFT);
1728 long nTop = rParam.pShadow->CalcShadowSpace(SHADOW_TOP);
1729 aStart.X() += nLeft;
1730 aStart.Y() += nTop;
1731 aPaperSize.Width() -= nLeft + rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT);
1732 aPaperSize.Height() -= nTop + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
1735 aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo;
1736 MakeEditEngine();
1738 pEditEngine->SetPaperSize(aPaperSize);
1739 const EditTextObject* pObject;
1741 // Rahmen / Hintergrund
1743 Point aBorderStart( nLineStartX, nStartY );
1744 Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1745 if ( rParam.bDynamic )
1747 // hier nochmal anpassen, wegen geraden/ungeraden Kopf/Fusszeilen
1748 // und evtl. anderen Umbruechen durch Variablen (Seitennummer etc.)
1750 long nMaxHeight = 0;
1751 nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) );
1752 nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) );
1753 nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) );
1754 if (rParam.pBorder)
1755 nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
1756 lcl_LineTotal( rParam.pBorder->GetBottom() ) +
1757 rParam.pBorder->GetDistance(BOX_LINE_TOP) +
1758 rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
1759 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
1760 nMaxHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
1761 rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
1763 if (nMaxHeight < rParam.nManHeight-rParam.nDistance)
1764 nMaxHeight = rParam.nManHeight-rParam.nDistance; // eingestelltes Minimum
1766 aBorderSize.Height() = nMaxHeight;
1769 if ( bDoPrint )
1771 double nOldScaleX = nScaleX;
1772 double nOldScaleY = nScaleY;
1773 nScaleX = nScaleY = 1.0; // direkt in Twips ausgeben
1774 DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(),
1775 rParam.pBorder, rParam.pBack, rParam.pShadow );
1776 nScaleX = nOldScaleX;
1777 nScaleY = nOldScaleY;
1779 // Clipping fuer Text
1781 pDev->SetClipRegion( Rectangle( aStart, aPaperSize ) );
1783 // links
1785 pObject = pHFItem->GetLeftArea();
1786 if (pObject)
1788 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1789 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1790 Point aDraw = aStart;
1791 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1792 if (nDif > 0)
1793 aDraw.Y() += nDif / 2;
1794 pEditEngine->Draw( pDev, aDraw, 0 );
1797 // Mitte
1799 pObject = pHFItem->GetCenterArea();
1800 if (pObject)
1802 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
1803 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1804 Point aDraw = aStart;
1805 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1806 if (nDif > 0)
1807 aDraw.Y() += nDif / 2;
1808 pEditEngine->Draw( pDev, aDraw, 0 );
1811 // rechts
1813 pObject = pHFItem->GetRightArea();
1814 if (pObject)
1816 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
1817 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1818 Point aDraw = aStart;
1819 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1820 if (nDif > 0)
1821 aDraw.Y() += nDif / 2;
1822 pEditEngine->Draw( pDev, aDraw, 0 );
1825 pDev->SetClipRegion();
1828 if ( pLocationData )
1830 Rectangle aHeaderRect( aBorderStart, aBorderSize );
1831 pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft );
1835 long ScPrintFunc::DoNotes( long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1837 if (bDoPrint)
1838 pDev->SetMapMode(aTwipMode);
1840 MakeEditEngine();
1841 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1842 pEditEngine->SetDefaults( *pEditDefaults );
1844 Font aMarkFont;
1845 ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
1846 ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).GetFont( aMarkFont, eColorMode );
1847 pDev->SetFont( aMarkFont );
1848 long nMarkLen = pDev->GetTextWidth(
1849 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:")));
1850 // ohne Space, weil's eh selten so weit kommt
1852 Size aDataSize = aPageRect.GetSize();
1853 if ( nMarkLen > aDataSize.Width() / 2 ) // alles viel zu klein?
1854 nMarkLen = aDataSize.Width() / 2; // Seite bruederlich aufteilen
1855 aDataSize.Width() -= nMarkLen;
1857 pEditEngine->SetPaperSize( aDataSize );
1858 long nPosX = aPageRect.Left() + nMarkLen;
1859 long nPosY = aPageRect.Top();
1861 long nCount = 0;
1862 long nSize = aNotePosList.size();
1863 sal_Bool bOk;
1866 bOk = false;
1867 if ( nNoteStart + nCount < nSize)
1869 ScAddress &rPos = aNotePosList[ nNoteStart + nCount ];
1871 ScBaseCell* pCell = pDoc->GetCell( rPos);
1872 if( const ScPostIt* pNote = pCell->GetNote() )
1874 if(const EditTextObject *pEditText = pNote->GetEditTextObject())
1875 pEditEngine->SetText(*pEditText);
1876 long nTextHeight = pEditEngine->GetTextHeight();
1877 if ( nPosY + nTextHeight < aPageRect.Bottom() )
1879 if (bDoPrint)
1881 pEditEngine->Draw( pDev, Point( nPosX, nPosY ), 0 );
1883 String aMarkStr;
1884 rPos.Format( aMarkStr, SCA_VALID, pDoc, pDoc->GetAddressConvention() );
1885 aMarkStr += ':';
1887 // Zellposition auch per EditEngine, damit die Position stimmt
1888 pEditEngine->SetText(aMarkStr);
1889 pEditEngine->Draw( pDev, Point( aPageRect.Left(), nPosY ), 0 );
1892 if ( pLocationData )
1894 Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) );
1895 pLocationData->AddNoteText( aTextRect, rPos );
1896 Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) );
1897 pLocationData->AddNoteMark( aMarkRect, rPos );
1900 nPosY += nTextHeight;
1901 nPosY += 200; // Abstand
1902 ++nCount;
1903 bOk = sal_True;
1908 while (bOk);
1910 return nCount;
1913 long ScPrintFunc::PrintNotes( long nPageNo, long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1915 if ( nNoteStart >= (long) aNotePosList.size() || !aTableParam.bNotes )
1916 return 0;
1918 if ( bDoPrint && bClearWin )
1920 //! mit PrintPage zusammenfassen !!!
1922 Color aBackgroundColor( COL_WHITE );
1923 if ( bUseStyleColor )
1924 aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1926 pDev->SetMapMode(aOffsetMode);
1927 pDev->SetLineColor();
1928 pDev->SetFillColor(aBackgroundColor);
1929 pDev->DrawRect(Rectangle(Point(),
1930 Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
1931 (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
1935 // aPageRect auf linke / rechte Seiten anpassen
1937 Rectangle aTempRect = Rectangle( Point(), aPageSize );
1938 if (IsMirror(nPageNo))
1940 aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
1941 aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
1943 else
1945 aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
1946 aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
1949 if ( pPrinter && bDoPrint )
1951 OSL_FAIL( "StartPage does not exist anymore" );
1954 if ( bDoPrint || pLocationData )
1956 // Kopf- und Fusszeilen
1958 if (aHdr.bEnable)
1960 long nHeaderY = aPageRect.Top()-aHdr.nHeight;
1961 PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
1963 if (aFtr.bEnable)
1965 long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
1966 PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
1970 long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData );
1972 if ( pPrinter && bDoPrint )
1974 OSL_FAIL( "EndPage does not exist anymore" );
1977 return nCount;
1980 void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1981 sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1983 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1984 long nLayoutSign = bLayoutRTL ? -1 : 1;
1986 // nPageNo is the page number within all sheets of one "start page" setting
1988 if ( bClearWin && bDoPrint )
1990 // muss genau zum Zeichnen des Rahmens in preview.cxx passen !!!
1992 Color aBackgroundColor( COL_WHITE );
1993 if ( bUseStyleColor )
1994 aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1996 pDev->SetMapMode(aOffsetMode);
1997 pDev->SetLineColor();
1998 pDev->SetFillColor(aBackgroundColor);
1999 pDev->DrawRect(Rectangle(Point(),
2000 Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
2001 (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
2005 // aPageRect auf linke / rechte Seiten anpassen
2007 Rectangle aTempRect = Rectangle( Point(), aPageSize );
2008 if (IsMirror(nPageNo))
2010 aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
2011 aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
2013 else
2015 aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
2016 aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
2019 if ( aAreaParam.bRepeatCol )
2020 if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol )
2021 nX1 = nRepeatEndCol + 1;
2022 sal_Bool bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol);
2023 if ( aAreaParam.bRepeatRow )
2024 if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow )
2025 nY1 = nRepeatEndRow + 1;
2026 sal_Bool bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow);
2028 // use new object hide flags in SdrPaintView
2029 if(pDrawView)
2031 pDrawView->setHideOle(!aTableParam.bObjects);
2032 pDrawView->setHideChart(!aTableParam.bCharts);
2033 pDrawView->setHideDraw(!aTableParam.bDrawings);
2034 pDrawView->setHideFormControl(!aTableParam.bDrawings);
2037 if ( pPrinter && bDoPrint )
2039 OSL_FAIL( "StartPage does not exist anymore" );
2042 // Kopf- und Fusszeilen (ohne Zentrierung)
2044 if (aHdr.bEnable)
2046 long nHeaderY = aPageRect.Top()-aHdr.nHeight;
2047 PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
2049 if (aFtr.bEnable)
2051 long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
2052 PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
2055 // Position ( Raender / zentrieren )
2057 long nLeftSpace = aPageRect.Left(); // Document-Twips
2058 long nTopSpace = aPageRect.Top();
2059 if ( bCenterHor || bLayoutRTL )
2061 long nDataWidth = 0;
2062 SCCOL i;
2063 for (i=nX1; i<=nX2; i++)
2064 nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2065 if (bDoRepCol)
2066 for (i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2067 nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2068 if (aTableParam.bHeaders)
2069 nDataWidth += (long) PRINT_HEADER_WIDTH;
2070 if (pBorderItem)
2071 nDataWidth += pBorderItem->GetDistance(BOX_LINE_LEFT) +
2072 pBorderItem->GetDistance(BOX_LINE_RIGHT); //! Line width?
2073 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2074 nDataWidth += pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
2075 pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
2076 if ( bCenterHor )
2078 nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2; // LTR or RTL
2079 if (pBorderItem)
2080 nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft());
2082 else if ( bLayoutRTL )
2083 nLeftSpace += aPageRect.GetWidth() - nDataWidth; // align to the right edge of the page
2085 if ( bCenterVer )
2087 long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab);
2088 if (bDoRepRow)
2089 nDataHeight += pDoc->GetRowHeight( nRepeatStartRow,
2090 nRepeatEndRow, nPrintTab);
2091 if (aTableParam.bHeaders)
2092 nDataHeight += (long) PRINT_HEADER_HEIGHT;
2093 if (pBorderItem)
2094 nDataHeight += pBorderItem->GetDistance(BOX_LINE_TOP) +
2095 pBorderItem->GetDistance(BOX_LINE_BOTTOM); //! Line width?
2096 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2097 nDataHeight += pShadowItem->CalcShadowSpace(SHADOW_TOP) +
2098 pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
2099 nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2;
2100 if (pBorderItem)
2101 nTopSpace -= lcl_LineTotal(pBorderItem->GetTop());
2104 // calculate sizes of the elements for partitioning
2105 // (header, repeat, data)
2107 long nHeaderWidth = 0;
2108 long nHeaderHeight = 0;
2109 long nRepeatWidth = 0;
2110 long nRepeatHeight = 0;
2111 long nContentWidth = 0; // scaled - not the same as nDataWidth above
2112 long nContentHeight = 0;
2113 if (aTableParam.bHeaders)
2115 nHeaderWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
2116 nHeaderHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
2118 if (bDoRepCol)
2119 for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2120 nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2121 if (bDoRepRow)
2122 nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow,
2123 nRepeatEndRow, nPrintTab, nScaleY);
2124 for (SCCOL i=nX1; i<=nX2; i++)
2125 nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2126 nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab,
2127 nScaleY);
2129 // partition the page
2131 long nStartX = ((long) ( nLeftSpace * nScaleX ));
2132 long nStartY = ((long) ( nTopSpace * nScaleY ));
2133 long nInnerStartX = nStartX;
2134 long nInnerStartY = nStartY;
2135 if (pBorderItem)
2137 nInnerStartX += (long) ( ( lcl_LineTotal(pBorderItem->GetLeft()) +
2138 pBorderItem->GetDistance(BOX_LINE_LEFT) ) * nScaleX );
2139 nInnerStartY += (long) ( ( lcl_LineTotal(pBorderItem->GetTop()) +
2140 pBorderItem->GetDistance(BOX_LINE_TOP) ) * nScaleY );
2142 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2144 nInnerStartX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
2145 nInnerStartY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_TOP) * nScaleY );
2148 if ( bLayoutRTL )
2150 // arrange elements starting from the right edge
2151 nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth;
2153 // make rounding easier so the elements are really next to each other in preview
2154 Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode );
2155 long nOffsetOneX = aOffsetOnePixel.Width();
2156 nInnerStartX += nOffsetOneX / 2;
2159 long nFrameStartX = nInnerStartX;
2160 long nFrameStartY = nInnerStartY;
2162 long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign; // widths/heights are 0 if not used
2163 long nRepStartY = nInnerStartY + nHeaderHeight;
2164 long nDataX = nRepStartX + nRepeatWidth * nLayoutSign;
2165 long nDataY = nRepStartY + nRepeatHeight;
2166 long nEndX = nDataX + nContentWidth * nLayoutSign;
2167 long nEndY = nDataY + nContentHeight;
2168 long nFrameEndX = nEndX;
2169 long nFrameEndY = nEndY;
2171 if ( bLayoutRTL )
2173 // each element's start position is its left edge
2174 //! subtract one pixel less?
2175 nInnerStartX -= nHeaderWidth; // used for header
2176 nRepStartX -= nRepeatWidth;
2177 nDataX -= nContentWidth;
2179 // continue right of the main elements again
2180 nEndX += nHeaderWidth + nRepeatWidth + nContentWidth;
2183 // Seiten-Rahmen / Hintergrund
2185 //! nEndX/Y anpassen
2187 long nBorderEndX = nEndX;
2188 long nBorderEndY = nEndY;
2189 if (pBorderItem)
2191 nBorderEndX += (long) ( ( lcl_LineTotal(pBorderItem->GetRight()) +
2192 pBorderItem->GetDistance(BOX_LINE_RIGHT) ) * nScaleX );
2193 nBorderEndY += (long) ( ( lcl_LineTotal(pBorderItem->GetBottom()) +
2194 pBorderItem->GetDistance(BOX_LINE_BOTTOM) ) * nScaleY );
2196 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2198 nBorderEndX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
2199 nBorderEndY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
2202 if ( bDoPrint )
2204 pDev->SetMapMode( aOffsetMode );
2205 DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY,
2206 pBorderItem, pBackgroundItem, pShadowItem );
2208 pDev->SetMapMode( aTwipMode );
2211 pDev->SetMapMode( aOffsetMode );
2213 // Wiederholungszeilen/Spalten ausgeben
2215 if (bDoRepCol && bDoRepRow)
2217 if ( bDoPrint )
2218 PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2219 nRepStartX,nRepStartY, sal_True,sal_True,false,false );
2220 if ( pLocationData )
2221 LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2222 nRepStartX,nRepStartY, sal_True,sal_True, *pLocationData );
2224 if (bDoRepCol)
2226 if ( bDoPrint )
2227 PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY,
2228 sal_True,!bDoRepRow,false,sal_True );
2229 if ( pLocationData )
2230 LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, sal_True,false, *pLocationData );
2232 if (bDoRepRow)
2234 if ( bDoPrint )
2235 PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY,
2236 !bDoRepCol,sal_True,sal_True,false );
2237 if ( pLocationData )
2238 LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, false,sal_True, *pLocationData );
2241 // Daten ausgeben
2243 if ( bDoPrint )
2244 PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow,sal_True,sal_True );
2245 if ( pLocationData )
2246 LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, false,false, *pLocationData );
2248 // Spalten-/Zeilenkoepfe ausgeben
2249 // nach den Daten (ueber evtl. weitergezeichneten Schatten)
2251 Color aGridColor( COL_BLACK );
2252 if ( bUseStyleColor )
2253 aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2255 if (aTableParam.bHeaders)
2257 if ( bDoPrint )
2259 pDev->SetLineColor( aGridColor );
2260 pDev->SetFillColor();
2261 pDev->SetMapMode(aOffsetMode);
2264 ScPatternAttr aPattern( pDoc->GetPool() );
2265 Font aFont;
2266 ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
2267 aPattern.GetFont( aFont, eColorMode, pDev );
2268 pDev->SetFont( aFont );
2270 if (bDoRepCol)
2272 if ( bDoPrint )
2273 PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY );
2274 if ( pLocationData )
2275 LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, sal_True, *pLocationData );
2277 if ( bDoPrint )
2278 PrintColHdr( nX1,nX2, nDataX,nInnerStartY );
2279 if ( pLocationData )
2280 LocateColHdr( nX1,nX2, nDataX,nInnerStartY, false, *pLocationData );
2281 if (bDoRepRow)
2283 if ( bDoPrint )
2284 PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY );
2285 if ( pLocationData )
2286 LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, sal_True, *pLocationData );
2288 if ( bDoPrint )
2289 PrintRowHdr( nY1,nY2, nInnerStartX,nDataY );
2290 if ( pLocationData )
2291 LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, false, *pLocationData );
2294 // einfacher Rahmen
2296 if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) )
2298 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
2299 long nOneX = aOnePixel.Width();
2300 long nOneY = aOnePixel.Height();
2302 long nLeftX = nFrameStartX;
2303 long nTopY = nFrameStartY - nOneY;
2304 long nRightX = nFrameEndX;
2305 long nBottomY = nFrameEndY - nOneY;
2306 if ( !bLayoutRTL )
2308 nLeftX -= nOneX;
2309 nRightX -= nOneX;
2311 pDev->SetMapMode(aOffsetMode);
2312 pDev->SetLineColor( aGridColor );
2313 pDev->SetFillColor();
2314 pDev->DrawRect( Rectangle( nLeftX, nTopY, nRightX, nBottomY ) );
2315 // nEndX/Y ohne Rahmen-Anpassung
2318 if ( pPrinter && bDoPrint )
2320 OSL_FAIL( "EndPage does not exist anymore" );
2323 aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab );
2324 bSourceRangeValid = sal_True;
2327 void ScPrintFunc::SetOffset( const Point& rOfs )
2329 aSrcOffset = rOfs;
2332 void ScPrintFunc::SetManualZoom( sal_uInt16 nNewZoom )
2334 nManualZoom = nNewZoom;
2337 void ScPrintFunc::SetClearFlag( sal_Bool bFlag )
2339 bClearWin = bFlag;
2342 void ScPrintFunc::SetUseStyleColor( sal_Bool bFlag )
2344 bUseStyleColor = bFlag;
2345 if (pEditEngine)
2346 pEditEngine->EnableAutoColor( bUseStyleColor );
2349 void ScPrintFunc::SetRenderFlag( sal_Bool bFlag )
2351 bIsRender = bFlag; // set when using XRenderable (PDF)
2354 void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects()
2356 aTableParam.bCellContent = false;
2357 aTableParam.bNotes = false;
2358 aTableParam.bGrid = false;
2359 aTableParam.bHeaders = false;
2360 aTableParam.bFormulas = false;;
2361 aTableParam.bNullVals = false;;
2362 aTableParam.bNullVals = false;;
2366 // UpdatePages wird nur von aussen gerufen, um die Umbrueche fuer die Anzeige
2367 // richtig zu setzen - immer ohne UserArea
2370 sal_Bool ScPrintFunc::UpdatePages()
2372 if (!pParamSet)
2373 return false;
2375 // Zoom
2377 nZoom = 100;
2378 if (aTableParam.bScalePageNum || aTableParam.bScaleTo)
2379 nZoom = ZOOM_MIN; // stimmt fuer Umbrueche
2380 else if (aTableParam.bScaleAll)
2382 nZoom = aTableParam.nScaleAll;
2383 if ( nZoom <= ZOOM_MIN )
2384 nZoom = ZOOM_MIN;
2387 rtl::OUString aName = pDoc->GetPageStyle( nPrintTab );
2388 SCTAB nTabCount = pDoc->GetTableCount();
2389 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
2390 if ( nTab==nPrintTab || pDoc->GetPageStyle(nTab)==aName )
2392 // Wiederholungszeilen / Spalten
2393 pDoc->SetRepeatArea( nTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2395 // Umbrueche setzen
2396 ResetBreaks(nTab);
2397 pDocShell->PostPaint(0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID);
2400 return sal_True;
2403 long ScPrintFunc::CountPages() // setzt auch nPagesX, nPagesY
2405 sal_Bool bAreaOk = false;
2407 if (pDoc->HasTable( nPrintTab ))
2409 if (aAreaParam.bPrintArea) // Druckbereich angegeben?
2411 if ( bPrintCurrentTable )
2413 ScRange& rRange = aAreaParam.aPrintArea;
2415 // hier kein Vergleich der Tabellen mehr, die Area gilt immer fuer diese Tabelle
2416 // wenn hier verglichen werden soll, muss die Tabelle der Druckbereiche beim
2417 // Einfuegen von Tabellen etc. angepasst werden !
2419 nStartCol = rRange.aStart.Col();
2420 nStartRow = rRange.aStart.Row();
2421 nEndCol = rRange.aEnd .Col();
2422 nEndRow = rRange.aEnd .Row();
2423 bAreaOk = AdjustPrintArea(false); // begrenzen
2425 else
2426 bAreaOk = false;
2428 else // aus Dokument suchen
2429 bAreaOk = AdjustPrintArea(sal_True);
2432 if (bAreaOk)
2434 long nPages = 0;
2435 size_t nY;
2436 if (bMultiArea)
2438 sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
2439 for (sal_uInt16 i=0; i<nRCount; i++)
2441 CalcZoom(i);
2442 if ( aTableParam.bSkipEmpty )
2443 for (nY=0; nY<nPagesY; nY++)
2444 nPages += pPageRows[nY].CountVisible();
2445 else
2446 nPages += ((long) nPagesX) * nPagesY;
2447 if ( pPageData )
2448 FillPageData();
2451 else
2453 CalcZoom(RANGENO_NORANGE); // Zoom berechnen
2454 if ( aTableParam.bSkipEmpty )
2455 for (nY=0; nY<nPagesY; nY++)
2456 nPages += pPageRows[nY].CountVisible();
2457 else
2458 nPages += ((long) nPagesX) * nPagesY;
2459 if ( pPageData )
2460 FillPageData();
2462 return nPages;
2464 else
2466 nPagesX = nPagesY = nTotalY = 0;
2467 return 0;
2471 long ScPrintFunc::CountNotePages()
2473 if ( !aTableParam.bNotes || !bPrintCurrentTable )
2474 return 0;
2476 long nCount=0;
2477 SCCOL nCol;
2478 SCROW nRow;
2480 sal_Bool bError = false;
2481 if (!aAreaParam.bPrintArea)
2482 bError = !AdjustPrintArea(sal_True); // komplett aus Dok suchen
2484 sal_uInt16 nRepeats = 1; // wie oft durchgehen ?
2485 if (bMultiArea)
2486 nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2487 if (bError)
2488 nRepeats = 0;
2490 for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2492 sal_Bool bDoThis = sal_True;
2493 if (bMultiArea) // alle Areas durchgehen
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 ScHorizontalCellIterator aIter( pDoc, nPrintTab, nStartCol,nStartRow, nEndCol,nEndRow );
2509 ScBaseCell* pCell = aIter.GetNext( nCol, nRow );
2510 while (pCell)
2512 if (pCell->HasNote())
2514 aNotePosList.push_back( ScAddress( nCol,nRow,nPrintTab ) );
2515 ++nCount;
2518 pCell = aIter.GetNext( nCol, nRow );
2523 long nPages = 0;
2524 long nNoteNr = 0;
2525 long nNoteAdd;
2528 nNoteAdd = PrintNotes( nPages, nNoteNr, false, NULL );
2529 if (nNoteAdd)
2531 nNoteNr += nNoteAdd;
2532 ++nPages;
2535 while (nNoteAdd);
2537 return nPages;
2540 void ScPrintFunc::InitModes() // aus nZoom etc. die MapModes setzen
2542 aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom );
2544 long nEffZoom = nZoom * (long) nManualZoom;
2545 nScaleX = nScaleY = HMM_PER_TWIPS; // Ausgabe in 1/100 mm
2547 Fraction aZoomFract( nEffZoom,10000 );
2548 Fraction aHorFract = aZoomFract;
2550 if ( !pPrinter && !bIsRender ) // adjust scale for preview
2552 double nFact = pDocShell->GetOutputFactor();
2553 aHorFract = Fraction( (long)( nEffZoom / nFact ), 10000 );
2556 aLogicMode = MapMode( MAP_100TH_MM, Point(), aHorFract, aZoomFract );
2558 Point aLogicOfs( -aOffset.X(), -aOffset.Y() );
2559 aOffsetMode = MapMode( MAP_100TH_MM, aLogicOfs, aHorFract, aZoomFract );
2561 Point aTwipsOfs( (long) ( -aOffset.X() / nScaleX + 0.5 ), (long) ( -aOffset.Y() / nScaleY + 0.5 ) );
2562 aTwipMode = MapMode( MAP_TWIP, aTwipsOfs, aHorFract, aZoomFract );
2565 //--------------------------------------------------------------------
2567 void ScPrintFunc::ApplyPrintSettings()
2569 if ( pPrinter )
2572 // Printer zum Drucken umstellen
2575 Size aEnumSize = aPageSize;
2578 pPrinter->SetOrientation( bLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT );
2579 if ( bLandscape )
2581 // landscape is always interpreted as a rotation by 90 degrees !
2582 // this leads to non WYSIWIG but at least it prints!
2583 // #i21775#
2584 long nTemp = aEnumSize.Width();
2585 aEnumSize.Width() = aEnumSize.Height();
2586 aEnumSize.Height() = nTemp;
2588 Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, sal_True );
2589 sal_uInt16 nPaperBin = ((const SvxPaperBinItem&)pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue();
2591 pPrinter->SetPaper( ePaper );
2592 if ( PAPER_USER == ePaper )
2594 MapMode aPrinterMode = pPrinter->GetMapMode();
2595 MapMode aLocalMode( MAP_TWIP );
2596 pPrinter->SetMapMode( aLocalMode );
2597 pPrinter->SetPaperSizeUser( aEnumSize );
2598 pPrinter->SetMapMode( aPrinterMode );
2601 pPrinter->SetPaperBin( nPaperBin );
2605 //--------------------------------------------------------------------
2606 // rPageRanges = range for all tables
2607 // nStartPage = rPageRanges starts at nStartPage
2608 // nDisplayStart = continious number for displaying the page number
2610 long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges,
2611 long nStartPage, long nDisplayStart, bool bDoPrint,
2612 SfxProgress* pProgress, ScPreviewLocationData* pLocationData )
2614 OSL_ENSURE(pDev,"Device == NULL");
2615 if (!pParamSet)
2616 return 0;
2618 if ( pPrinter && bDoPrint )
2619 ApplyPrintSettings();
2621 //--------------------------------------------------------------------
2623 InitModes();
2624 if ( pLocationData )
2626 pLocationData->SetCellMapMode( aOffsetMode );
2627 pLocationData->SetPrintTab( nPrintTab );
2630 MakeTableString();
2632 if ( pProgress )
2633 pProgress->SetText( String( ScResId( SCSTR_STAT_PRINT ) ) );
2635 //--------------------------------------------------------------------
2637 long nPageNo = 0;
2638 long nPrinted = 0;
2639 long nEndPage = rPageRanges.GetTotalRange().Max();
2641 sal_uInt16 nRepeats = 1;
2642 if (bMultiArea)
2643 nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2644 for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2646 if (bMultiArea) // replace area
2648 CalcZoom(nStep); // also sets nStartCol etc. new
2649 InitModes();
2652 SCCOL nX1;
2653 SCROW nY1;
2654 SCCOL nX2;
2655 SCROW nY2;
2656 size_t nCountX;
2657 size_t nCountY;
2659 if (aTableParam.bTopDown) // top-bottom
2661 nX1 = nStartCol;
2662 for (nCountX=0; nCountX<nPagesX; nCountX++)
2664 nX2 = pPageEndX[nCountX];
2665 for (nCountY=0; nCountY<nPagesY; nCountY++)
2667 nY1 = pPageRows[nCountY].GetStartRow();
2668 nY2 = pPageRows[nCountY].GetEndRow();
2669 if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
2671 if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2673 PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2674 bDoPrint, pLocationData );
2676 if ( pProgress )
2678 pProgress->SetState( nPageNo+nStartPage+1, nEndPage );
2679 pProgress->Reschedule(); //does the user want to continue
2681 ++nPrinted;
2683 ++nPageNo;
2686 nX1 = nX2 + 1;
2689 else // left to right
2691 for (nCountY=0; nCountY<nPagesY; nCountY++)
2693 nY1 = pPageRows[nCountY].GetStartRow();
2694 nY2 = pPageRows[nCountY].GetEndRow();
2695 nX1 = nStartCol;
2696 for (nCountX=0; nCountX<nPagesX; nCountX++)
2698 nX2 = pPageEndX[nCountX];
2699 if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
2701 if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2703 PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2704 bDoPrint, pLocationData );
2706 if ( pProgress )
2708 pProgress->SetState( nPageNo+nStartPage+1, nEndPage );
2709 pProgress->Reschedule(); //does the user want to continue
2712 ++nPrinted;
2714 ++nPageNo;
2716 nX1 = nX2 + 1;
2722 aFieldData.aTabName = ScGlobal::GetRscString( STR_NOTES );
2724 long nNoteNr = 0;
2725 long nNoteAdd;
2728 if ( nPageNo+nStartPage <= nEndPage )
2730 sal_Bool bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 );
2731 nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected,
2732 ( bPageSelected ? pLocationData : NULL ) );
2733 if ( nNoteAdd )
2735 nNoteNr += nNoteAdd;
2736 if ( pProgress && bPageSelected )
2738 pProgress->SetState( nPageNo+nStartPage+1, nEndPage );
2739 pProgress->Reschedule(); //does the user want to continue
2741 if (bPageSelected)
2743 ++nPrinted;
2744 bSourceRangeValid = false; // last page was no cell range
2746 ++nPageNo;
2749 else
2750 nNoteAdd = 0;
2752 while (nNoteAdd);
2754 if ( bMultiArea )
2755 ResetBreaks(nPrintTab); //breaks correct for displaying
2757 return nPrinted;
2760 void ScPrintFunc::CalcZoom( sal_uInt16 nRangeNo ) // calculate zoom
2762 sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
2763 const ScRange* pThisRange = NULL;
2764 if ( nRangeNo != RANGENO_NORANGE || nRangeNo < nRCount )
2765 pThisRange = pDoc->GetPrintRange( nPrintTab, nRangeNo );
2766 if ( pThisRange )
2768 nStartCol = pThisRange->aStart.Col();
2769 nStartRow = pThisRange->aStart.Row();
2770 nEndCol = pThisRange->aEnd .Col();
2771 nEndRow = pThisRange->aEnd .Row();
2774 if (!AdjustPrintArea(false)) // empty
2776 nZoom = 100;
2777 nPagesX = nPagesY = nTotalY = 0;
2778 return;
2781 pDoc->SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2783 if (aTableParam.bScalePageNum)
2785 nZoom = 100;
2786 sal_uInt16 nPagesToFit = aTableParam.nScalePageNum;
2788 sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2789 while (true)
2791 if (nZoom <= ZOOM_MIN)
2792 break;
2794 CalcPages();
2795 bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit);
2797 if (bFitsPage)
2799 if (nZoom == 100)
2800 // If it fits at 100 %, it's good enough for me.
2801 break;
2803 nLastFitZoom = nZoom;
2804 nZoom = (nLastNonFitZoom + nZoom) / 2;
2806 if (nLastFitZoom == nZoom)
2807 // It converged. Use this zoom level.
2808 break;
2810 else
2812 if (nZoom - nLastFitZoom <= 1)
2814 nZoom = nLastFitZoom;
2815 CalcPages();
2816 break;
2819 nLastNonFitZoom = nZoom;
2820 nZoom = (nLastFitZoom + nZoom) / 2;
2824 else if (aTableParam.bScaleTo)
2826 nZoom = 100;
2827 sal_uInt16 nW = aTableParam.nScaleWidth;
2828 sal_uInt16 nH = aTableParam.nScaleHeight;
2830 sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2831 while (true)
2833 if (nZoom <= ZOOM_MIN)
2834 break;
2836 CalcPages();
2837 bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH)));
2839 if (bFitsPage)
2841 if (nZoom == 100)
2842 // If it fits at 100 %, it's good enough for me.
2843 break;
2845 nLastFitZoom = nZoom;
2846 nZoom = (nLastNonFitZoom + nZoom) / 2;
2848 if (nLastFitZoom == nZoom)
2849 // It converged. Use this zoom level.
2850 break;
2852 else
2854 if (nZoom - nLastFitZoom <= 1)
2856 nZoom = nLastFitZoom;
2857 CalcPages();
2858 break;
2861 nLastNonFitZoom = nZoom;
2862 nZoom = (nLastFitZoom + nZoom) / 2;
2866 else if (aTableParam.bScaleAll)
2868 nZoom = aTableParam.nScaleAll;
2869 if ( nZoom <= ZOOM_MIN )
2870 nZoom = ZOOM_MIN;
2871 CalcPages();
2873 else
2875 OSL_ENSURE( aTableParam.bScaleNone, "kein Scale-Flag gesetzt" );
2876 nZoom = 100;
2877 CalcPages();
2881 Size ScPrintFunc::GetDocPageSize()
2883 // Hoehe Kopf-/Fusszeile anpassen
2885 InitModes(); // aTwipMode aus nZoom initialisieren
2886 pDev->SetMapMode( aTwipMode ); // Kopf-/Fusszeilen in Twips
2887 UpdateHFHeight( aHdr );
2888 UpdateHFHeight( aFtr );
2890 // Seitengroesse in Document-Twips
2891 // Berechnung Left / Right auch in PrintPage
2893 aPageRect = Rectangle( Point(), aPageSize );
2894 aPageRect.Left() = ( aPageRect.Left() + nLeftMargin ) * 100 / nZoom;
2895 aPageRect.Right() = ( aPageRect.Right() - nRightMargin ) * 100 / nZoom;
2896 aPageRect.Top() = ( aPageRect.Top() + nTopMargin ) * 100 / nZoom + aHdr.nHeight;
2897 aPageRect.Bottom() = ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight;
2899 Size aDocPageSize = aPageRect.GetSize();
2900 if (aTableParam.bHeaders)
2902 aDocPageSize.Width() -= (long) PRINT_HEADER_WIDTH;
2903 aDocPageSize.Height() -= (long) PRINT_HEADER_HEIGHT;
2905 if (pBorderItem)
2907 aDocPageSize.Width() -= lcl_LineTotal(pBorderItem->GetLeft()) +
2908 lcl_LineTotal(pBorderItem->GetRight()) +
2909 pBorderItem->GetDistance(BOX_LINE_LEFT) +
2910 pBorderItem->GetDistance(BOX_LINE_RIGHT);
2911 aDocPageSize.Height() -= lcl_LineTotal(pBorderItem->GetTop()) +
2912 lcl_LineTotal(pBorderItem->GetBottom()) +
2913 pBorderItem->GetDistance(BOX_LINE_TOP) +
2914 pBorderItem->GetDistance(BOX_LINE_BOTTOM);
2916 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2918 aDocPageSize.Width() -= pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
2919 pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
2920 aDocPageSize.Height() -= pShadowItem->CalcShadowSpace(SHADOW_TOP) +
2921 pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
2923 return aDocPageSize;
2926 void ScPrintFunc::ResetBreaks( SCTAB nTab ) // Breaks fuer Anzeige richtig setzen
2928 pDoc->SetPageSize( nTab, GetDocPageSize() );
2929 pDoc->UpdatePageBreaks( nTab, NULL );
2932 void lcl_SetHidden( ScDocument* pDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry,
2933 SCCOL nStartCol, const SCCOL* pPageEndX )
2935 size_t nPagesX = rPageRowEntry.GetPagesX();
2936 SCROW nStartRow = rPageRowEntry.GetStartRow();
2937 SCROW nEndRow = rPageRowEntry.GetEndRow();
2939 sal_Bool bLeftIsEmpty = false;
2940 ScRange aTempRange;
2941 Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 );
2943 for (size_t i=0; i<nPagesX; i++)
2945 SCCOL nEndCol = pPageEndX[i];
2946 if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow,
2947 bLeftIsEmpty, &aTempRange, &aTempRect ) )
2949 rPageRowEntry.SetHidden(i);
2950 bLeftIsEmpty = sal_True;
2952 else
2953 bLeftIsEmpty = false;
2955 nStartCol = nEndCol+1;
2959 void ScPrintFunc::CalcPages() // berechnet aPageRect und Seiten aus nZoom
2961 if (!pPageEndX) pPageEndX = new SCCOL[MAXCOL+1];
2962 if (!pPageEndY) pPageEndY = new SCROW[MAXROW+1];
2963 if (!pPageRows) pPageRows = new ScPageRowEntry[MAXROW+1]; //! vorher zaehlen !!!!
2965 pDoc->SetPageSize( nPrintTab, GetDocPageSize() );
2966 if (aAreaParam.bPrintArea)
2968 ScRange aRange( nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab );
2969 pDoc->UpdatePageBreaks( nPrintTab, &aRange );
2971 else
2972 pDoc->UpdatePageBreaks( nPrintTab, NULL ); // sonst wird das Ende markiert
2975 // Seiteneinteilung nach Umbruechen in Col/RowFlags
2976 // Von mehreren Umbruechen in einem ausgeblendeten Bereich zaehlt nur einer.
2979 nPagesX = 0;
2980 nPagesY = 0;
2981 nTotalY = 0;
2983 bool bVisCol = false;
2984 for (SCCOL i=nStartCol; i<=nEndCol; i++)
2986 bool bHidden = pDoc->ColHidden(i, nPrintTab);
2987 bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE);
2988 if ( i>nStartCol && bVisCol && bPageBreak )
2990 pPageEndX[nPagesX] = i-1;
2991 ++nPagesX;
2992 bVisCol = false;
2994 if (!bHidden)
2995 bVisCol = true;
2997 if (bVisCol) // auch am Ende keine leeren Seiten
2999 pPageEndX[nPagesX] = nEndCol;
3000 ++nPagesX;
3003 bool bVisRow = false;
3004 SCROW nPageStartRow = nStartRow;
3005 SCROW nLastVisibleRow = -1;
3007 ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab));
3008 SCROW nNextPageBreak = pRowBreakIter->first();
3009 while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow)
3010 // Skip until the page break position is at the start row or greater.
3011 nNextPageBreak = pRowBreakIter->next();
3013 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
3015 bool bPageBreak = (nNextPageBreak == nRow);
3016 if (bPageBreak)
3017 nNextPageBreak = pRowBreakIter->next();
3019 if (nRow > nStartRow && bVisRow && bPageBreak )
3021 pPageEndY[nTotalY] = nRow-1;
3022 ++nTotalY;
3024 if ( !aTableParam.bSkipEmpty ||
3025 !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) )
3027 pPageRows[nPagesY].SetStartRow( nPageStartRow );
3028 pPageRows[nPagesY].SetEndRow( nRow-1 );
3029 pPageRows[nPagesY].SetPagesX( nPagesX );
3030 if (aTableParam.bSkipEmpty)
3031 lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX );
3032 ++nPagesY;
3035 nPageStartRow = nRow;
3036 bVisRow = false;
3039 if (nRow <= nLastVisibleRow)
3041 // This row is still visible. Don't bother calling RowHidden() to
3042 // find out, for speed optimization.
3043 bVisRow = true;
3044 continue;
3047 SCROW nLastRow = -1;
3048 if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow))
3050 bVisRow = true;
3051 nLastVisibleRow = nLastRow;
3053 else
3054 // skip all hidden rows.
3055 nRow = nLastRow;
3058 if (bVisRow)
3060 pPageEndY[nTotalY] = nEndRow;
3061 ++nTotalY;
3063 if ( !aTableParam.bSkipEmpty ||
3064 !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) )
3066 pPageRows[nPagesY].SetStartRow( nPageStartRow );
3067 pPageRows[nPagesY].SetEndRow( nEndRow );
3068 pPageRows[nPagesY].SetPagesX( nPagesX );
3069 if (aTableParam.bSkipEmpty)
3070 lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX );
3071 ++nPagesY;
3076 //------------------------------------------------------------------------
3077 // class ScJobSetup
3078 //------------------------------------------------------------------------
3080 ScJobSetup::ScJobSetup( SfxPrinter* pPrinter )
3082 eOrientation = pPrinter->GetOrientation();
3083 nPaperBin = pPrinter->GetPaperBin();
3084 ePaper = pPrinter->GetPaper();
3086 if ( PAPER_USER == ePaper )
3088 aUserSize = pPrinter->GetPaperSize();
3089 aUserMapMode = pPrinter->GetMapMode();
3097 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */