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