bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / ui / view / printfun.cxx
blob9ac82304976be07f8a82de2e484d04860a78b42e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "scitems.hxx"
21 #include <editeng/eeitem.hxx>
23 #include "printfun.hxx"
25 #include <svx/svxids.hrc>
26 #include <editeng/adjustitem.hxx>
27 #include <editeng/boxitem.hxx>
28 #include <editeng/brushitem.hxx>
29 #include <svtools/colorcfg.hxx>
30 #include <editeng/editstat.hxx> // EE_CNTRL_RTFSTYLESHEETS
31 #include <svx/fmview.hxx>
32 #include <editeng/frmdiritem.hxx>
33 #include <editeng/lrspitem.hxx>
34 #include <editeng/paperinf.hxx>
35 #include <editeng/pbinitem.hxx>
36 #include <editeng/shaditem.hxx>
37 #include <editeng/sizeitem.hxx>
38 #include <svx/svdpagv.hxx>
39 #include <editeng/ulspitem.hxx>
40 #include <sfx2/app.hxx>
41 #include <sfx2/printer.hxx>
42 #include <tools/multisel.hxx>
43 #include <sfx2/docfile.hxx>
44 #include <tools/urlobj.hxx>
45 #include <svx/xoutbmp.hxx>
47 #include "editutil.hxx"
48 #include "docsh.hxx"
49 #include "output.hxx"
50 #include "viewdata.hxx"
51 #include "viewopti.hxx"
52 #include "stlpool.hxx"
53 #include "pagepar.hxx"
54 #include "attrib.hxx"
55 #include "patattr.hxx"
56 #include "docpool.hxx"
57 #include "dociter.hxx"
58 #include "formulacell.hxx"
59 #include "drawutil.hxx"
60 #include "globstr.hrc"
61 #include "scresid.hxx"
62 #include "sc.hrc"
63 #include "pagedata.hxx"
64 #include "printopt.hxx"
65 #include "prevloc.hxx"
66 #include "scmod.hxx"
67 #include "drwlayer.hxx"
68 #include "fillinfo.hxx"
69 #include "postit.hxx"
71 #include <vcl/lineinfo.hxx>
73 #include <boost/scoped_ptr.hpp>
74 #include <com/sun/star/document/XDocumentProperties.hpp>
76 #define ZOOM_MIN 10
78 #define GET_BOOL(set,which) ((const SfxBoolItem&)(set)->Get((which))).GetValue()
79 #define GET_USHORT(set,which) ((const SfxUInt16Item&)(set)->Get((which))).GetValue()
80 #define GET_SHOW(set,which) ( VOBJ_MODE_SHOW == ScVObjMode( ((const ScViewObjectModeItem&)(set)->Get((which))).GetValue()) )
82 //------------------------------------------------------------------------
84 ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r)
86 nStartRow = r.nStartRow;
87 nEndRow = r.nEndRow;
88 nPagesX = r.nPagesX;
89 if (r.pHidden && nPagesX)
91 pHidden = new sal_Bool[nPagesX];
92 memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
94 else
95 pHidden = NULL;
98 const ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r)
100 delete[] pHidden;
102 nStartRow = r.nStartRow;
103 nEndRow = r.nEndRow;
104 nPagesX = r.nPagesX;
105 if (r.pHidden && nPagesX)
107 pHidden = new sal_Bool[nPagesX];
108 memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
110 else
111 pHidden = NULL;
113 return *this;
116 void ScPageRowEntry::SetPagesX(size_t nNew)
118 if (pHidden)
120 OSL_FAIL("SetPagesX nicht nach SetHidden");
121 delete[] pHidden;
122 pHidden = NULL;
124 nPagesX = nNew;
127 void ScPageRowEntry::SetHidden(size_t nX)
129 if ( nX < nPagesX )
131 if ( nX+1 == nPagesX ) // last page?
132 --nPagesX;
133 else
135 if (!pHidden)
137 pHidden = new sal_Bool[nPagesX];
138 memset( pHidden, false, nPagesX * sizeof(sal_Bool) );
140 pHidden[nX] = sal_True;
145 sal_Bool ScPageRowEntry::IsHidden(size_t nX) const
147 return nX>=nPagesX || ( pHidden && pHidden[nX] ); //! inline?
150 size_t ScPageRowEntry::CountVisible() const
152 if ( pHidden )
154 size_t nVis = 0;
155 for (size_t i=0; i<nPagesX; i++)
156 if (!pHidden[i])
157 ++nVis;
158 return nVis;
160 else
161 return nPagesX;
164 //------------------------------------------------------------------------
166 static long lcl_LineTotal(const ::editeng::SvxBorderLine* pLine)
168 return pLine ? ( pLine->GetOutWidth() + pLine->GetInWidth() + pLine->GetDistance() ) : 0;
171 void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
173 pDocShell->UpdatePendingRowHeights( nPrintTab );
174 pDoc = pDocShell->GetDocument();
176 SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // use the printer, even for preview
177 if (pDocPrinter)
178 aOldPrinterMode = pDocPrinter->GetMapMode();
180 // unified MapMode for all calls (e.g. Repaint!!!)
181 // else, EditEngine outputs different text heights
182 pDev->SetMapMode(MAP_PIXEL);
184 pPageEndX = NULL;
185 pPageEndY = NULL;
186 pPageRows = NULL;
187 pBorderItem = NULL;
188 pBackgroundItem = NULL;
189 pShadowItem = NULL;
191 pEditEngine = NULL;
192 pEditDefaults = NULL;
194 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
195 SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
196 pDoc->GetPageStyle( nPrintTab ),
197 SFX_STYLE_FAMILY_PAGE );
198 if (pStyleSheet)
199 pParamSet = &pStyleSheet->GetItemSet();
200 else
202 OSL_FAIL("Seitenvorlage nicht gefunden" );
203 pParamSet = NULL;
206 if (!bState)
207 nZoom = 100;
208 nManualZoom = 100;
209 bClearWin = false;
210 bUseStyleColor = false;
211 bIsRender = false;
213 InitParam(pOptions);
215 pPageData = NULL; // wird nur zur Initialisierung gebraucht
218 ScPrintFunc::ScPrintFunc( ScDocShell* pShell, SfxPrinter* pNewPrinter, SCTAB nTab,
219 long nPage, long nDocP, const ScRange* pArea,
220 const ScPrintOptions* pOptions,
221 ScPageBreakData* pData )
222 : pDocShell ( pShell ),
223 pPrinter ( pNewPrinter ),
224 pDrawView ( NULL ),
225 nPrintTab ( nTab ),
226 nPageStart ( nPage ),
227 nDocPages ( nDocP ),
228 pUserArea ( pArea ),
229 bState ( false ),
230 bSourceRangeValid ( false ),
231 bPrintCurrentTable ( false ),
232 bMultiArea ( false ),
233 nTabPages ( 0 ),
234 nTotalPages ( 0 ),
235 nPagesX(0),
236 nPagesY(0),
237 nTotalY(0),
238 pPageData ( pData )
240 pDev = pPrinter;
241 aSrcOffset = pPrinter->PixelToLogic( pPrinter->GetPageOffsetPixel(), MAP_100TH_MM );
242 Construct( pOptions );
245 ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, SCTAB nTab,
246 long nPage, long nDocP, const ScRange* pArea,
247 const ScPrintOptions* pOptions )
248 : pDocShell ( pShell ),
249 pPrinter ( NULL ),
250 pDrawView ( NULL ),
251 nPrintTab ( nTab ),
252 nPageStart ( nPage ),
253 nDocPages ( nDocP ),
254 pUserArea ( pArea ),
255 bState ( false ),
256 bSourceRangeValid ( false ),
257 bPrintCurrentTable ( false ),
258 bMultiArea ( false ),
259 nTabPages ( 0 ),
260 nTotalPages ( 0 ),
261 nPagesX(0),
262 nPagesY(0),
263 nTotalY(0),
264 pPageData ( NULL )
266 pDev = pOutDev;
267 Construct( pOptions );
270 ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell,
271 const ScPrintState& rState, const ScPrintOptions* pOptions )
272 : pDocShell ( pShell ),
273 pPrinter ( NULL ),
274 pDrawView ( NULL ),
275 pUserArea ( NULL ),
276 bSourceRangeValid ( false ),
277 bPrintCurrentTable ( false ),
278 bMultiArea ( false ),
279 nPagesX(0),
280 nPagesY(0),
281 nTotalY(0),
282 pPageData ( NULL )
284 pDev = pOutDev;
286 nPrintTab = rState.nPrintTab;
287 nStartCol = rState.nStartCol;
288 nStartRow = rState.nStartRow;
289 nEndCol = rState.nEndCol;
290 nEndRow = rState.nEndRow;
291 nZoom = rState.nZoom;
292 nPagesX = rState.nPagesX;
293 nPagesY = rState.nPagesY;
294 nTabPages = rState.nTabPages;
295 nTotalPages = rState.nTotalPages;
296 nPageStart = rState.nPageStart;
297 nDocPages = rState.nDocPages;
298 bState = sal_True;
300 Construct( pOptions );
303 void ScPrintFunc::GetPrintState( ScPrintState& rState )
305 rState.nPrintTab = nPrintTab;
306 rState.nStartCol = nStartCol;
307 rState.nStartRow = nStartRow;
308 rState.nEndCol = nEndCol;
309 rState.nEndRow = nEndRow;
310 rState.nZoom = nZoom;
311 rState.nPagesX = nPagesX;
312 rState.nPagesY = nPagesY;
313 rState.nTabPages = nTabPages;
314 rState.nTotalPages = nTotalPages;
315 rState.nPageStart = nPageStart;
316 rState.nDocPages = nDocPages;
319 sal_Bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const
321 rRange = aLastSourceRange;
322 return bSourceRangeValid;
325 void ScPrintFunc::FillPageData()
327 if (pPageData)
329 sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
330 ScPrintRangeData& rData = pPageData->GetData(nCount); // count up
332 rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab,
333 nEndCol, nEndRow, nPrintTab ) );
334 rData.SetPagesX( nPagesX, pPageEndX );
335 rData.SetPagesY( nTotalY, pPageEndY );
337 // Settings
338 rData.SetTopDown( aTableParam.bTopDown );
339 rData.SetAutomatic( !aAreaParam.bPrintArea );
343 ScPrintFunc::~ScPrintFunc()
345 delete[] pPageEndX;
346 delete[] pPageEndY;
347 delete[] pPageRows;
348 delete pEditDefaults;
349 delete pEditEngine;
351 // Printer settings are now restored from outside
353 // For DrawingLayer/Charts, the MapMode of the printer (RefDevice) must always be correct
354 SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // use Preview also for the printer
355 if (pDocPrinter)
356 pDocPrinter->SetMapMode(aOldPrinterMode);
359 void ScPrintFunc::SetDrawView( FmFormView* pNew )
361 pDrawView = pNew;
364 static void lcl_HidePrint( ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 )
366 for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++)
368 RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY];
369 for (SCCOL nX=nX1; nX<=nX2; nX++)
371 const CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1];
372 if (!rCellInfo.bEmptyCellText)
373 if (((const ScProtectionAttr&)rCellInfo.pPatternAttr->
374 GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet)).GetHidePrint())
376 pThisRowInfo->pCellInfo[nX+1].maCell.clear();
377 pThisRowInfo->pCellInfo[nX+1].bEmptyCellText = true;
384 // output to Device (static)
386 // us used for:
387 // - Clipboard/Bitmap
388 // - Ole-Object (DocShell::Draw)
389 // - Preview of templates
391 void ScPrintFunc::DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double /* nPrintFactor */,
392 const Rectangle& rBound, ScViewData* pViewData, sal_Bool bMetaFile )
394 //! evaluate nPrintFactor !!!
396 SCTAB nTab = 0;
397 if (pViewData)
398 nTab = pViewData->GetTabNo();
400 sal_Bool bDoGrid, bNullVal, bFormula;
401 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
402 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
403 if (pStyleSheet)
405 SfxItemSet& rSet = pStyleSheet->GetItemSet();
406 bDoGrid = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_GRID)).GetValue();
407 bNullVal = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_NULLVALS)).GetValue();
408 bFormula = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_FORMULAS)).GetValue();
410 else
412 const ScViewOptions& rOpt = pDoc->GetViewOptions();
413 bDoGrid = rOpt.GetOption(VOPT_GRID);
414 bNullVal = rOpt.GetOption(VOPT_NULLVALS);
415 bFormula = rOpt.GetOption(VOPT_FORMULAS);
418 MapMode aMode = pDev->GetMapMode();
420 Rectangle aRect = rBound;
422 if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top())
423 aRect = Rectangle( Point(), pDev->GetOutputSize() );
425 SCCOL nX1 = 0;
426 SCROW nY1 = 0;
427 SCCOL nX2 = OLE_STD_CELLS_X - 1;
428 SCROW nY2 = OLE_STD_CELLS_Y - 1;
429 if (bMetaFile)
431 ScRange aRange = pDoc->GetRange( nTab, rBound );
432 nX1 = aRange.aStart.Col();
433 nY1 = aRange.aStart.Row();
434 nX2 = aRange.aEnd.Col();
435 nY2 = aRange.aEnd.Row();
437 else if (pViewData)
439 ScSplitPos eWhich = pViewData->GetActivePart();
440 ScHSplitPos eHWhich = WhichH(eWhich);
441 ScVSplitPos eVWhich = WhichV(eWhich);
442 nX1 = pViewData->GetPosX(eHWhich);
443 nY1 = pViewData->GetPosY(eVWhich);
444 nX2 = nX1 + pViewData->VisibleCellsX(eHWhich);
445 if (nX2>nX1) --nX2;
446 nY2 = nY1 + pViewData->VisibleCellsY(eVWhich);
447 if (nY2>nY1) --nY2;
450 if (nX1 > MAXCOL) nX1 = MAXCOL;
451 if (nX2 > MAXCOL) nX2 = MAXCOL;
452 if (nY1 > MAXROW) nY1 = MAXROW;
453 if (nY2 > MAXROW) nY2 = MAXROW;
455 long nDevSizeX = aRect.Right()-aRect.Left()+1;
456 long nDevSizeY = aRect.Bottom()-aRect.Top()+1;
458 Rectangle aLines;
459 ScRange aRange( nX1,nY1,nTab, nX2,nY2,nTab );
461 long nTwipsSizeX = 0;
462 for (SCCOL i=nX1; i<=nX2; i++)
463 nTwipsSizeX += pDoc->GetColWidth( i, nTab );
464 long nTwipsSizeY = (long) pDoc->GetRowHeight( nY1, nY2, nTab );
466 // if no lines, still space for the outline frame (20 Twips = 1pt)
467 // (HasLines initalizes aLines to 0,0,0,0)
468 nTwipsSizeX += aLines.Left() + std::max( aLines.Right(), 20L );
469 nTwipsSizeY += aLines.Top() + std::max( aLines.Bottom(), 20L );
471 double nScaleX = (double) nDevSizeX / nTwipsSizeX;
472 double nScaleY = (double) nDevSizeY / nTwipsSizeY;
474 //! hand over Flag at FillInfo !!!!!
475 ScRange aERange;
476 sal_Bool bEmbed = pDoc->IsEmbedded();
477 if (bEmbed)
479 pDoc->GetEmbedded(aERange);
480 pDoc->ResetEmbedded();
483 // Assemble data
485 ScTableInfo aTabInfo;
486 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
487 nScaleX, nScaleY, false, bFormula );
488 lcl_HidePrint( aTabInfo, nX1, nX2 );
490 if (bEmbed)
491 pDoc->SetEmbedded(aERange);
493 long nScrX = aRect.Left();
494 long nScrY = aRect.Top();
496 // If no lines, still leave space for grid lines
497 // (would be elseways cut away)
498 long nAddX = (long)( aLines.Left() * nScaleX );
499 nScrX += ( nAddX ? nAddX : 1 );
500 long nAddY = (long)( aLines.Top() * nScaleY );
501 nScrY += ( nAddY ? nAddY : 1 );
503 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nTab,
504 nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
505 aOutputData.SetMetaFileMode(bMetaFile);
506 aOutputData.SetShowNullValues(bNullVal);
507 aOutputData.SetShowFormulas(bFormula);
509 // #114135#
510 ScDrawLayer* pModel = pDoc->GetDrawLayer();
511 FmFormView* pDrawView = NULL;
513 if( pModel )
515 pDrawView = new FmFormView( pModel, pDev );
516 pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
517 pDrawView->SetPrintPreview( sal_True );
518 aOutputData.SetDrawView( pDrawView );
521 //! SetUseStyleColor ??
523 if ( bMetaFile && pDev->GetOutDevType() == OUTDEV_VIRDEV )
524 aOutputData.SetSnapPixel();
526 Point aLogStart = pDev->PixelToLogic( Point(nScrX,nScrY), MAP_100TH_MM );
527 long nLogStX = aLogStart.X();
528 long nLogStY = aLogStart.Y();
530 //! nZoom for GetFont in OutputData ???
532 if (!bMetaFile && pViewData)
533 pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
535 // #i72502#
536 const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
537 aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
539 if (!bMetaFile && pViewData)
540 pDev->SetMapMode(aMode);
542 aOutputData.DrawBackground();
543 aOutputData.DrawShadow();
544 aOutputData.DrawFrame();
545 aOutputData.DrawStrings();
547 if (!bMetaFile && pViewData)
548 pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
550 aOutputData.DrawEdit(!bMetaFile);
552 if (bDoGrid)
554 if (!bMetaFile && pViewData)
555 pDev->SetMapMode(aMode);
557 aOutputData.DrawGrid( sal_True, false ); // no page breaks
559 pDev->SetLineColor( COL_BLACK );
561 Size aOne = pDev->PixelToLogic( Size(1,1) );
562 if (bMetaFile)
563 aOne = Size(1,1); // compatible with DrawGrid
564 long nRight = nScrX + aOutputData.GetScrW() - aOne.Width();
565 long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height();
567 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
569 // extra line at the left edge for left-to-right, right for right-to-left
570 if ( bLayoutRTL )
571 pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) );
572 else
573 pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) );
574 // extra line at the top in both cases
575 pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) );
578 // #i72502#
579 aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
580 aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
581 aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
583 // #114135#
584 delete pDrawView;
588 // Printing
591 static void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet )
593 // nDistance must be initialized differently before
595 if ( pHFSet == NULL )
597 rParam.bEnable = false;
598 rParam.pBorder = NULL;
599 rParam.pBack = NULL;
600 rParam.pShadow = NULL;
602 else
604 rParam.bEnable = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_ON)).GetValue();
605 rParam.bDynamic = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_DYNAMIC)).GetValue();
606 rParam.bShared = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_SHARED)).GetValue();
607 rParam.nHeight = ((const SvxSizeItem&) pHFSet->Get(ATTR_PAGE_SIZE)).GetSize().Height();
608 const SvxLRSpaceItem* pHFLR = &(const SvxLRSpaceItem&) pHFSet->Get(ATTR_LRSPACE);
609 long nTmp;
610 nTmp = pHFLR->GetLeft();
611 rParam.nLeft = nTmp < 0 ? 0 : sal_uInt16(nTmp);
612 nTmp = pHFLR->GetRight();
613 rParam.nRight = nTmp < 0 ? 0 : sal_uInt16(nTmp);
614 rParam.pBorder = (const SvxBoxItem*) &pHFSet->Get(ATTR_BORDER);
615 rParam.pBack = (const SvxBrushItem*) &pHFSet->Get(ATTR_BACKGROUND);
616 rParam.pShadow = (const SvxShadowItem*)&pHFSet->Get(ATTR_SHADOW);
618 // now back in the dialog:
619 // rParam.nHeight += rParam.nDistance; // not in the dialog any more ???
621 if (rParam.pBorder)
622 rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
623 lcl_LineTotal( rParam.pBorder->GetBottom() );
625 rParam.nManHeight = rParam.nHeight;
628 if (!rParam.bEnable)
629 rParam.nHeight = 0;
632 // bNew = TRUE: search for used part of the document
633 // bNew = FALSE: only limit whole lines/columns
635 sal_Bool ScPrintFunc::AdjustPrintArea( sal_Bool bNew )
637 SCCOL nOldEndCol = nEndCol; // only important for !bNew
638 SCROW nOldEndRow = nEndRow;
639 sal_Bool bChangeCol = sal_True; // at bNew both are being adjusted
640 sal_Bool bChangeRow = sal_True;
642 sal_Bool bNotes = aTableParam.bNotes;
643 if ( bNew )
645 nStartCol = 0;
646 nStartRow = 0;
647 if (!pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ))
648 return false; // nix
650 else
652 sal_Bool bFound = sal_True;
653 bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL );
654 bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW );
655 sal_Bool bForcedChangeRow = false;
657 // #i53558# Crop entire column of old row limit to real print area with
658 // some fuzzyness.
659 if (!bChangeRow && nStartRow == 0)
661 SCROW nPAEndRow;
662 bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nPAEndRow, bNotes );
663 // Say we don't want to print more than ~1000 empty rows, which are
664 // about 14 pages intentionally left blank..
665 const SCROW nFuzzy = 23*42;
666 if (nPAEndRow + nFuzzy < nEndRow)
668 bForcedChangeRow = sal_True;
669 nEndRow = nPAEndRow;
671 else
672 bFound = sal_True; // user seems to _want_ to print some empty rows
674 // TODO: in case we extend the number of columns we may have to do the
675 // same for horizontal cropping.
677 if ( bChangeCol && bChangeRow )
678 bFound = pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes );
679 else if ( bChangeCol )
680 bFound = pDoc->GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol, bNotes );
681 else if ( bChangeRow )
682 bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes );
684 if (!bFound)
685 return false; // empty
687 if (bForcedChangeRow)
688 bChangeRow = sal_True;
691 pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab,
692 false ); // no Refresh, incl. Attrs
694 if ( bChangeCol )
696 OutputDevice* pRefDev = pDoc->GetPrinter(); // use the printer also for Preview
697 pRefDev->SetMapMode( MAP_PIXEL ); // important for GetNeededSize
699 pDoc->ExtendPrintArea( pRefDev,
700 nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow );
701 // changing nEndCol
704 if ( nEndCol < MAXCOL && pDoc->HasAttrib(
705 nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_RIGHT ) )
706 ++nEndCol;
707 if ( nEndRow < MAXROW && pDoc->HasAttrib(
708 nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_DOWN ) )
709 ++nEndRow;
711 if (!bChangeCol) nEndCol = nOldEndCol;
712 if (!bChangeRow) nEndRow = nOldEndRow;
714 return sal_True;
717 long ScPrintFunc::TextHeight( const EditTextObject* pObject )
719 if (!pObject)
720 return 0;
722 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
724 return (long) pEditEngine->GetTextHeight();
727 // nZoom must be set !!!
728 // and the respective Twip-MapMode configured
730 void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam )
732 OSL_ENSURE( aPageSize.Width(), "UpdateHFHeight ohne aPageSize");
734 if (rParam.bEnable && rParam.bDynamic)
736 // calculate nHeight from content
738 MakeEditEngine();
739 long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin -
740 rParam.nLeft - rParam.nRight ) * 100 / nZoom;
741 if (rParam.pBorder)
742 nPaperWidth -= ( rParam.pBorder->GetDistance(BOX_LINE_LEFT) +
743 rParam.pBorder->GetDistance(BOX_LINE_RIGHT) +
744 lcl_LineTotal(rParam.pBorder->GetLeft()) +
745 lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom;
747 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
748 nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SHADOW_LEFT) +
749 rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT) ) * 100L / nZoom;
751 pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) );
753 long nMaxHeight = 0;
754 if ( rParam.pLeft )
756 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) );
757 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) );
758 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) );
760 if ( rParam.pRight )
762 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) );
763 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) );
764 nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) );
767 rParam.nHeight = nMaxHeight + rParam.nDistance;
768 if (rParam.pBorder)
769 rParam.nHeight += rParam.pBorder->GetDistance(BOX_LINE_TOP) +
770 rParam.pBorder->GetDistance(BOX_LINE_BOTTOM) +
771 lcl_LineTotal( rParam.pBorder->GetTop() ) +
772 lcl_LineTotal( rParam.pBorder->GetBottom() );
773 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
774 rParam.nHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
775 rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
777 if (rParam.nHeight < rParam.nManHeight)
778 rParam.nHeight = rParam.nManHeight; // configured minimum
782 void ScPrintFunc::InitParam( const ScPrintOptions* pOptions )
784 if (!pParamSet)
785 return;
787 // TabPage "Page"
788 const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &pParamSet->Get( ATTR_LRSPACE );
789 long nTmp;
790 nTmp = pLRItem->GetLeft();
791 nLeftMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
792 nTmp = pLRItem->GetRight();
793 nRightMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
794 const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &pParamSet->Get( ATTR_ULSPACE );
795 nTopMargin = pULItem->GetUpper();
796 nBottomMargin = pULItem->GetLower();
798 const SvxPageItem* pPageItem = (const SvxPageItem*) &pParamSet->Get( ATTR_PAGE );
799 nPageUsage = pPageItem->GetPageUsage();
800 bLandscape = pPageItem->IsLandscape();
801 aFieldData.eNumType = pPageItem->GetNumType();
803 bCenterHor = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_HORCENTER)).GetValue();
804 bCenterVer = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_VERCENTER)).GetValue();
806 aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
807 if ( !aPageSize.Width() || !aPageSize.Height() )
809 OSL_FAIL("PageSize Null ?!?!?");
810 aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
813 pBorderItem = (const SvxBoxItem*) &pParamSet->Get(ATTR_BORDER);
814 pBackgroundItem = (const SvxBrushItem*) &pParamSet->Get(ATTR_BACKGROUND);
815 pShadowItem = (const SvxShadowItem*) &pParamSet->Get(ATTR_SHADOW);
817 // TabPage "Headline"
819 aHdr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERLEFT); // Content
820 aHdr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERRIGHT);
822 const SvxSetItem* pHeaderSetItem;
823 const SfxItemSet* pHeaderSet = NULL;
824 if ( pParamSet->GetItemState( ATTR_PAGE_HEADERSET, false,
825 (const SfxPoolItem**)&pHeaderSetItem ) == SFX_ITEM_SET )
827 pHeaderSet = &pHeaderSetItem->GetItemSet();
828 // Headline has space below
829 aHdr.nDistance = ((const SvxULSpaceItem&) pHeaderSet->Get(ATTR_ULSPACE)).GetLower();
831 lcl_FillHFParam( aHdr, pHeaderSet );
833 // TabPage "Footline"
835 aFtr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERLEFT); // Content
836 aFtr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT);
838 const SvxSetItem* pFooterSetItem;
839 const SfxItemSet* pFooterSet = NULL;
840 if ( pParamSet->GetItemState( ATTR_PAGE_FOOTERSET, false,
841 (const SfxPoolItem**)&pFooterSetItem ) == SFX_ITEM_SET )
843 pFooterSet = &pFooterSetItem->GetItemSet();
844 // Footline has space above
845 aFtr.nDistance = ((const SvxULSpaceItem&) pFooterSet->Get(ATTR_ULSPACE)).GetUpper();
847 lcl_FillHFParam( aFtr, pFooterSet );
849 //------------------------------------------------------
850 // Compile Table-/Area-Params from single Items
851 //------------------------------------------------------
852 // TabPage "Table"
854 const SfxUInt16Item* pScaleItem = NULL;
855 const ScPageScaleToItem* pScaleToItem = NULL;
856 const SfxUInt16Item* pScaleToPagesItem = NULL;
857 SfxItemState eState;
859 eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, false,
860 (const SfxPoolItem**)&pScaleItem );
861 if ( SFX_ITEM_DEFAULT == eState )
862 pScaleItem = (const SfxUInt16Item*)
863 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE );
865 eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, false,
866 (const SfxPoolItem**)&pScaleToItem );
867 if ( SFX_ITEM_DEFAULT == eState )
868 pScaleToItem = (const ScPageScaleToItem*)
869 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO );
871 eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, false,
872 (const SfxPoolItem**)&pScaleToPagesItem );
873 if ( SFX_ITEM_DEFAULT == eState )
874 pScaleToPagesItem = (const SfxUInt16Item*)
875 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETOPAGES );
877 OSL_ENSURE( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" );
879 aTableParam.bCellContent = sal_True;
880 aTableParam.bNotes = GET_BOOL(pParamSet,ATTR_PAGE_NOTES);
881 aTableParam.bGrid = GET_BOOL(pParamSet,ATTR_PAGE_GRID);
882 aTableParam.bHeaders = GET_BOOL(pParamSet,ATTR_PAGE_HEADERS);
883 aTableParam.bFormulas = GET_BOOL(pParamSet,ATTR_PAGE_FORMULAS);
884 aTableParam.bNullVals = GET_BOOL(pParamSet,ATTR_PAGE_NULLVALS);
885 aTableParam.bCharts = GET_SHOW(pParamSet,ATTR_PAGE_CHARTS);
886 aTableParam.bObjects = GET_SHOW(pParamSet,ATTR_PAGE_OBJECTS);
887 aTableParam.bDrawings = GET_SHOW(pParamSet,ATTR_PAGE_DRAWINGS);
888 aTableParam.bTopDown = GET_BOOL(pParamSet,ATTR_PAGE_TOPDOWN);
889 aTableParam.bLeftRight = !aTableParam.bLeftRight;
890 aTableParam.nFirstPageNo = GET_USHORT(pParamSet,ATTR_PAGE_FIRSTPAGENO);
891 if (!aTableParam.nFirstPageNo)
892 aTableParam.nFirstPageNo = (sal_uInt16) nPageStart; // from previous table
894 if ( pScaleItem && pScaleToItem && pScaleToPagesItem )
896 sal_uInt16 nScaleAll = pScaleItem->GetValue();
897 sal_uInt16 nScaleToPages = pScaleToPagesItem->GetValue();
899 aTableParam.bScaleNone = (nScaleAll == 100);
900 aTableParam.bScaleAll = (nScaleAll > 0 );
901 aTableParam.bScaleTo = pScaleToItem->IsValid();
902 aTableParam.bScalePageNum = (nScaleToPages > 0 );
903 aTableParam.nScaleAll = nScaleAll;
904 aTableParam.nScaleWidth = pScaleToItem->GetWidth();
905 aTableParam.nScaleHeight = pScaleToItem->GetHeight();
906 aTableParam.nScalePageNum = nScaleToPages;
908 else
910 aTableParam.bScaleNone = sal_True;
911 aTableParam.bScaleAll = false;
912 aTableParam.bScaleTo = false;
913 aTableParam.bScalePageNum = false;
914 aTableParam.nScaleAll = 0;
915 aTableParam.nScaleWidth = 0;
916 aTableParam.nScaleHeight = 0;
917 aTableParam.nScalePageNum = 0;
920 // skip empty pages only if options with that flag are passed
921 aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty();
922 if ( pPageData )
923 aTableParam.bSkipEmpty = false;
924 // If pPageData is set, only the breaks are interesting for the
925 // pagebreak preview, empty pages are not addressed separately.
927 //------------------------------------------------------
928 // TabPage "Parts":
929 //------------------------------------------------------
931 //! walk throuch all PrintAreas of the table !!!
932 const ScRange* pPrintArea = pDoc->GetPrintRange( nPrintTab, 0 );
933 const ScRange* pRepeatCol = pDoc->GetRepeatColRange( nPrintTab );
934 const ScRange* pRepeatRow = pDoc->GetRepeatRowRange( nPrintTab );
936 // ignoring ATTR_PAGE_PRINTTABLES
938 if ( pUserArea ) // UserArea (selection) has prority
940 bPrintCurrentTable =
941 aAreaParam.bPrintArea = sal_True; // Selection
942 aAreaParam.aPrintArea = *pUserArea;
944 // The table-query is already in DocShell::Print, here always
945 aAreaParam.aPrintArea.aStart.SetTab(nPrintTab);
946 aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab);
948 else if ( pDoc->HasPrintRange() )
950 if ( pPrintArea ) // at least one set?
952 bPrintCurrentTable =
953 aAreaParam.bPrintArea = sal_True;
954 aAreaParam.aPrintArea = *pPrintArea;
956 bMultiArea = ( pDoc->GetPrintRangeCount(nPrintTab) > 1 );
958 else
960 // do not print hidden sheets with "Print entire sheet" flag
961 bPrintCurrentTable = pDoc->IsPrintEntireSheet( nPrintTab ) && pDoc->IsVisible( nPrintTab );
962 aAreaParam.bPrintArea = !bPrintCurrentTable; // otherwise the table is always counted
965 else
967 // don't print hidden tables if there's no print range defined there
968 if ( pDoc->IsVisible( nPrintTab ) )
970 aAreaParam.bPrintArea = false;
971 bPrintCurrentTable = sal_True;
973 else
975 aAreaParam.bPrintArea = sal_True; // otherwise the table is always counted
976 bPrintCurrentTable = false;
980 if ( pRepeatCol )
982 aAreaParam.bRepeatCol = sal_True;
983 aAreaParam.aRepeatCol = *pRepeatCol;
984 nRepeatStartCol = pRepeatCol->aStart.Col();
985 nRepeatEndCol = pRepeatCol->aEnd .Col();
987 else
989 aAreaParam.bRepeatCol = false;
990 nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE;
993 if ( pRepeatRow )
995 aAreaParam.bRepeatRow = sal_True;
996 aAreaParam.aRepeatRow = *pRepeatRow;
997 nRepeatStartRow = pRepeatRow->aStart.Row();
998 nRepeatEndRow = pRepeatRow->aEnd .Row();
1000 else
1002 aAreaParam.bRepeatRow = false;
1003 nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE;
1007 // Split pages
1010 if (!bState)
1012 nTabPages = CountPages(); // also calculates zoom
1013 nTotalPages = nTabPages;
1014 nTotalPages += CountNotePages();
1016 else
1018 CalcPages(); // search breaks only
1019 CountNotePages(); // Count notes, even if number of pages is already known
1022 if (nDocPages)
1023 aFieldData.nTotalPages = nDocPages;
1024 else
1025 aFieldData.nTotalPages = nTotalPages;
1027 SetDateTime( Date( Date::SYSTEM ), Time( Time::SYSTEM ) );
1029 if( pDocShell->getDocProperties()->getTitle().getLength() != 0 )
1030 aFieldData.aTitle = pDocShell->getDocProperties()->getTitle();
1031 else
1032 aFieldData.aTitle = pDocShell->GetTitle();
1034 const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
1035 aFieldData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
1036 if ( aFieldData.aLongDocName.Len() )
1037 aFieldData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
1038 else
1039 aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle;
1041 // Printer settings (Orientation, Paper) at DoPrint
1044 Size ScPrintFunc::GetDataSize() const
1046 Size aSize = aPageSize;
1047 aSize.Width() -= nLeftMargin + nRightMargin;
1048 aSize.Height() -= nTopMargin + nBottomMargin;
1049 aSize.Height() -= aHdr.nHeight + aFtr.nHeight;
1050 return aSize;
1053 void ScPrintFunc::GetScaleData( Size& rPhysSize, long& rDocHdr, long& rDocFtr )
1055 rPhysSize = aPageSize;
1056 rPhysSize.Width() -= nLeftMargin + nRightMargin;
1057 rPhysSize.Height() -= nTopMargin + nBottomMargin;
1059 rDocHdr = aHdr.nHeight;
1060 rDocFtr = aFtr.nHeight;
1063 void ScPrintFunc::SetDateTime( const Date& rDate, const Time& rTime )
1065 aFieldData.aDate = rDate;
1066 aFieldData.aTime = rTime;
1069 static void lcl_DrawGraphic( const Graphic &rGraphic, OutputDevice *pOut,
1070 const Rectangle &rGrf, const Rectangle &rOut )
1072 const bool bNotInside = !rOut.IsInside( rGrf );
1073 if ( bNotInside )
1075 pOut->Push();
1076 pOut->IntersectClipRegion( rOut );
1079 ((Graphic&)rGraphic).Draw( pOut, rGrf.TopLeft(), rGrf.GetSize() );
1081 if ( bNotInside )
1082 pOut->Pop();
1085 static void lcl_DrawGraphic( const SvxBrushItem &rBrush, OutputDevice *pOut, OutputDevice* pRefDev,
1086 const Rectangle &rOrg, const Rectangle &rOut )
1088 Size aGrfSize(0,0);
1089 const Graphic *pGraphic = rBrush.GetGraphic();
1090 SvxGraphicPosition ePos;
1091 if ( pGraphic && pGraphic->IsSupportedGraphic() )
1093 const MapMode aMapMM( MAP_100TH_MM );
1094 if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1095 aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM );
1096 else
1097 aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1098 pGraphic->GetPrefMapMode(), aMapMM );
1099 ePos = rBrush.GetGraphicPos();
1101 else
1102 ePos = GPOS_NONE;
1104 Point aPos;
1105 Size aDrawSize = aGrfSize;
1107 bool bDraw = true;
1108 switch ( ePos )
1110 case GPOS_LT: aPos = rOrg.TopLeft();
1111 break;
1112 case GPOS_MT: aPos.Y() = rOrg.Top();
1113 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1114 break;
1115 case GPOS_RT: aPos.Y() = rOrg.Top();
1116 aPos.X() = rOrg.Right() - aGrfSize.Width();
1117 break;
1119 case GPOS_LM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1120 aPos.X() = rOrg.Left();
1121 break;
1122 case GPOS_MM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1123 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1124 break;
1125 case GPOS_RM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1126 aPos.X() = rOrg.Right() - aGrfSize.Width();
1127 break;
1129 case GPOS_LB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1130 aPos.X() = rOrg.Left();
1131 break;
1132 case GPOS_MB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1133 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1134 break;
1135 case GPOS_RB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1136 aPos.X() = rOrg.Right() - aGrfSize.Width();
1137 break;
1139 case GPOS_AREA:
1140 aPos = rOrg.TopLeft();
1141 aDrawSize = rOrg.GetSize();
1142 break;
1143 case GPOS_TILED:
1145 // use GraphicObject::DrawTiled instead of an own loop
1146 // (pixel rounding is handled correctly, and a very small bitmap
1147 // is duplicated into a bigger one for better performance)
1149 GraphicObject aObject( *pGraphic );
1151 if( pOut->GetPDFWriter() &&
1152 (aObject.GetType() == GRAPHIC_BITMAP || aObject.GetType() == GRAPHIC_DEFAULT) )
1154 // For PDF export, every draw
1155 // operation for bitmaps takes a noticeable
1156 // amount of place (~50 characters). Thus,
1157 // optimize between tile bitmap size and
1158 // number of drawing operations here.
1160 // A_out
1161 // n_chars = k1 * ---------- + k2 * A_bitmap
1162 // A_bitmap
1164 // minimum n_chars is obtained for (derive for
1165 // A_bitmap, set to 0, take positive
1166 // solution):
1167 // k1
1168 // A_bitmap = Sqrt( ---- A_out )
1169 // k2
1171 // where k1 is the number of chars per draw
1172 // operation, and k2 is the number of chars
1173 // per bitmap pixel. This is approximately 50
1174 // and 7 for current PDF writer, respectively.
1176 const double k1( 50 );
1177 const double k2( 7 );
1178 const Size aSize( rOrg.GetSize() );
1179 const double Abitmap( k1/k2 * aSize.Width()*aSize.Height() );
1181 aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0),
1182 NULL, GRFMGR_DRAW_STANDARD,
1183 ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
1185 else
1187 aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0) );
1190 bDraw = false;
1192 break;
1194 case GPOS_NONE:
1195 bDraw = false;
1196 break;
1198 default: OSL_ENSURE( !pOut, "new Graphic position?" );
1200 Rectangle aGrf( aPos,aDrawSize );
1201 if ( bDraw && aGrf.IsOver( rOut ) )
1203 lcl_DrawGraphic( *pGraphic, pOut, aGrf, rOut );
1207 // Rahmen wird nach innen gezeichnet
1209 void ScPrintFunc::DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH,
1210 const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground,
1211 const SvxShadowItem* pShadow )
1213 //! direkte Ausgabe aus SvxBoxItem !!!
1215 if (pBorderData)
1216 if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() &&
1217 !pBorderData->GetRight() )
1218 pBorderData = NULL;
1220 if (!pBorderData && !pBackground && !pShadow)
1221 return; // nichts zu tun
1223 long nLeft = 0;
1224 long nRight = 0;
1225 long nTop = 0;
1226 long nBottom = 0;
1228 // aFrameRect - ouside around frame, without shadow
1229 if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1231 nLeft += (long) ( pShadow->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
1232 nRight += (long) ( pShadow->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
1233 nTop += (long) ( pShadow->CalcShadowSpace(SHADOW_TOP) * nScaleY );
1234 nBottom += (long) ( pShadow->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
1236 Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop),
1237 Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) );
1239 // center of frame, to paint lines through OutputData
1240 if (pBorderData)
1242 nLeft += (long) ( lcl_LineTotal(pBorderData->GetLeft()) * nScaleX / 2 );
1243 nRight += (long) ( lcl_LineTotal(pBorderData->GetRight()) * nScaleX / 2 );
1244 nTop += (long) ( lcl_LineTotal(pBorderData->GetTop()) * nScaleY / 2 );
1245 nBottom += (long) ( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 );
1247 long nEffHeight = nScrH - nTop - nBottom;
1248 long nEffWidth = nScrW - nLeft - nRight;
1249 if (nEffHeight<=0 || nEffWidth<=0)
1250 return; // enmpty
1252 if ( pBackground )
1254 if (pBackground->GetGraphicPos() != GPOS_NONE)
1256 OutputDevice* pRefDev;
1257 if ( bIsRender )
1258 pRefDev = pDev; // don't use printer for PDF
1259 else
1260 pRefDev = pDoc->GetPrinter(); // use printer also for preview
1262 lcl_DrawGraphic( *pBackground, pDev, pRefDev, aFrameRect, aFrameRect );
1264 else
1266 pDev->SetFillColor(pBackground->GetColor());
1267 pDev->SetLineColor();
1268 pDev->DrawRect(aFrameRect);
1272 if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1274 pDev->SetFillColor(pShadow->GetColor());
1275 pDev->SetLineColor();
1276 long nShadowX = (long) ( pShadow->GetWidth() * nScaleX );
1277 long nShadowY = (long) ( pShadow->GetWidth() * nScaleY );
1278 switch (pShadow->GetLocation())
1280 case SVX_SHADOW_TOPLEFT:
1281 pDev->DrawRect( Rectangle(
1282 aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1283 aFrameRect.Right()-nShadowX, aFrameRect.Top() ) );
1284 pDev->DrawRect( Rectangle(
1285 aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1286 aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) );
1287 break;
1288 case SVX_SHADOW_TOPRIGHT:
1289 pDev->DrawRect( Rectangle(
1290 aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY,
1291 aFrameRect.Right()+nShadowX, aFrameRect.Top() ) );
1292 pDev->DrawRect( Rectangle(
1293 aFrameRect.Right(), aFrameRect.Top()-nShadowY,
1294 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) );
1295 break;
1296 case SVX_SHADOW_BOTTOMLEFT:
1297 pDev->DrawRect( Rectangle(
1298 aFrameRect.Left()-nShadowX, aFrameRect.Bottom(),
1299 aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) );
1300 pDev->DrawRect( Rectangle(
1301 aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY,
1302 aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) );
1303 break;
1304 case SVX_SHADOW_BOTTOMRIGHT:
1305 pDev->DrawRect( Rectangle(
1306 aFrameRect.Left()+nShadowX, aFrameRect.Bottom(),
1307 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1308 pDev->DrawRect( Rectangle(
1309 aFrameRect.Right(), aFrameRect.Top()+nShadowY,
1310 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1311 break;
1312 default:
1314 // added to avoid warnings
1319 if (pBorderData)
1321 ScDocument* pBorderDoc = new ScDocument( SCDOCMODE_UNDO );
1322 pBorderDoc->InitUndo( pDoc, 0,0, sal_True,sal_True );
1323 if (pBorderData)
1324 pBorderDoc->ApplyAttr( 0,0,0, *pBorderData );
1326 ScTableInfo aTabInfo;
1327 pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0,
1328 nScaleX, nScaleY, false, false );
1329 OSL_ENSURE(aTabInfo.mnArrCount,"nArrCount == 0");
1331 aTabInfo.mpRowInfo[1].nHeight = (sal_uInt16) nEffHeight;
1332 aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth =
1333 aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = (sal_uInt16) nEffWidth;
1335 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc, 0,
1336 nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY );
1337 aOutputData.SetUseStyleColor( bUseStyleColor );
1339 if (pBorderData)
1340 aOutputData.DrawFrame();
1342 delete pBorderDoc;
1346 void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY )
1348 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1349 long nLayoutSign = bLayoutRTL ? -1 : 1;
1351 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1352 long nOneX = aOnePixel.Width();
1353 long nOneY = aOnePixel.Height();
1354 SCCOL nCol;
1356 long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1357 long nEndY = nScrY + nHeight - nOneY;
1359 long nPosX = nScrX;
1360 if ( bLayoutRTL )
1362 for (nCol=nX1; nCol<=nX2; nCol++)
1363 nPosX += (long)( pDoc->GetColWidth( nCol, nPrintTab ) * nScaleX );
1365 else
1366 nPosX -= nOneX;
1367 long nPosY = nScrY - nOneY;
1368 String aText;
1370 for (nCol=nX1; nCol<=nX2; nCol++)
1372 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1373 if (nDocW)
1375 long nWidth = (long) (nDocW * nScaleX);
1376 long nEndX = nPosX + nWidth * nLayoutSign;
1378 pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1380 aText = ::ScColToAlpha( nCol);
1381 long nTextWidth = pDev->GetTextWidth(aText);
1382 long nTextHeight = pDev->GetTextHeight();
1383 long nAddX = ( nWidth - nTextWidth ) / 2;
1384 long nAddY = ( nHeight - nTextHeight ) / 2;
1385 long nTextPosX = nPosX+nAddX;
1386 if ( bLayoutRTL )
1387 nTextPosX -= nWidth;
1388 pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText );
1390 nPosX = nEndX;
1395 void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY )
1397 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1398 long nOneX = aOnePixel.Width();
1399 long nOneY = aOnePixel.Height();
1401 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1403 long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1404 long nEndX = nScrX + nWidth;
1405 long nPosX = nScrX;
1406 if ( !bLayoutRTL )
1408 nEndX -= nOneX;
1409 nPosX -= nOneX;
1411 long nPosY = nScrY - nOneY;
1412 String aText;
1414 for (SCROW nRow=nY1; nRow<=nY2; nRow++)
1416 sal_uInt16 nDocH = pDoc->GetRowHeight( nRow, nPrintTab );
1417 if (nDocH)
1419 long nHeight = (long) (nDocH * nScaleY);
1420 long nEndY = nPosY + nHeight;
1422 pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1424 aText = OUString::number( nRow+1 );
1425 long nTextWidth = pDev->GetTextWidth(aText);
1426 long nTextHeight = pDev->GetTextHeight();
1427 long nAddX = ( nWidth - nTextWidth ) / 2;
1428 long nAddY = ( nHeight - nTextHeight ) / 2;
1429 pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText );
1431 nPosY = nEndY;
1436 void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY,
1437 sal_Bool bRepCol, ScPreviewLocationData& rLocationData )
1439 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1440 long nOneX = aOnePixel.Width();
1441 long nOneY = aOnePixel.Height();
1443 long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1444 long nEndY = nScrY + nHeight - nOneY;
1446 long nPosX = nScrX - nOneX;
1447 for (SCCOL nCol=nX1; nCol<=nX2; nCol++)
1449 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1450 if (nDocW)
1451 nPosX += (long) (nDocW * nScaleX);
1453 Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY );
1454 rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol );
1457 void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY,
1458 sal_Bool bRepRow, ScPreviewLocationData& rLocationData )
1460 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1461 long nOneX = aOnePixel.Width();
1462 long nOneY = aOnePixel.Height();
1464 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1466 long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1467 long nEndX = nScrX + nWidth;
1468 if ( !bLayoutRTL )
1469 nEndX -= nOneX;
1471 long nPosY = nScrY - nOneY;
1472 nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1473 Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY );
1474 rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow );
1477 void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1478 long nScrX, long nScrY, sal_Bool bRepCol, sal_Bool bRepRow,
1479 ScPreviewLocationData& rLocationData )
1481 // get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer)
1483 Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1484 long nLogStX = aLogPos.X();
1485 long nLogStY = aLogPos.Y();
1487 SCCOL nCol;
1488 Point aTwipOffset;
1489 for (nCol=0; nCol<nX1; nCol++)
1490 aTwipOffset.X() -= pDoc->GetColWidth( nCol, nPrintTab );
1491 aTwipOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nPrintTab );
1493 Point aMMOffset( aTwipOffset );
1494 aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS);
1495 aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS);
1496 aMMOffset += Point( nLogStX, nLogStY );
1497 MapMode aDrawMapMode( MAP_100TH_MM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() );
1499 // get pixel rectangle
1501 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1502 long nOneX = aOnePixel.Width();
1503 long nOneY = aOnePixel.Height();
1505 long nPosX = nScrX - nOneX;
1506 for (nCol=nX1; nCol<=nX2; nCol++)
1508 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1509 if (nDocW)
1510 nPosX += (long) (nDocW * nScaleX);
1513 long nPosY = nScrY - nOneY;
1514 nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1515 Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY );
1516 rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ),
1517 bRepCol, bRepRow, aDrawMapMode );
1520 void ScPrintFunc::PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1521 long nScrX, long nScrY,
1522 sal_Bool bShLeft, sal_Bool bShTop, sal_Bool bShRight, sal_Bool bShBottom )
1524 // #i47547# nothing to do if the end of the print area is before the end of
1525 // the repeat columns/rows (don't use negative size for ScOutputData)
1526 if ( nX2 < nX1 || nY2 < nY1 )
1527 return;
1529 //! hand over Flag at FillInfo !!!!!
1530 ScRange aERange;
1531 sal_Bool bEmbed = pDoc->IsEmbedded();
1532 if (bEmbed)
1534 pDoc->GetEmbedded(aERange);
1535 pDoc->ResetEmbedded();
1538 Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1539 long nLogStX = aPos.X();
1540 long nLogStY = aPos.Y();
1542 // Assemble data
1544 ScTableInfo aTabInfo;
1545 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab,
1546 nScaleX, nScaleY, sal_True, aTableParam.bFormulas );
1547 lcl_HidePrint( aTabInfo, nX1, nX2 );
1549 if (bEmbed)
1550 pDoc->SetEmbedded(aERange);
1552 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nPrintTab,
1553 nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
1555 // #114135#
1556 aOutputData.SetDrawView( pDrawView );
1558 // test if all paint parts are hidden, then a paint is not necessary at all
1559 const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
1560 const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart()
1561 && pDrawView->getHideDraw() && pDrawView->getHideFormControl() );
1563 if(!bHideAllDrawingLayer)
1565 pDev->SetMapMode(aLogicMode);
1566 // don's set Clipping here (Mapmode is being moved)
1568 // #i72502#
1569 aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
1572 pDev->SetMapMode(aOffsetMode);
1574 aOutputData.SetShowFormulas( aTableParam.bFormulas );
1575 aOutputData.SetShowNullValues( aTableParam.bNullVals );
1576 aOutputData.SetUseStyleColor( bUseStyleColor );
1578 Color aGridColor( COL_BLACK );
1579 if ( bUseStyleColor )
1580 aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
1581 aOutputData.SetGridColor( aGridColor );
1583 if ( !pPrinter )
1585 OutputDevice* pRefDev = pDoc->GetPrinter(); // use the printer also for Preview
1586 Fraction aPrintFrac( nZoom, 100 ); // without nManualZoom
1587 // MapMode, as it would arrive at the printer:
1588 pRefDev->SetMapMode( MapMode( MAP_100TH_MM, Point(), aPrintFrac, aPrintFrac ) );
1590 // when rendering (PDF), don't use printer as ref device, but printer's MapMode
1591 // has to be set anyway, as charts still use it (#106409#)
1592 if ( !bIsRender )
1593 aOutputData.SetRefDevice( pRefDev );
1596 if( aTableParam.bCellContent )
1597 aOutputData.DrawBackground();
1599 pDev->SetClipRegion(Region(Rectangle(
1600 aPos, Size(aOutputData.GetScrW(), aOutputData.GetScrH()))));
1601 pDev->SetClipRegion();
1603 if( aTableParam.bCellContent )
1605 aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom );
1606 aOutputData.DrawFrame();
1607 aOutputData.DrawStrings();
1608 aOutputData.DrawEdit(false);
1611 if (aTableParam.bGrid)
1612 aOutputData.DrawGrid( sal_True, false ); // no page breaks
1614 aOutputData.AddPDFNotes(); // has no effect if not rendering PDF with notes enabled
1616 // test if all paint parts are hidden, then a paint is not necessary at all
1617 if(!bHideAllDrawingLayer)
1619 // #i72502#
1620 aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
1623 // #i72502#
1624 aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
1625 aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
1628 sal_Bool ScPrintFunc::IsMirror( long nPageNo ) // Mirror margins?
1630 SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1631 return ( eUsage == SVX_PAGE_MIRROR && (nPageNo & 1) );
1634 sal_Bool ScPrintFunc::IsLeft( long nPageNo ) // left foot notes?
1636 SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1637 sal_Bool bLeft;
1638 if (eUsage == SVX_PAGE_LEFT)
1639 bLeft = sal_True;
1640 else if (eUsage == SVX_PAGE_RIGHT)
1641 bLeft = false;
1642 else
1643 bLeft = (nPageNo & 1) != 0;
1644 return bLeft;
1647 void ScPrintFunc::MakeTableString()
1649 OUString aTmp;
1650 pDoc->GetName(nPrintTab, aTmp);
1651 aFieldData.aTabName = aTmp;
1654 void ScPrintFunc::MakeEditEngine()
1656 if (!pEditEngine)
1658 // can't use document's edit engine pool here,
1659 // because pool must have twips as default metric
1660 pEditEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), sal_True );
1662 pEditEngine->EnableUndo(false);
1663 //fdo#45869 we want text to be positioned as it would be for the the
1664 //high dpi printed output, not as would be ideal for the 96dpi preview
1665 //window itself
1666 pEditEngine->SetRefDevice(pPrinter ? pPrinter : pDoc->GetRefDevice());
1667 pEditEngine->SetWordDelimiters(
1668 ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
1669 pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
1670 pDoc->ApplyAsianEditSettings( *pEditEngine );
1671 pEditEngine->EnableAutoColor( bUseStyleColor );
1673 // Default-Set for alignment
1674 pEditDefaults = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
1676 const ScPatternAttr& rPattern = (const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN);
1677 rPattern.FillEditItemSet( pEditDefaults );
1678 // FillEditItemSet adjusts font height to 1/100th mm,
1679 // but for header/footer twips is needed, as in the PatternAttr:
1680 pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
1681 pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
1682 pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
1683 // dont use font color, because background color is not used
1684 //! there's no way to set the background for note pages
1685 pEditDefaults->ClearItem( EE_CHAR_COLOR );
1686 if (ScGlobal::IsSystemRTL())
1687 pEditDefaults->Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
1690 pEditEngine->SetData( aFieldData ); // Set page count etc.
1693 // nStartY = logic
1694 void ScPrintFunc::PrintHF( long nPageNo, sal_Bool bHeader, long nStartY,
1695 sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1697 const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr;
1699 pDev->SetMapMode( aTwipMode ); // Head-/Footlines in Twips
1701 sal_Bool bLeft = IsLeft(nPageNo) && !rParam.bShared;
1702 const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight;
1704 long nLineStartX = aPageRect.Left() + rParam.nLeft;
1705 long nLineEndX = aPageRect.Right() - rParam.nRight;
1706 long nLineWidth = nLineEndX - nLineStartX + 1;
1708 // Edit-Engine
1710 Point aStart( nLineStartX, nStartY );
1711 Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1712 if ( rParam.pBorder )
1714 long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(BOX_LINE_LEFT);
1715 long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(BOX_LINE_TOP);
1716 aStart.X() += nLeft;
1717 aStart.Y() += nTop;
1718 aPaperSize.Width() -= nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(BOX_LINE_RIGHT);
1719 aPaperSize.Height() -= nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
1722 if ( rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE )
1724 long nLeft = rParam.pShadow->CalcShadowSpace(SHADOW_LEFT);
1725 long nTop = rParam.pShadow->CalcShadowSpace(SHADOW_TOP);
1726 aStart.X() += nLeft;
1727 aStart.Y() += nTop;
1728 aPaperSize.Width() -= nLeft + rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT);
1729 aPaperSize.Height() -= nTop + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
1732 aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo;
1733 MakeEditEngine();
1735 pEditEngine->SetPaperSize(aPaperSize);
1737 // Frame / Background
1739 Point aBorderStart( nLineStartX, nStartY );
1740 Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1741 if ( rParam.bDynamic )
1743 // adjust here again, for even/odd head-/footlines
1744 // and probably other breaks by variable (page number etc.)
1746 long nMaxHeight = 0;
1747 nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) );
1748 nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) );
1749 nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) );
1750 if (rParam.pBorder)
1751 nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
1752 lcl_LineTotal( rParam.pBorder->GetBottom() ) +
1753 rParam.pBorder->GetDistance(BOX_LINE_TOP) +
1754 rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
1755 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
1756 nMaxHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
1757 rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
1759 if (nMaxHeight < rParam.nManHeight-rParam.nDistance)
1760 nMaxHeight = rParam.nManHeight-rParam.nDistance; // configured Minimum
1762 aBorderSize.Height() = nMaxHeight;
1765 if ( bDoPrint )
1767 double nOldScaleX = nScaleX;
1768 double nOldScaleY = nScaleY;
1769 nScaleX = nScaleY = 1.0; // output directly in Twips
1770 DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(),
1771 rParam.pBorder, rParam.pBack, rParam.pShadow );
1772 nScaleX = nOldScaleX;
1773 nScaleY = nOldScaleY;
1775 // Clipping for Text
1777 pDev->SetClipRegion(Region(Rectangle(aStart, aPaperSize)));
1779 // left
1781 const EditTextObject* pObject = pHFItem->GetLeftArea();
1782 if (pObject)
1784 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1785 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1786 Point aDraw = aStart;
1787 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1788 if (nDif > 0)
1789 aDraw.Y() += nDif / 2;
1790 pEditEngine->Draw( pDev, aDraw, 0 );
1793 // center
1795 pObject = pHFItem->GetCenterArea();
1796 if (pObject)
1798 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
1799 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1800 Point aDraw = aStart;
1801 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1802 if (nDif > 0)
1803 aDraw.Y() += nDif / 2;
1804 pEditEngine->Draw( pDev, aDraw, 0 );
1807 // right
1809 pObject = pHFItem->GetRightArea();
1810 if (pObject)
1812 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
1813 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1814 Point aDraw = aStart;
1815 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1816 if (nDif > 0)
1817 aDraw.Y() += nDif / 2;
1818 pEditEngine->Draw( pDev, aDraw, 0 );
1821 pDev->SetClipRegion();
1824 if ( pLocationData )
1826 Rectangle aHeaderRect( aBorderStart, aBorderSize );
1827 pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft );
1831 long ScPrintFunc::DoNotes( long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1833 if (bDoPrint)
1834 pDev->SetMapMode(aTwipMode);
1836 MakeEditEngine();
1837 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1838 pEditEngine->SetDefaults( *pEditDefaults );
1840 Font aMarkFont;
1841 ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
1842 ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).GetFont( aMarkFont, eColorMode );
1843 pDev->SetFont( aMarkFont );
1844 long nMarkLen = pDev->GetTextWidth(OUString("GW99999:"));
1845 // without Space-Char, because it rarle arrives there
1847 Size aDataSize = aPageRect.GetSize();
1848 if ( nMarkLen > aDataSize.Width() / 2 ) // everything much too small?
1849 nMarkLen = aDataSize.Width() / 2; // split the page appropriately
1850 aDataSize.Width() -= nMarkLen;
1852 pEditEngine->SetPaperSize( aDataSize );
1853 long nPosX = aPageRect.Left() + nMarkLen;
1854 long nPosY = aPageRect.Top();
1856 long nCount = 0;
1857 long nSize = aNotePosList.size();
1858 sal_Bool bOk;
1861 bOk = false;
1862 if ( nNoteStart + nCount < nSize)
1864 ScAddress &rPos = aNotePosList[ nNoteStart + nCount ];
1866 if( const ScPostIt* pNote = pDoc->GetNotes(rPos.Tab())->findByAddress( rPos ) )
1868 if(const EditTextObject *pEditText = pNote->GetEditTextObject())
1869 pEditEngine->SetText(*pEditText);
1870 long nTextHeight = pEditEngine->GetTextHeight();
1871 if ( nPosY + nTextHeight < aPageRect.Bottom() )
1873 if (bDoPrint)
1875 pEditEngine->Draw( pDev, Point( nPosX, nPosY ), 0 );
1877 String aMarkStr;
1878 rPos.Format( aMarkStr, SCA_VALID, pDoc, pDoc->GetAddressConvention() );
1879 aMarkStr += ':';
1881 // cell position also via EditEngine, for correct positioning
1882 pEditEngine->SetText(aMarkStr);
1883 pEditEngine->Draw( pDev, Point( aPageRect.Left(), nPosY ), 0 );
1886 if ( pLocationData )
1888 Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) );
1889 pLocationData->AddNoteText( aTextRect, rPos );
1890 Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) );
1891 pLocationData->AddNoteMark( aMarkRect, rPos );
1894 nPosY += nTextHeight;
1895 nPosY += 200; // Distance
1896 ++nCount;
1897 bOk = sal_True;
1902 while (bOk);
1904 return nCount;
1907 long ScPrintFunc::PrintNotes( long nPageNo, long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1909 if ( nNoteStart >= (long) aNotePosList.size() || !aTableParam.bNotes )
1910 return 0;
1912 if ( bDoPrint && bClearWin )
1914 //! aggregate PrintPage !!!
1916 Color aBackgroundColor( COL_WHITE );
1917 if ( bUseStyleColor )
1918 aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1920 pDev->SetMapMode(aOffsetMode);
1921 pDev->SetLineColor();
1922 pDev->SetFillColor(aBackgroundColor);
1923 pDev->DrawRect(Rectangle(Point(),
1924 Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
1925 (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
1929 // adjust aPageRect for left/right page
1931 Rectangle aTempRect = Rectangle( Point(), aPageSize );
1932 if (IsMirror(nPageNo))
1934 aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
1935 aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
1937 else
1939 aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
1940 aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
1943 if ( pPrinter && bDoPrint )
1945 OSL_FAIL( "StartPage does not exist anymore" );
1948 if ( bDoPrint || pLocationData )
1950 // Head and foot lines
1952 if (aHdr.bEnable)
1954 long nHeaderY = aPageRect.Top()-aHdr.nHeight;
1955 PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
1957 if (aFtr.bEnable)
1959 long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
1960 PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
1964 long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData );
1966 if ( pPrinter && bDoPrint )
1968 OSL_FAIL( "EndPage does not exist anymore" );
1971 return nCount;
1974 void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1975 sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
1977 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1978 long nLayoutSign = bLayoutRTL ? -1 : 1;
1980 // nPageNo is the page number within all sheets of one "start page" setting
1982 if ( bClearWin && bDoPrint )
1984 // must exactly fit to painting the frame in preview.cxx !!!
1986 Color aBackgroundColor( COL_WHITE );
1987 if ( bUseStyleColor )
1988 aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1990 pDev->SetMapMode(aOffsetMode);
1991 pDev->SetLineColor();
1992 pDev->SetFillColor(aBackgroundColor);
1993 pDev->DrawRect(Rectangle(Point(),
1994 Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
1995 (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
1999 // adjust aPageRect for left/right page
2001 Rectangle aTempRect = Rectangle( Point(), aPageSize );
2002 if (IsMirror(nPageNo))
2004 aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
2005 aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
2007 else
2009 aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
2010 aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
2013 if ( aAreaParam.bRepeatCol )
2014 if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol )
2015 nX1 = nRepeatEndCol + 1;
2016 sal_Bool bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol);
2017 if ( aAreaParam.bRepeatRow )
2018 if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow )
2019 nY1 = nRepeatEndRow + 1;
2020 sal_Bool bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow);
2022 // use new object hide flags in SdrPaintView
2023 if(pDrawView)
2025 pDrawView->setHideOle(!aTableParam.bObjects);
2026 pDrawView->setHideChart(!aTableParam.bCharts);
2027 pDrawView->setHideDraw(!aTableParam.bDrawings);
2028 pDrawView->setHideFormControl(!aTableParam.bDrawings);
2031 if ( pPrinter && bDoPrint )
2033 OSL_FAIL( "StartPage does not exist anymore" );
2036 // head and foot lines (without centering)
2038 if (aHdr.bEnable)
2040 long nHeaderY = aPageRect.Top()-aHdr.nHeight;
2041 PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
2043 if (aFtr.bEnable)
2045 long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
2046 PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
2049 // Position ( margins / centering )
2051 long nLeftSpace = aPageRect.Left(); // Document-Twips
2052 long nTopSpace = aPageRect.Top();
2053 if ( bCenterHor || bLayoutRTL )
2055 long nDataWidth = 0;
2056 SCCOL i;
2057 for (i=nX1; i<=nX2; i++)
2058 nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2059 if (bDoRepCol)
2060 for (i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2061 nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2062 if (aTableParam.bHeaders)
2063 nDataWidth += (long) PRINT_HEADER_WIDTH;
2064 if (pBorderItem)
2065 nDataWidth += pBorderItem->GetDistance(BOX_LINE_LEFT) +
2066 pBorderItem->GetDistance(BOX_LINE_RIGHT); //! Line width?
2067 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2068 nDataWidth += pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
2069 pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
2070 if ( bCenterHor )
2072 nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2; // LTR or RTL
2073 if (pBorderItem)
2074 nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft());
2076 else if ( bLayoutRTL )
2077 nLeftSpace += aPageRect.GetWidth() - nDataWidth; // align to the right edge of the page
2079 if ( bCenterVer )
2081 long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab);
2082 if (bDoRepRow)
2083 nDataHeight += pDoc->GetRowHeight( nRepeatStartRow,
2084 nRepeatEndRow, nPrintTab);
2085 if (aTableParam.bHeaders)
2086 nDataHeight += (long) PRINT_HEADER_HEIGHT;
2087 if (pBorderItem)
2088 nDataHeight += pBorderItem->GetDistance(BOX_LINE_TOP) +
2089 pBorderItem->GetDistance(BOX_LINE_BOTTOM); //! Line width?
2090 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2091 nDataHeight += pShadowItem->CalcShadowSpace(SHADOW_TOP) +
2092 pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
2093 nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2;
2094 if (pBorderItem)
2095 nTopSpace -= lcl_LineTotal(pBorderItem->GetTop());
2098 // calculate sizes of the elements for partitioning
2099 // (header, repeat, data)
2101 long nHeaderWidth = 0;
2102 long nHeaderHeight = 0;
2103 long nRepeatWidth = 0;
2104 long nRepeatHeight = 0;
2105 long nContentWidth = 0; // scaled - not the same as nDataWidth above
2106 long nContentHeight = 0;
2107 if (aTableParam.bHeaders)
2109 nHeaderWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
2110 nHeaderHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
2112 if (bDoRepCol)
2113 for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2114 nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2115 if (bDoRepRow)
2116 nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow,
2117 nRepeatEndRow, nPrintTab, nScaleY);
2118 for (SCCOL i=nX1; i<=nX2; i++)
2119 nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2120 nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab,
2121 nScaleY);
2123 // partition the page
2125 long nStartX = ((long) ( nLeftSpace * nScaleX ));
2126 long nStartY = ((long) ( nTopSpace * nScaleY ));
2127 long nInnerStartX = nStartX;
2128 long nInnerStartY = nStartY;
2129 if (pBorderItem)
2131 nInnerStartX += (long) ( ( lcl_LineTotal(pBorderItem->GetLeft()) +
2132 pBorderItem->GetDistance(BOX_LINE_LEFT) ) * nScaleX );
2133 nInnerStartY += (long) ( ( lcl_LineTotal(pBorderItem->GetTop()) +
2134 pBorderItem->GetDistance(BOX_LINE_TOP) ) * nScaleY );
2136 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2138 nInnerStartX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
2139 nInnerStartY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_TOP) * nScaleY );
2142 if ( bLayoutRTL )
2144 // arrange elements starting from the right edge
2145 nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth;
2147 // make rounding easier so the elements are really next to each other in preview
2148 Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode );
2149 long nOffsetOneX = aOffsetOnePixel.Width();
2150 nInnerStartX += nOffsetOneX / 2;
2153 long nFrameStartX = nInnerStartX;
2154 long nFrameStartY = nInnerStartY;
2156 long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign; // widths/heights are 0 if not used
2157 long nRepStartY = nInnerStartY + nHeaderHeight;
2158 long nDataX = nRepStartX + nRepeatWidth * nLayoutSign;
2159 long nDataY = nRepStartY + nRepeatHeight;
2160 long nEndX = nDataX + nContentWidth * nLayoutSign;
2161 long nEndY = nDataY + nContentHeight;
2162 long nFrameEndX = nEndX;
2163 long nFrameEndY = nEndY;
2165 if ( bLayoutRTL )
2167 // each element's start position is its left edge
2168 //! subtract one pixel less?
2169 nInnerStartX -= nHeaderWidth; // used for header
2170 nRepStartX -= nRepeatWidth;
2171 nDataX -= nContentWidth;
2173 // continue right of the main elements again
2174 nEndX += nHeaderWidth + nRepeatWidth + nContentWidth;
2177 // Page frame / background
2179 //! adjust nEndX/Y
2181 long nBorderEndX = nEndX;
2182 long nBorderEndY = nEndY;
2183 if (pBorderItem)
2185 nBorderEndX += (long) ( ( lcl_LineTotal(pBorderItem->GetRight()) +
2186 pBorderItem->GetDistance(BOX_LINE_RIGHT) ) * nScaleX );
2187 nBorderEndY += (long) ( ( lcl_LineTotal(pBorderItem->GetBottom()) +
2188 pBorderItem->GetDistance(BOX_LINE_BOTTOM) ) * nScaleY );
2190 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2192 nBorderEndX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
2193 nBorderEndY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
2196 if ( bDoPrint )
2198 pDev->SetMapMode( aOffsetMode );
2199 DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY,
2200 pBorderItem, pBackgroundItem, pShadowItem );
2202 pDev->SetMapMode( aTwipMode );
2205 pDev->SetMapMode( aOffsetMode );
2207 // Output repeating rows/columns
2209 if (bDoRepCol && bDoRepRow)
2211 if ( bDoPrint )
2212 PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2213 nRepStartX,nRepStartY, sal_True,sal_True,false,false );
2214 if ( pLocationData )
2215 LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2216 nRepStartX,nRepStartY, sal_True,sal_True, *pLocationData );
2218 if (bDoRepCol)
2220 if ( bDoPrint )
2221 PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY,
2222 sal_True,!bDoRepRow,false,sal_True );
2223 if ( pLocationData )
2224 LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, sal_True,false, *pLocationData );
2226 if (bDoRepRow)
2228 if ( bDoPrint )
2229 PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY,
2230 !bDoRepCol,sal_True,sal_True,false );
2231 if ( pLocationData )
2232 LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, false,sal_True, *pLocationData );
2235 // output data
2237 if ( bDoPrint )
2238 PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow,sal_True,sal_True );
2239 if ( pLocationData )
2240 LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, false,false, *pLocationData );
2242 // output column/row headers
2243 // after data (throug probably shadow)
2245 Color aGridColor( COL_BLACK );
2246 if ( bUseStyleColor )
2247 aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2249 if (aTableParam.bHeaders)
2251 if ( bDoPrint )
2253 pDev->SetLineColor( aGridColor );
2254 pDev->SetFillColor();
2255 pDev->SetMapMode(aOffsetMode);
2258 ScPatternAttr aPattern( pDoc->GetPool() );
2259 Font aFont;
2260 ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
2261 aPattern.GetFont( aFont, eColorMode, pDev );
2262 pDev->SetFont( aFont );
2264 if (bDoRepCol)
2266 if ( bDoPrint )
2267 PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY );
2268 if ( pLocationData )
2269 LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, sal_True, *pLocationData );
2271 if ( bDoPrint )
2272 PrintColHdr( nX1,nX2, nDataX,nInnerStartY );
2273 if ( pLocationData )
2274 LocateColHdr( nX1,nX2, nDataX,nInnerStartY, false, *pLocationData );
2275 if (bDoRepRow)
2277 if ( bDoPrint )
2278 PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY );
2279 if ( pLocationData )
2280 LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, sal_True, *pLocationData );
2282 if ( bDoPrint )
2283 PrintRowHdr( nY1,nY2, nInnerStartX,nDataY );
2284 if ( pLocationData )
2285 LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, false, *pLocationData );
2288 // simple frame
2290 if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) )
2292 Size aOnePixel = pDev->PixelToLogic(Size(1,1));
2293 long nOneX = aOnePixel.Width();
2294 long nOneY = aOnePixel.Height();
2296 long nLeftX = nFrameStartX;
2297 long nTopY = nFrameStartY - nOneY;
2298 long nRightX = nFrameEndX;
2299 long nBottomY = nFrameEndY - nOneY;
2300 if ( !bLayoutRTL )
2302 nLeftX -= nOneX;
2303 nRightX -= nOneX;
2305 pDev->SetMapMode(aOffsetMode);
2306 pDev->SetLineColor( aGridColor );
2307 pDev->SetFillColor();
2308 pDev->DrawRect( Rectangle( nLeftX, nTopY, nRightX, nBottomY ) );
2309 // nEndX/Y without frame-adaption
2312 if ( pPrinter && bDoPrint )
2314 OSL_FAIL( "EndPage does not exist anymore" );
2317 aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab );
2318 bSourceRangeValid = sal_True;
2321 void ScPrintFunc::SetOffset( const Point& rOfs )
2323 aSrcOffset = rOfs;
2326 void ScPrintFunc::SetManualZoom( sal_uInt16 nNewZoom )
2328 nManualZoom = nNewZoom;
2331 void ScPrintFunc::SetClearFlag( sal_Bool bFlag )
2333 bClearWin = bFlag;
2336 void ScPrintFunc::SetUseStyleColor( sal_Bool bFlag )
2338 bUseStyleColor = bFlag;
2339 if (pEditEngine)
2340 pEditEngine->EnableAutoColor( bUseStyleColor );
2343 void ScPrintFunc::SetRenderFlag( sal_Bool bFlag )
2345 bIsRender = bFlag; // set when using XRenderable (PDF)
2348 void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects()
2350 aTableParam.bCellContent = false;
2351 aTableParam.bNotes = false;
2352 aTableParam.bGrid = false;
2353 aTableParam.bHeaders = false;
2354 aTableParam.bFormulas = false;
2355 aTableParam.bNullVals = false;
2359 // UpdatePages is only called from outside to set the breaks correctly for viewing
2360 // - always without UserArea
2363 sal_Bool ScPrintFunc::UpdatePages()
2365 if (!pParamSet)
2366 return false;
2368 // Zoom
2370 nZoom = 100;
2371 if (aTableParam.bScalePageNum || aTableParam.bScaleTo)
2372 nZoom = ZOOM_MIN; // correct for breaks
2373 else if (aTableParam.bScaleAll)
2375 nZoom = aTableParam.nScaleAll;
2376 if ( nZoom <= ZOOM_MIN )
2377 nZoom = ZOOM_MIN;
2380 OUString aName = pDoc->GetPageStyle( nPrintTab );
2381 SCTAB nTabCount = pDoc->GetTableCount();
2382 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
2383 if ( nTab==nPrintTab || pDoc->GetPageStyle(nTab)==aName )
2385 // Repeating rows/columns
2386 pDoc->SetRepeatArea( nTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2388 // set breaks
2389 ResetBreaks(nTab);
2390 pDocShell->PostPaint(0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID);
2393 return sal_True;
2396 long ScPrintFunc::CountPages() // sets also nPagesX, nPagesY
2398 sal_Bool bAreaOk = false;
2400 if (pDoc->HasTable( nPrintTab ))
2402 if (aAreaParam.bPrintArea) // Specify print area?
2404 if ( bPrintCurrentTable )
2406 ScRange& rRange = aAreaParam.aPrintArea;
2408 // Here, no comparison of the tables any more. Area is always valid for this table
2409 // If comparison should be done here, the table of print ranges must be adjusted
2410 // when inserting tables etc.!
2412 nStartCol = rRange.aStart.Col();
2413 nStartRow = rRange.aStart.Row();
2414 nEndCol = rRange.aEnd .Col();
2415 nEndRow = rRange.aEnd .Row();
2416 bAreaOk = AdjustPrintArea(false); // limit
2418 else
2419 bAreaOk = false;
2421 else // search from document
2422 bAreaOk = AdjustPrintArea(sal_True);
2425 if (bAreaOk)
2427 long nPages = 0;
2428 size_t nY;
2429 if (bMultiArea)
2431 sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
2432 for (sal_uInt16 i=0; i<nRCount; i++)
2434 CalcZoom(i);
2435 if ( aTableParam.bSkipEmpty )
2436 for (nY=0; nY<nPagesY; nY++)
2437 nPages += pPageRows[nY].CountVisible();
2438 else
2439 nPages += ((long) nPagesX) * nPagesY;
2440 if ( pPageData )
2441 FillPageData();
2444 else
2446 CalcZoom(RANGENO_NORANGE); // calculate Zoom
2447 if ( aTableParam.bSkipEmpty )
2448 for (nY=0; nY<nPagesY; nY++)
2449 nPages += pPageRows[nY].CountVisible();
2450 else
2451 nPages += ((long) nPagesX) * nPagesY;
2452 if ( pPageData )
2453 FillPageData();
2455 return nPages;
2457 else
2459 nPagesX = nPagesY = nTotalY = 0;
2460 return 0;
2464 long ScPrintFunc::CountNotePages()
2466 if ( !aTableParam.bNotes || !bPrintCurrentTable )
2467 return 0;
2469 long nCount=0;
2471 sal_Bool bError = false;
2472 if (!aAreaParam.bPrintArea)
2473 bError = !AdjustPrintArea(sal_True); // completely search in Doc
2475 sal_uInt16 nRepeats = 1; // how often go through it ?
2476 if (bMultiArea)
2477 nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2478 if (bError)
2479 nRepeats = 0;
2481 for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2483 sal_Bool bDoThis = sal_True;
2484 if (bMultiArea) // go through all Areas
2486 const ScRange* pThisRange = pDoc->GetPrintRange( nPrintTab, nStep );
2487 if ( pThisRange )
2489 nStartCol = pThisRange->aStart.Col();
2490 nStartRow = pThisRange->aStart.Row();
2491 nEndCol = pThisRange->aEnd .Col();
2492 nEndRow = pThisRange->aEnd .Row();
2493 bDoThis = AdjustPrintArea(false);
2497 if (bDoThis)
2499 ScNotes::const_iterator itr = pDoc->GetNotes(nPrintTab)->begin();
2500 ScNotes::const_iterator itrEnd = pDoc->GetNotes(nPrintTab)->end();
2501 for (; itr != itrEnd; ++itr)
2503 SCCOL nCol = itr->first.first;
2504 SCROW nRow = itr->first.second;
2505 if (nCol > nEndCol || nRow > nEndRow)
2506 continue;
2508 if (nCol < nStartCol || nRow < nStartRow)
2509 continue;
2511 aNotePosList.push_back( ScAddress( nCol, nRow, nPrintTab ) );
2512 ++nCount;
2517 long nPages = 0;
2518 long nNoteNr = 0;
2519 long nNoteAdd;
2522 nNoteAdd = PrintNotes( nPages, nNoteNr, false, NULL );
2523 if (nNoteAdd)
2525 nNoteNr += nNoteAdd;
2526 ++nPages;
2529 while (nNoteAdd);
2531 return nPages;
2534 void ScPrintFunc::InitModes() // set MapModes from nZoom etc.
2536 aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom );
2538 long nEffZoom = nZoom * (long) nManualZoom;
2539 nScaleX = nScaleY = HMM_PER_TWIPS; // output in 1/100 mm
2541 Fraction aZoomFract( nEffZoom,10000 );
2542 Fraction aHorFract = aZoomFract;
2544 if ( !pPrinter && !bIsRender ) // adjust scale for preview
2546 double nFact = pDocShell->GetOutputFactor();
2547 aHorFract = Fraction( (long)( nEffZoom / nFact ), 10000 );
2550 aLogicMode = MapMode( MAP_100TH_MM, Point(), aHorFract, aZoomFract );
2552 Point aLogicOfs( -aOffset.X(), -aOffset.Y() );
2553 aOffsetMode = MapMode( MAP_100TH_MM, aLogicOfs, aHorFract, aZoomFract );
2555 Point aTwipsOfs( (long) ( -aOffset.X() / nScaleX + 0.5 ), (long) ( -aOffset.Y() / nScaleY + 0.5 ) );
2556 aTwipMode = MapMode( MAP_TWIP, aTwipsOfs, aHorFract, aZoomFract );
2559 //--------------------------------------------------------------------
2561 void ScPrintFunc::ApplyPrintSettings()
2563 if ( pPrinter )
2566 // Configure Printer to Printing
2569 Size aEnumSize = aPageSize;
2572 pPrinter->SetOrientation( bLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT );
2573 if ( bLandscape )
2575 // landscape is always interpreted as a rotation by 90 degrees !
2576 // this leads to non WYSIWIG but at least it prints!
2577 // #i21775#
2578 long nTemp = aEnumSize.Width();
2579 aEnumSize.Width() = aEnumSize.Height();
2580 aEnumSize.Height() = nTemp;
2582 Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, sal_True );
2583 sal_uInt16 nPaperBin = ((const SvxPaperBinItem&)pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue();
2585 pPrinter->SetPaper( ePaper );
2586 if ( PAPER_USER == ePaper )
2588 MapMode aPrinterMode = pPrinter->GetMapMode();
2589 MapMode aLocalMode( MAP_TWIP );
2590 pPrinter->SetMapMode( aLocalMode );
2591 pPrinter->SetPaperSizeUser( aEnumSize );
2592 pPrinter->SetMapMode( aPrinterMode );
2595 pPrinter->SetPaperBin( nPaperBin );
2599 //--------------------------------------------------------------------
2600 // rPageRanges = range for all tables
2601 // nStartPage = rPageRanges starts at nStartPage
2602 // nDisplayStart = continious number for displaying the page number
2604 long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges,
2605 long nStartPage, long nDisplayStart, bool bDoPrint,
2606 ScPreviewLocationData* pLocationData )
2608 OSL_ENSURE(pDev,"Device == NULL");
2609 if (!pParamSet)
2610 return 0;
2612 if ( pPrinter && bDoPrint )
2613 ApplyPrintSettings();
2615 //--------------------------------------------------------------------
2617 InitModes();
2618 if ( pLocationData )
2620 pLocationData->SetCellMapMode( aOffsetMode );
2621 pLocationData->SetPrintTab( nPrintTab );
2624 MakeTableString();
2626 //--------------------------------------------------------------------
2628 long nPageNo = 0;
2629 long nPrinted = 0;
2630 long nEndPage = rPageRanges.GetTotalRange().Max();
2632 sal_uInt16 nRepeats = 1;
2633 if (bMultiArea)
2634 nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2635 for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2637 if (bMultiArea) // replace area
2639 CalcZoom(nStep); // also sets nStartCol etc. new
2640 InitModes();
2643 SCCOL nX1;
2644 SCROW nY1;
2645 SCCOL nX2;
2646 SCROW nY2;
2647 size_t nCountX;
2648 size_t nCountY;
2650 if (aTableParam.bTopDown) // top-bottom
2652 nX1 = nStartCol;
2653 for (nCountX=0; nCountX<nPagesX; nCountX++)
2655 nX2 = pPageEndX[nCountX];
2656 for (nCountY=0; nCountY<nPagesY; nCountY++)
2658 nY1 = pPageRows[nCountY].GetStartRow();
2659 nY2 = pPageRows[nCountY].GetEndRow();
2660 if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
2662 if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2664 PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2665 bDoPrint, pLocationData );
2666 ++nPrinted;
2668 ++nPageNo;
2671 nX1 = nX2 + 1;
2674 else // left to right
2676 for (nCountY=0; nCountY<nPagesY; nCountY++)
2678 nY1 = pPageRows[nCountY].GetStartRow();
2679 nY2 = pPageRows[nCountY].GetEndRow();
2680 nX1 = nStartCol;
2681 for (nCountX=0; nCountX<nPagesX; nCountX++)
2683 nX2 = pPageEndX[nCountX];
2684 if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
2686 if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2688 PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2689 bDoPrint, pLocationData );
2690 ++nPrinted;
2692 ++nPageNo;
2694 nX1 = nX2 + 1;
2700 aFieldData.aTabName = ScGlobal::GetRscString( STR_NOTES );
2702 long nNoteNr = 0;
2703 long nNoteAdd;
2706 if ( nPageNo+nStartPage <= nEndPage )
2708 sal_Bool bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 );
2709 nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected,
2710 ( bPageSelected ? pLocationData : NULL ) );
2711 if ( nNoteAdd )
2713 nNoteNr += nNoteAdd;
2714 if (bPageSelected)
2716 ++nPrinted;
2717 bSourceRangeValid = false; // last page was no cell range
2719 ++nPageNo;
2722 else
2723 nNoteAdd = 0;
2725 while (nNoteAdd);
2727 if ( bMultiArea )
2728 ResetBreaks(nPrintTab); //breaks correct for displaying
2730 return nPrinted;
2733 void ScPrintFunc::CalcZoom( sal_uInt16 nRangeNo ) // calculate zoom
2735 sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
2736 const ScRange* pThisRange = NULL;
2737 if ( nRangeNo != RANGENO_NORANGE || nRangeNo < nRCount )
2738 pThisRange = pDoc->GetPrintRange( nPrintTab, nRangeNo );
2739 if ( pThisRange )
2741 nStartCol = pThisRange->aStart.Col();
2742 nStartRow = pThisRange->aStart.Row();
2743 nEndCol = pThisRange->aEnd .Col();
2744 nEndRow = pThisRange->aEnd .Row();
2747 if (!AdjustPrintArea(false)) // empty
2749 nZoom = 100;
2750 nPagesX = nPagesY = nTotalY = 0;
2751 return;
2754 pDoc->SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2756 if (aTableParam.bScalePageNum)
2758 nZoom = 100;
2759 sal_uInt16 nPagesToFit = aTableParam.nScalePageNum;
2761 sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2762 while (true)
2764 if (nZoom <= ZOOM_MIN)
2765 break;
2767 CalcPages();
2768 bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit);
2770 if (bFitsPage)
2772 if (nZoom == 100)
2773 // If it fits at 100 %, it's good enough for me.
2774 break;
2776 nLastFitZoom = nZoom;
2777 nZoom = (nLastNonFitZoom + nZoom) / 2;
2779 if (nLastFitZoom == nZoom)
2780 // It converged. Use this zoom level.
2781 break;
2783 else
2785 if (nZoom - nLastFitZoom <= 1)
2787 nZoom = nLastFitZoom;
2788 CalcPages();
2789 break;
2792 nLastNonFitZoom = nZoom;
2793 nZoom = (nLastFitZoom + nZoom) / 2;
2797 else if (aTableParam.bScaleTo)
2799 nZoom = 100;
2800 sal_uInt16 nW = aTableParam.nScaleWidth;
2801 sal_uInt16 nH = aTableParam.nScaleHeight;
2803 sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2804 while (true)
2806 if (nZoom <= ZOOM_MIN)
2807 break;
2809 CalcPages();
2810 bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH)));
2812 if (bFitsPage)
2814 if (nZoom == 100)
2815 // If it fits at 100 %, it's good enough for me.
2816 break;
2818 nLastFitZoom = nZoom;
2819 nZoom = (nLastNonFitZoom + nZoom) / 2;
2821 if (nLastFitZoom == nZoom)
2822 // It converged. Use this zoom level.
2823 break;
2825 else
2827 if (nZoom - nLastFitZoom <= 1)
2829 nZoom = nLastFitZoom;
2830 CalcPages();
2831 break;
2834 nLastNonFitZoom = nZoom;
2835 nZoom = (nLastFitZoom + nZoom) / 2;
2839 else if (aTableParam.bScaleAll)
2841 nZoom = aTableParam.nScaleAll;
2842 if ( nZoom <= ZOOM_MIN )
2843 nZoom = ZOOM_MIN;
2844 CalcPages();
2846 else
2848 OSL_ENSURE( aTableParam.bScaleNone, "kein Scale-Flag gesetzt" );
2849 nZoom = 100;
2850 CalcPages();
2854 Size ScPrintFunc::GetDocPageSize()
2856 // Adjust height of head/foot line
2858 InitModes(); // initialize aTwipMode from nZoom
2859 pDev->SetMapMode( aTwipMode ); // head/foot line in Twips
2860 UpdateHFHeight( aHdr );
2861 UpdateHFHeight( aFtr );
2863 // Page size in Document-Twips
2864 // Calculating Left / Right also in PrintPage
2866 aPageRect = Rectangle( Point(), aPageSize );
2867 aPageRect.Left() = ( aPageRect.Left() + nLeftMargin ) * 100 / nZoom;
2868 aPageRect.Right() = ( aPageRect.Right() - nRightMargin ) * 100 / nZoom;
2869 aPageRect.Top() = ( aPageRect.Top() + nTopMargin ) * 100 / nZoom + aHdr.nHeight;
2870 aPageRect.Bottom() = ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight;
2872 Size aDocPageSize = aPageRect.GetSize();
2873 if (aTableParam.bHeaders)
2875 aDocPageSize.Width() -= (long) PRINT_HEADER_WIDTH;
2876 aDocPageSize.Height() -= (long) PRINT_HEADER_HEIGHT;
2878 if (pBorderItem)
2880 aDocPageSize.Width() -= lcl_LineTotal(pBorderItem->GetLeft()) +
2881 lcl_LineTotal(pBorderItem->GetRight()) +
2882 pBorderItem->GetDistance(BOX_LINE_LEFT) +
2883 pBorderItem->GetDistance(BOX_LINE_RIGHT);
2884 aDocPageSize.Height() -= lcl_LineTotal(pBorderItem->GetTop()) +
2885 lcl_LineTotal(pBorderItem->GetBottom()) +
2886 pBorderItem->GetDistance(BOX_LINE_TOP) +
2887 pBorderItem->GetDistance(BOX_LINE_BOTTOM);
2889 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2891 aDocPageSize.Width() -= pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
2892 pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
2893 aDocPageSize.Height() -= pShadowItem->CalcShadowSpace(SHADOW_TOP) +
2894 pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
2896 return aDocPageSize;
2899 void ScPrintFunc::ResetBreaks( SCTAB nTab ) // Set Breaks correctly for view
2901 pDoc->SetPageSize( nTab, GetDocPageSize() );
2902 pDoc->UpdatePageBreaks( nTab, NULL );
2905 static void lcl_SetHidden( ScDocument* pDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry,
2906 SCCOL nStartCol, const SCCOL* pPageEndX )
2908 size_t nPagesX = rPageRowEntry.GetPagesX();
2909 SCROW nStartRow = rPageRowEntry.GetStartRow();
2910 SCROW nEndRow = rPageRowEntry.GetEndRow();
2912 sal_Bool bLeftIsEmpty = false;
2913 ScRange aTempRange;
2914 Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 );
2916 for (size_t i=0; i<nPagesX; i++)
2918 SCCOL nEndCol = pPageEndX[i];
2919 if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow,
2920 bLeftIsEmpty, &aTempRange, &aTempRect ) )
2922 rPageRowEntry.SetHidden(i);
2923 bLeftIsEmpty = sal_True;
2925 else
2926 bLeftIsEmpty = false;
2928 nStartCol = nEndCol+1;
2932 void ScPrintFunc::CalcPages() // calculates aPageRect and pages from nZoom
2934 if (!pPageEndX) pPageEndX = new SCCOL[MAXCOL+1];
2935 if (!pPageEndY) pPageEndY = new SCROW[MAXROW+1];
2936 if (!pPageRows) pPageRows = new ScPageRowEntry[MAXROW+1]; //! count before !!!!
2938 pDoc->SetPageSize( nPrintTab, GetDocPageSize() );
2939 if (aAreaParam.bPrintArea)
2941 ScRange aRange( nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab );
2942 pDoc->UpdatePageBreaks( nPrintTab, &aRange );
2944 else
2945 pDoc->UpdatePageBreaks( nPrintTab, NULL ); // else, end is marked
2948 // Page alignment/splitting after breaks in Col/RowFlags
2949 // Of several breaks in a hidden area, only one counts.
2952 nPagesX = 0;
2953 nPagesY = 0;
2954 nTotalY = 0;
2956 bool bVisCol = false;
2957 for (SCCOL i=nStartCol; i<=nEndCol; i++)
2959 bool bHidden = pDoc->ColHidden(i, nPrintTab);
2960 bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE);
2961 if ( i>nStartCol && bVisCol && bPageBreak )
2963 pPageEndX[nPagesX] = i-1;
2964 ++nPagesX;
2965 bVisCol = false;
2967 if (!bHidden)
2968 bVisCol = true;
2970 if (bVisCol) // also at the end, no empty pages
2972 pPageEndX[nPagesX] = nEndCol;
2973 ++nPagesX;
2976 bool bVisRow = false;
2977 SCROW nPageStartRow = nStartRow;
2978 SCROW nLastVisibleRow = -1;
2980 ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab));
2981 SCROW nNextPageBreak = pRowBreakIter->first();
2982 while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow)
2983 // Skip until the page break position is at the start row or greater.
2984 nNextPageBreak = pRowBreakIter->next();
2986 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
2988 bool bPageBreak = (nNextPageBreak == nRow);
2989 if (bPageBreak)
2990 nNextPageBreak = pRowBreakIter->next();
2992 if (nRow > nStartRow && bVisRow && bPageBreak )
2994 pPageEndY[nTotalY] = nRow-1;
2995 ++nTotalY;
2997 if ( !aTableParam.bSkipEmpty ||
2998 !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) )
3000 pPageRows[nPagesY].SetStartRow( nPageStartRow );
3001 pPageRows[nPagesY].SetEndRow( nRow-1 );
3002 pPageRows[nPagesY].SetPagesX( nPagesX );
3003 if (aTableParam.bSkipEmpty)
3004 lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX );
3005 ++nPagesY;
3008 nPageStartRow = nRow;
3009 bVisRow = false;
3012 if (nRow <= nLastVisibleRow)
3014 // This row is still visible. Don't bother calling RowHidden() to
3015 // find out, for speed optimization.
3016 bVisRow = true;
3017 continue;
3020 SCROW nLastRow = -1;
3021 if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow))
3023 bVisRow = true;
3024 nLastVisibleRow = nLastRow;
3026 else
3027 // skip all hidden rows.
3028 nRow = nLastRow;
3031 if (bVisRow)
3033 pPageEndY[nTotalY] = nEndRow;
3034 ++nTotalY;
3036 if ( !aTableParam.bSkipEmpty ||
3037 !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) )
3039 pPageRows[nPagesY].SetStartRow( nPageStartRow );
3040 pPageRows[nPagesY].SetEndRow( nEndRow );
3041 pPageRows[nPagesY].SetPagesX( nPagesX );
3042 if (aTableParam.bSkipEmpty)
3043 lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX );
3044 ++nPagesY;
3049 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */