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