/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

// INCLUDE ---------------------------------------------------------------

#include "scitems.hxx"
#include <editeng/eeitem.hxx>

#include "printfun.hxx"

#include <svx/svxids.hrc>
#include <editeng/adjitem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/brshitem.hxx>
#include <svtools/colorcfg.hxx>
#include <editeng/editstat.hxx>		// EE_CNTRL_RTFSTYLESHEETS
#include <svx/fmview.hxx>
#include <editeng/frmdiritem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/paperinf.hxx>
#include <editeng/pbinitem.hxx>
#include <editeng/shaditem.hxx>
#include <editeng/sizeitem.hxx>
#include <svx/svdpagv.hxx>
#include <editeng/ulspitem.hxx>
#include <sfx2/app.hxx>
#include <sfx2/printer.hxx>
#include <tools/multisel.hxx>
#include <sfx2/docfile.hxx>
#include <tools/urlobj.hxx>
#include <svx/xoutbmp.hxx>

#include "editutil.hxx"
#include "docsh.hxx"
#include "output.hxx"
#include "viewdata.hxx"
#include "viewopti.hxx"
#include "stlpool.hxx"
#include "pagepar.hxx"
#include "attrib.hxx"
#include "patattr.hxx"
#include "docpool.hxx"
#include "dociter.hxx"
#include "cell.hxx"
#include "drawutil.hxx"
#include "globstr.hrc"
#include "scresid.hxx"
#include "sc.hrc"
#include "pagedata.hxx"
#include "printopt.hxx"
#include "prevloc.hxx"
#include "scmod.hxx"
#include "drwlayer.hxx"
#include "fillinfo.hxx"
#include "postit.hxx"

#include <vcl/lineinfo.hxx>
#include <tools/pstm.hxx>

#include <boost/scoped_ptr.hpp>

#define ZOOM_MIN	10

#define GET_BOOL(set,which)   ((const SfxBoolItem&)(set)->Get((which))).GetValue()
#define GET_USHORT(set,which) ((const SfxUInt16Item&)(set)->Get((which))).GetValue()
#define GET_SHOW(set,which)   ( VOBJ_MODE_SHOW == ScVObjMode( ((const ScViewObjectModeItem&)(set)->Get((which))).GetValue()) )

//------------------------------------------------------------------------

ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r)
{
	nStartRow = r.nStartRow;
	nEndRow	  = r.nEndRow;
	nPagesX   = r.nPagesX;
	if (r.pHidden && nPagesX)
	{
		pHidden = new sal_Bool[nPagesX];
		memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
	}
	else
		pHidden = NULL;
}

const ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r)
{
	delete[] pHidden;

	nStartRow = r.nStartRow;
	nEndRow	  = r.nEndRow;
	nPagesX   = r.nPagesX;
	if (r.pHidden && nPagesX)
	{
		pHidden = new sal_Bool[nPagesX];
		memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
	}
	else
		pHidden = NULL;

	return *this;
}

void ScPageRowEntry::SetPagesX(size_t nNew)
{
	if (pHidden)
	{
		DBG_ERROR("SetPagesX nicht nach SetHidden");
		delete[] pHidden;
		pHidden = NULL;
	}
	nPagesX = nNew;
}

void ScPageRowEntry::SetHidden(size_t nX)
{
	if ( nX < nPagesX )
	{
		if ( nX+1 == nPagesX )	// letzte Seite?
			--nPagesX;
		else
		{
			if (!pHidden)
			{
				pHidden = new sal_Bool[nPagesX];
				memset( pHidden, sal_False, nPagesX * sizeof(sal_Bool) );
			}
			pHidden[nX] = sal_True;
		}
	}
}

sal_Bool ScPageRowEntry::IsHidden(size_t nX) const
{
	return nX>=nPagesX || ( pHidden && pHidden[nX] );		//! inline?
}

size_t ScPageRowEntry::CountVisible() const
{
	if ( pHidden )
	{
		size_t nVis = 0;
		for (size_t i=0; i<nPagesX; i++)
			if (!pHidden[i])
				++nVis;
		return nVis;
	}
	else
		return nPagesX;
}

//------------------------------------------------------------------------

long lcl_LineTotal(const SvxBorderLine* pLine)
{
	return pLine ? ( pLine->GetOutWidth() + pLine->GetInWidth() + pLine->GetDistance() ) : 0;
}

void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
{
    pDocShell->UpdatePendingRowHeights( nPrintTab );
	pDoc = pDocShell->GetDocument();

	SfxPrinter* pDocPrinter = pDoc->GetPrinter();	// auch fuer Preview den Drucker nehmen
	if (pDocPrinter)
		aOldPrinterMode = pDocPrinter->GetMapMode();

	//	einheitlicher MapMode ueber alle Aufrufe (z.B. Repaint !!!),
	//	weil die EditEngine sonst unterschiedliche Texthoehen liefert
	pDev->SetMapMode(MAP_PIXEL);

	pBorderItem = NULL;
	pBackgroundItem = NULL;
	pShadowItem = NULL;

	pEditEngine = NULL;
	pEditDefaults = NULL;

	ScStyleSheetPool* pStylePool	= pDoc->GetStyleSheetPool();
	SfxStyleSheetBase* pStyleSheet  = pStylePool->Find(
											pDoc->GetPageStyle( nPrintTab ),
											SFX_STYLE_FAMILY_PAGE );
	if (pStyleSheet)
		pParamSet = &pStyleSheet->GetItemSet();
	else
	{
		DBG_ERROR("Seitenvorlage nicht gefunden" );
		pParamSet = NULL;
	}

	if (!bState)
		nZoom = 100;
	nManualZoom = 100;
	bClearWin = sal_False;
	bUseStyleColor = sal_False;
	bIsRender = sal_False;

	InitParam(pOptions);

	pPageData = NULL;		// wird nur zur Initialisierung gebraucht
}

ScPrintFunc::ScPrintFunc( ScDocShell* pShell, SfxPrinter* pNewPrinter, SCTAB nTab,
							long nPage, long nDocP, const ScRange* pArea,
							const ScPrintOptions* pOptions,
							ScPageBreakData* pData )
	:	pDocShell			( pShell ),
		pPrinter			( pNewPrinter ),
		pDrawView			( NULL ),
		nPrintTab			( nTab ),
		nPageStart			( nPage ),
		nDocPages			( nDocP ),
		pUserArea			( pArea ),
		bState				( sal_False ),
		bSourceRangeValid	( sal_False ),
		bPrintCurrentTable	( sal_False ),
		bMultiArea			( sal_False ),
		nTabPages			( 0 ),
		nTotalPages			( 0 ),
		pPageData			( pData )
{
	pDev = pPrinter;
	aSrcOffset = pPrinter->PixelToLogic( pPrinter->GetPageOffsetPixel(), MAP_100TH_MM );
	Construct( pOptions );
}

ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, SCTAB nTab,
							long nPage, long nDocP, const ScRange* pArea,
							const ScPrintOptions* pOptions )
	:	pDocShell			( pShell ),
		pPrinter			( NULL ),
		pDrawView			( NULL ),
		nPrintTab			( nTab ),
		nPageStart			( nPage ),
		nDocPages			( nDocP ),
		pUserArea			( pArea ),
		bState				( sal_False ),
		bSourceRangeValid	( sal_False ),
		bPrintCurrentTable	( sal_False ),
		bMultiArea			( sal_False ),
		nTabPages			( 0 ),
		nTotalPages			( 0 ),
		pPageData			( NULL )
{
	pDev = pOutDev;
	Construct( pOptions );
}

ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell,
							 const ScPrintState& rState, const ScPrintOptions* pOptions )
	:	pDocShell			( pShell ),
		pPrinter			( NULL ),
		pDrawView			( NULL ),
		pUserArea			( NULL ),
		bSourceRangeValid	( sal_False ),
		bPrintCurrentTable	( sal_False ),
		bMultiArea			( sal_False ),
		pPageData			( NULL )
{
	pDev = pOutDev;

	nPrintTab	= rState.nPrintTab;
	nStartCol	= rState.nStartCol;
	nStartRow	= rState.nStartRow;
	nEndCol		= rState.nEndCol;
	nEndRow		= rState.nEndRow;
	nZoom		= rState.nZoom;
	nPagesX		= rState.nPagesX;
	nPagesY		= rState.nPagesY;
	nTabPages	= rState.nTabPages;
	nTotalPages	= rState.nTotalPages;
	nPageStart	= rState.nPageStart;
	nDocPages	= rState.nDocPages;
	bState		= sal_True;

	Construct( pOptions );
}

void ScPrintFunc::GetPrintState( ScPrintState& rState )
{
	rState.nPrintTab	= nPrintTab;
	rState.nStartCol	= nStartCol;
	rState.nStartRow	= nStartRow;
	rState.nEndCol		= nEndCol;
	rState.nEndRow		= nEndRow;
	rState.nZoom		= nZoom;
	rState.nPagesX		= nPagesX;
	rState.nPagesY		= nPagesY;
	rState.nTabPages	= nTabPages;
	rState.nTotalPages	= nTotalPages;
	rState.nPageStart	= nPageStart;
	rState.nDocPages	= nDocPages;
}

sal_Bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const
{
	rRange = aLastSourceRange;
	return bSourceRangeValid;
}

void ScPrintFunc::FillPageData()
{
	if (pPageData)
	{
        sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
		ScPrintRangeData& rData = pPageData->GetData(nCount);		// hochzaehlen

		rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab,
										nEndCol, nEndRow, nPrintTab ) );
        // #123672#
        if(maPageEndX.empty())
        {
            OSL_ENSURE(false, "vector access error for maPageEndX (!)");
        }
        else
        {
            rData.SetPagesX( nPagesX, &maPageEndX[0]);
        }

        // #123672#
        if(maPageEndY.empty())
        {
            OSL_ENSURE(false, "vector access error for maPageEndY (!)");
        }
        else
        {
            rData.SetPagesY( nTotalY, &maPageEndY[0]);
        }

		//	Einstellungen
		rData.SetTopDown( aTableParam.bTopDown );
		rData.SetAutomatic( !aAreaParam.bPrintArea );
	}
}

ScPrintFunc::~ScPrintFunc()
{
	ScAddress* pTripel = (ScAddress*) aNotePosList.First();
	while (pTripel)
	{
		delete pTripel;
		pTripel = (ScAddress*) aNotePosList.Next();
	}
	aNotePosList.Clear();

	delete pEditDefaults;
	delete pEditEngine;

	//	Druckereinstellungen werden jetzt von aussen wiederhergestellt

	//	#64294# Fuer DrawingLayer/Charts muss der MapMode am Drucker (RefDevice) immer stimmen
	SfxPrinter* pDocPrinter = pDoc->GetPrinter();	// auch fuer Preview den Drucker nehmen
	if (pDocPrinter)
		pDocPrinter->SetMapMode(aOldPrinterMode);
}

void ScPrintFunc::SetDrawView( FmFormView* pNew )
{
	pDrawView = pNew;
}

void lcl_HidePrint( ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 )
{
    for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++)
	{
        RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY];
		for (SCCOL nX=nX1; nX<=nX2; nX++)
		{
			const CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1];
			if (!rCellInfo.bEmptyCellText)
				if (((const ScProtectionAttr&)rCellInfo.pPatternAttr->
							GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet)).GetHidePrint())
				{
					pThisRowInfo->pCellInfo[nX+1].pCell			 = NULL;
					pThisRowInfo->pCellInfo[nX+1].bEmptyCellText = sal_True;
				}
		}
	}
}

//
//			Ausgabe auf Device (static)
//
//		wird benutzt fuer:
//		-	Clipboard/Bitmap
//		-	Ole-Object (DocShell::Draw)
//		-	Vorschau bei Vorlagen

void ScPrintFunc::DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double /* nPrintFactor */,
							const Rectangle& rBound, ScViewData* pViewData, sal_Bool bMetaFile )
{
	//!	nPrintFactor auswerten !!!

	SCTAB nTab = 0;
	if (pViewData)
		nTab = pViewData->GetTabNo();

	sal_Bool bDoGrid, bNullVal, bFormula;
	ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
	SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
	if (pStyleSheet)
	{
		SfxItemSet& rSet = pStyleSheet->GetItemSet();
		bDoGrid  = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_GRID)).GetValue();
		bNullVal = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_NULLVALS)).GetValue();
		bFormula = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_FORMULAS)).GetValue();
	}
	else
	{
		const ScViewOptions& rOpt = pDoc->GetViewOptions();
		bDoGrid  = rOpt.GetOption(VOPT_GRID);
		bNullVal = rOpt.GetOption(VOPT_NULLVALS);
		bFormula = rOpt.GetOption(VOPT_FORMULAS);
	}

	MapMode aMode = pDev->GetMapMode();

	Rectangle aRect = rBound;

	if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top())
		aRect = Rectangle( Point(), pDev->GetOutputSize() );

	SCCOL nX1 = 0;
	SCROW nY1 = 0;
	SCCOL nX2 = OLE_STD_CELLS_X - 1;
	SCROW nY2 = OLE_STD_CELLS_Y - 1;
	if (bMetaFile)
	{
		ScRange aRange = pDoc->GetRange( nTab, rBound );
		nX1 = aRange.aStart.Col();
		nY1 = aRange.aStart.Row();
		nX2 = aRange.aEnd.Col();
		nY2 = aRange.aEnd.Row();
	}
	else if (pViewData)
	{
		ScSplitPos eWhich = pViewData->GetActivePart();
		ScHSplitPos eHWhich = WhichH(eWhich);
		ScVSplitPos eVWhich = WhichV(eWhich);
		nX1 = pViewData->GetPosX(eHWhich);
		nY1 = pViewData->GetPosY(eVWhich);
		nX2 = nX1 + pViewData->VisibleCellsX(eHWhich);
		if (nX2>nX1) --nX2;
		nY2 = nY1 + pViewData->VisibleCellsY(eVWhich);
		if (nY2>nY1) --nY2;
	}

	if (nX1 > MAXCOL) nX1 = MAXCOL;
	if (nX2 > MAXCOL) nX2 = MAXCOL;
	if (nY1 > MAXROW) nY1 = MAXROW;
	if (nY2 > MAXROW) nY2 = MAXROW;

	long nDevSizeX = aRect.Right()-aRect.Left()+1;
	long nDevSizeY = aRect.Bottom()-aRect.Top()+1;

	Rectangle aLines;
	ScRange aRange( nX1,nY1,nTab, nX2,nY2,nTab );
//    sal_Bool bAddLines = pDoc->HasLines( aRange, aLines );

	long nTwipsSizeX = 0;
	for (SCCOL i=nX1; i<=nX2; i++)
		nTwipsSizeX += pDoc->GetColWidth( i, nTab );
	long nTwipsSizeY = (long) pDoc->GetRowHeight( nY1, nY2, nTab );

	//	wenn keine Linien, dann trotzdem Platz fuer den Aussenrahmen (20 Twips = 1pt)
	//	(HasLines initalisiert aLines auf 0,0,0,0)
	nTwipsSizeX += aLines.Left() + Max( aLines.Right(), 20L );
	nTwipsSizeY += aLines.Top() +  Max( aLines.Bottom(), 20L );

	double nScaleX = (double) nDevSizeX / nTwipsSizeX;
	double nScaleY = (double) nDevSizeY / nTwipsSizeY;

							//!		Flag bei FillInfo uebergeben !!!!!
    ScRange aERange;
	sal_Bool bEmbed = pDoc->IsEmbedded();
	if (bEmbed)
	{
		pDoc->GetEmbedded(aERange);
		pDoc->ResetEmbedded();
	}

	//	Daten zusammenstellen

    ScTableInfo aTabInfo;
    pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
										nScaleX, nScaleY, sal_False, bFormula );
    lcl_HidePrint( aTabInfo, nX1, nX2 );

	if (bEmbed)
		pDoc->SetEmbedded(aERange);

/*	if (!bMetaFile)
		pDev->SetMapMode(MAP_PIXEL);
*/
	long nScrX = aRect.Left();
	long nScrY = aRect.Top();

	//	Wenn keine Linien, trotzdem Platz fuer Gitterlinien lassen
	//	(werden sonst abgeschnitten)
	long nAddX = (long)( aLines.Left() * nScaleX );
	nScrX += ( nAddX ? nAddX : 1 );
	long nAddY = (long)( aLines.Top() * nScaleY );
	nScrY += ( nAddY ? nAddY : 1 );

    ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nTab,
								nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
	aOutputData.SetMetaFileMode(bMetaFile);
	aOutputData.SetShowNullValues(bNullVal);
	aOutputData.SetShowFormulas(bFormula);

	// #114135#
	ScDrawLayer* pModel = pDoc->GetDrawLayer();
	FmFormView* pDrawView = NULL;

	if( pModel )
	{
		pDrawView = new FmFormView( pModel, pDev );
		pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
		pDrawView->SetPrintPreview( sal_True );
		aOutputData.SetDrawView( pDrawView );
	}

	//!	SetUseStyleColor ??

	if ( bMetaFile && pDev->GetOutDevType() == OUTDEV_VIRDEV )
		aOutputData.SetSnapPixel();

	Point aLogStart = pDev->PixelToLogic( Point(nScrX,nScrY), MAP_100TH_MM );
	long nLogStX = aLogStart.X();
	long nLogStY = aLogStart.Y();

	//!		nZoom fuer GetFont in OutputData ???

	if (!bMetaFile && pViewData)
		pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));

	// #i72502#
	const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
	aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);

	if (!bMetaFile && pViewData)
		pDev->SetMapMode(aMode);

	aOutputData.DrawBackground();

#ifdef OS2
	if (bMetaFile && !bDoGrid)
	{
					// unter OS2 fuer Metafiles gesamte Flaeche benutzen,
					// weil sonst die Groesse nicht erkannt wird
		pDev->SetLineColor();
		pDev->SetFillColor();
		pDev->DrawRect( Rectangle( nScrX,nScrY,
						nScrX+aOutputData.GetScrW(), nScrY+aOutputData.GetScrH() ) );
	}
#endif

	aOutputData.DrawShadow();
	aOutputData.DrawFrame();
	aOutputData.DrawStrings();

	if (!bMetaFile && pViewData)
		pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));

	aOutputData.DrawEdit(!bMetaFile);

	if (bDoGrid)
	{
		if (!bMetaFile && pViewData)
			pDev->SetMapMode(aMode);

		aOutputData.DrawGrid( sal_True, sal_False );	// keine Seitenumbrueche

		pDev->SetLineColor( COL_BLACK );

		Size aOne = pDev->PixelToLogic( Size(1,1) );
		if (bMetaFile)
			aOne = Size(1,1);	// compatible with DrawGrid
		long nRight = nScrX + aOutputData.GetScrW() - aOne.Width();
		long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height();

		sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );

		// extra line at the left edge for left-to-right, right for right-to-left
		if ( bLayoutRTL )
			pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) );
		else
			pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) );
		// extra line at the top in both cases
		pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) );
	}

	// #i72502#
	aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
	aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
	aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#

	// #114135#
	delete pDrawView;
}

//
//			Drucken
//

void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet )
{
	//	nDistance muss vorher unterschiedlich initalisiert sein

	if ( pHFSet == NULL )
	{
		rParam.bEnable	= sal_False;
		rParam.pBorder	= NULL;
		rParam.pBack	= NULL;
		rParam.pShadow	= NULL;
	}
	else
	{
		rParam.bEnable	= ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_ON)).GetValue();
		rParam.bDynamic	= ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_DYNAMIC)).GetValue();
		rParam.bShared	= ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_SHARED)).GetValue();
		rParam.nHeight	= ((const SvxSizeItem&) pHFSet->Get(ATTR_PAGE_SIZE)).GetSize().Height();
		const SvxLRSpaceItem* pHFLR = &(const SvxLRSpaceItem&) pHFSet->Get(ATTR_LRSPACE);
		long nTmp;
		nTmp = pHFLR->GetLeft();
		rParam.nLeft = nTmp < 0 ? 0 : sal_uInt16(nTmp);
		nTmp = pHFLR->GetRight();
		rParam.nRight = nTmp < 0 ? 0 : sal_uInt16(nTmp);
		rParam.pBorder	= (const SvxBoxItem*)   &pHFSet->Get(ATTR_BORDER);
		rParam.pBack	= (const SvxBrushItem*) &pHFSet->Get(ATTR_BACKGROUND);
		rParam.pShadow	= (const SvxShadowItem*)&pHFSet->Get(ATTR_SHADOW);;

//	jetzt doch wieder schon im Dialog:
//		rParam.nHeight += rParam.nDistance;				// nicht mehr im Dialog ???

		if (rParam.pBorder)
			rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
							  lcl_LineTotal( rParam.pBorder->GetBottom() );

		rParam.nManHeight = rParam.nHeight;
	}

	if (!rParam.bEnable)
		rParam.nHeight = 0;
}

//	bNew = TRUE:	benutzten Bereich aus dem Dokument suchen
//	bNew = FALSE:	nur ganze Zeilen/Spalten begrenzen

sal_Bool ScPrintFunc::AdjustPrintArea( sal_Bool bNew )
{
	SCCOL nOldEndCol = nEndCol;	// nur wichtig bei !bNew
	SCROW nOldEndRow = nEndRow;
	sal_Bool bChangeCol = sal_True;			// bei bNew werden beide angepasst
	sal_Bool bChangeRow = sal_True;

	sal_Bool bNotes = aTableParam.bNotes;
	if ( bNew )
	{
		nStartCol = 0;
		nStartRow = 0;
		if (!pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ))
			return sal_False;	// nix
	}
	else
	{
		sal_Bool bFound = sal_True;
		bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL );
		bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW );
        sal_Bool bForcedChangeRow = sal_False;

        // #i53558# Crop entire column of old row limit to real print area with
        // some fuzzyness.
        if (!bChangeRow && nStartRow == 0)
        {
            SCROW nPAEndRow;
            bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nPAEndRow, bNotes );
            // Say we don't want to print more than ~1000 empty rows, which are
            // about 14 pages intentionally left blank..
            const SCROW nFuzzy = 23*42;
            if (nPAEndRow + nFuzzy < nEndRow)
            {
                bForcedChangeRow = sal_True;
                nEndRow = nPAEndRow;
            }
            else
                bFound = sal_True;  // user seems to _want_ to print some empty rows
        }
        // TODO: in case we extend the number of columns we may have to do the
        // same for horizontal cropping.

		if ( bChangeCol && bChangeRow )
			bFound = pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes );
		else if ( bChangeCol )
			bFound = pDoc->GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol, bNotes );
		else if ( bChangeRow )
			bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes );

		if (!bFound)
			return sal_False;	// leer

        if (bForcedChangeRow)
            bChangeRow = sal_True;
	}

	pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab,
						sal_False, sal_True );		// kein Refresh, incl. Attrs

	if ( bChangeCol )
	{
		OutputDevice* pRefDev = pDoc->GetPrinter();		// auch fuer Preview den Drucker nehmen
		pRefDev->SetMapMode( MAP_PIXEL );				// wichtig fuer GetNeededSize

		pDoc->ExtendPrintArea( pRefDev,
							nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow );
		//	nEndCol wird veraendert
	}

	if ( nEndCol < MAXCOL && pDoc->HasAttrib(
					nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_RIGHT ) )
		++nEndCol;
	if ( nEndRow < MAXROW && pDoc->HasAttrib(
					nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_DOWN ) )
		++nEndRow;

	if (!bChangeCol) nEndCol = nOldEndCol;
	if (!bChangeRow) nEndRow = nOldEndRow;

	return sal_True;
}

long ScPrintFunc::TextHeight( const EditTextObject* pObject )
{
	if (!pObject)
		return 0;

//	pEditEngine->SetPageNo( nTotalPages );
	pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False );

	return (long) pEditEngine->GetTextHeight();
}

//	nZoom muss gesetzt sein !!!
//	und der entsprechende Twip-MapMode eingestellt

void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam )
{
	DBG_ASSERT( aPageSize.Width(), "UpdateHFHeight ohne aPageSize");

	if (rParam.bEnable && rParam.bDynamic)
	{
		//	nHeight aus Inhalten berechnen

		MakeEditEngine();
		long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin -
								rParam.nLeft - rParam.nRight ) * 100 / nZoom;
		if (rParam.pBorder)
			nPaperWidth -= ( rParam.pBorder->GetDistance(BOX_LINE_LEFT) +
							 rParam.pBorder->GetDistance(BOX_LINE_RIGHT) +
							 lcl_LineTotal(rParam.pBorder->GetLeft()) +
							 lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom;

		if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
			nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SHADOW_LEFT) +
							 rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT) ) * 100L / nZoom;

		pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) );

		long nMaxHeight = 0;
		if ( rParam.pLeft )
		{
			nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) );
			nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) );
			nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) );
		}
		if ( rParam.pRight )
		{
			nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) );
			nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) );
			nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) );
		}

		rParam.nHeight = nMaxHeight + rParam.nDistance;
		if (rParam.pBorder)
			rParam.nHeight += rParam.pBorder->GetDistance(BOX_LINE_TOP) +
							  rParam.pBorder->GetDistance(BOX_LINE_BOTTOM) +
							  lcl_LineTotal( rParam.pBorder->GetTop() ) +
							  lcl_LineTotal( rParam.pBorder->GetBottom() );
		if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
			rParam.nHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
							  rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);

		if (rParam.nHeight < rParam.nManHeight)
			rParam.nHeight = rParam.nManHeight;			// eingestelltes Minimum
	}
}

void ScPrintFunc::InitParam( const ScPrintOptions* pOptions )
{
	if (!pParamSet)
		return;

								// TabPage "Seite"
	const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &pParamSet->Get( ATTR_LRSPACE );
	long nTmp;
	nTmp = pLRItem->GetLeft();
	nLeftMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
	nTmp = pLRItem->GetRight();
	nRightMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
	const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &pParamSet->Get( ATTR_ULSPACE );
	nTopMargin    = pULItem->GetUpper();
	nBottomMargin = pULItem->GetLower();

	const SvxPageItem* pPageItem = (const SvxPageItem*) &pParamSet->Get( ATTR_PAGE );
	nPageUsage			= pPageItem->GetPageUsage();
	bLandscape			= pPageItem->IsLandscape();
	aFieldData.eNumType	= pPageItem->GetNumType();

	bCenterHor = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_HORCENTER)).GetValue();
	bCenterVer = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_VERCENTER)).GetValue();

	aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
	if ( !aPageSize.Width() || !aPageSize.Height() )
	{
		DBG_ERROR("PageSize Null ?!?!?");
		aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
	}

	pBorderItem		= (const SvxBoxItem*)    &pParamSet->Get(ATTR_BORDER);
	pBackgroundItem	= (const SvxBrushItem*)	 &pParamSet->Get(ATTR_BACKGROUND);
	pShadowItem		= (const SvxShadowItem*) &pParamSet->Get(ATTR_SHADOW);

								// TabPage "Kopfzeile"

	aHdr.pLeft		= (const ScPageHFItem*)	&pParamSet->Get(ATTR_PAGE_HEADERLEFT);		// Inhalt
	aHdr.pRight		= (const ScPageHFItem*)	&pParamSet->Get(ATTR_PAGE_HEADERRIGHT);

	const SvxSetItem* pHeaderSetItem;
	const SfxItemSet* pHeaderSet = NULL;
	if ( pParamSet->GetItemState( ATTR_PAGE_HEADERSET, sal_False,
							(const SfxPoolItem**)&pHeaderSetItem ) == SFX_ITEM_SET )
	{
		pHeaderSet = &pHeaderSetItem->GetItemSet();
														// Kopfzeile hat unteren Abstand
		aHdr.nDistance	= ((const SvxULSpaceItem&) pHeaderSet->Get(ATTR_ULSPACE)).GetLower();
	}
	lcl_FillHFParam( aHdr, pHeaderSet );

								// TabPage "Fusszeile"

	aFtr.pLeft		= (const ScPageHFItem*)	&pParamSet->Get(ATTR_PAGE_FOOTERLEFT);		// Inhalt
	aFtr.pRight		= (const ScPageHFItem*)	&pParamSet->Get(ATTR_PAGE_FOOTERRIGHT);

	const SvxSetItem* pFooterSetItem;
	const SfxItemSet* pFooterSet = NULL;
	if ( pParamSet->GetItemState( ATTR_PAGE_FOOTERSET, sal_False,
							(const SfxPoolItem**)&pFooterSetItem ) == SFX_ITEM_SET )
	{
		pFooterSet = &pFooterSetItem->GetItemSet();
														// Fusszeile hat oberen Abstand
		aFtr.nDistance	= ((const SvxULSpaceItem&) pFooterSet->Get(ATTR_ULSPACE)).GetUpper();
	}
	lcl_FillHFParam( aFtr, pFooterSet );

	//------------------------------------------------------
	// Table-/Area-Params aus einzelnen Items zusammenbauen:
	//------------------------------------------------------
	// TabPage "Tabelle"

    const SfxUInt16Item*     pScaleItem          = NULL;
    const ScPageScaleToItem* pScaleToItem        = NULL;
    const SfxUInt16Item*     pScaleToPagesItem   = NULL;
    SfxItemState             eState;

	eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, sal_False,
									  (const SfxPoolItem**)&pScaleItem );
	if ( SFX_ITEM_DEFAULT == eState )
		pScaleItem = (const SfxUInt16Item*)
                    &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE );

    eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, sal_False,
                                      (const SfxPoolItem**)&pScaleToItem );
    if ( SFX_ITEM_DEFAULT == eState )
        pScaleToItem = (const ScPageScaleToItem*)
                    &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO );

	eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, sal_False,
									  (const SfxPoolItem**)&pScaleToPagesItem );
	if ( SFX_ITEM_DEFAULT == eState )
		pScaleToPagesItem = (const SfxUInt16Item*)
                    &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETOPAGES );

    DBG_ASSERT( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" );

    aTableParam.bCellContent    = sal_True;
	aTableParam.bNotes			= GET_BOOL(pParamSet,ATTR_PAGE_NOTES);
	aTableParam.bGrid			= GET_BOOL(pParamSet,ATTR_PAGE_GRID);
	aTableParam.bHeaders		= GET_BOOL(pParamSet,ATTR_PAGE_HEADERS);
	aTableParam.bFormulas		= GET_BOOL(pParamSet,ATTR_PAGE_FORMULAS);
	aTableParam.bNullVals		= GET_BOOL(pParamSet,ATTR_PAGE_NULLVALS);
	aTableParam.bCharts			= GET_SHOW(pParamSet,ATTR_PAGE_CHARTS);
	aTableParam.bObjects		= GET_SHOW(pParamSet,ATTR_PAGE_OBJECTS);
	aTableParam.bDrawings		= GET_SHOW(pParamSet,ATTR_PAGE_DRAWINGS);
	aTableParam.bTopDown		= GET_BOOL(pParamSet,ATTR_PAGE_TOPDOWN);
	aTableParam.bLeftRight		= !aTableParam.bLeftRight;
	aTableParam.nFirstPageNo	= GET_USHORT(pParamSet,ATTR_PAGE_FIRSTPAGENO);
	if (!aTableParam.nFirstPageNo)
		aTableParam.nFirstPageNo = (sal_uInt16) nPageStart;		// von vorheriger Tabelle

    if ( pScaleItem && pScaleToItem && pScaleToPagesItem )
	{
		sal_uInt16	nScaleAll     = pScaleItem->GetValue();
		sal_uInt16	nScaleToPages = pScaleToPagesItem->GetValue();

		aTableParam.bScaleNone		= (nScaleAll     == 100);
		aTableParam.bScaleAll		= (nScaleAll      > 0  );
        aTableParam.bScaleTo        = pScaleToItem->IsValid();
		aTableParam.bScalePageNum	= (nScaleToPages  > 0  );
		aTableParam.nScaleAll		= nScaleAll;
        aTableParam.nScaleWidth     = pScaleToItem->GetWidth();
        aTableParam.nScaleHeight    = pScaleToItem->GetHeight();
		aTableParam.nScalePageNum	= nScaleToPages;
	}
	else
	{
		aTableParam.bScaleNone		= sal_True;
		aTableParam.bScaleAll		= sal_False;
        aTableParam.bScaleTo        = sal_False;
		aTableParam.bScalePageNum	= sal_False;
		aTableParam.nScaleAll		= 0;
        aTableParam.nScaleWidth     = 0;
        aTableParam.nScaleHeight    = 0;
		aTableParam.nScalePageNum	= 0;
	}

	//	skip empty pages only if options with that flag are passed
	aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty();
	if ( pPageData )
		aTableParam.bSkipEmpty = sal_False;
	// Wenn pPageData gesetzt ist, interessieren fuer die Umbruch-Vorschau
	// nur die Umbrueche, leere Seiten werden nicht speziell behandelt

	//------------------------------------------------------
	// TabPage "Bereiche":
	//------------------------------------------------------

	//!	alle PrintAreas der Tabelle durchgehen !!!
	const ScRange*	pPrintArea = pDoc->GetPrintRange( nPrintTab, 0 );
	const ScRange*	pRepeatCol = pDoc->GetRepeatColRange( nPrintTab );
	const ScRange*	pRepeatRow = pDoc->GetRepeatRowRange( nPrintTab );

	//	ATTR_PAGE_PRINTTABLES wird ignoriert

	if ( pUserArea )				// UserArea (Selektion) hat Vorrang
	{
		bPrintCurrentTable    =
		aAreaParam.bPrintArea = sal_True;					// Selektion
		aAreaParam.aPrintArea = *pUserArea;

		//	Die Tabellen-Abfrage ist schon in DocShell::Print, hier immer
		aAreaParam.aPrintArea.aStart.SetTab(nPrintTab);
		aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab);

//		lcl_LimitRange( aAreaParam.aPrintArea, nPrintTab );			// ganze Zeilen/Spalten...
	}
	else if ( pDoc->HasPrintRange() )
	{
		if ( pPrintArea )								// mindestens eine gesetzt ?
		{
			bPrintCurrentTable    =
			aAreaParam.bPrintArea = sal_True;
			aAreaParam.aPrintArea = *pPrintArea;

			bMultiArea = ( pDoc->GetPrintRangeCount(nPrintTab) > 1 );
		}
		else
		{
            // do not print hidden sheets with "Print entire sheet" flag
            bPrintCurrentTable = pDoc->IsPrintEntireSheet( nPrintTab ) && pDoc->IsVisible( nPrintTab );
            aAreaParam.bPrintArea = !bPrintCurrentTable;    // otherwise the table is always counted
		}
	}
	else
	{
		//	#74834# don't print hidden tables if there's no print range defined there
		if ( pDoc->IsVisible( nPrintTab ) )
		{
			aAreaParam.bPrintArea = sal_False;
			bPrintCurrentTable = sal_True;
		}
		else
		{
			aAreaParam.bPrintArea = sal_True;	// otherwise the table is always counted
			bPrintCurrentTable = sal_False;
		}
	}

	if ( pRepeatCol )
	{
		aAreaParam.bRepeatCol = sal_True;
		aAreaParam.aRepeatCol = *pRepeatCol;
		nRepeatStartCol	= pRepeatCol->aStart.Col();
		nRepeatEndCol	= pRepeatCol->aEnd  .Col();
	}
	else
	{
		aAreaParam.bRepeatCol = sal_False;
		nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE;
	}

	if ( pRepeatRow )
	{
		aAreaParam.bRepeatRow = sal_True;
		aAreaParam.aRepeatRow = *pRepeatRow;
		nRepeatStartRow	= pRepeatRow->aStart.Row();
		nRepeatEndRow	= pRepeatRow->aEnd  .Row();
	}
	else
	{
		aAreaParam.bRepeatRow = sal_False;
		nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE;
	}

			//
			//	Seiten aufteilen
			//

	if (!bState)
	{
		nTabPages = CountPages();									// berechnet auch Zoom
		nTotalPages = nTabPages;
		nTotalPages += CountNotePages();
	}
	else
	{
		CalcPages();			// nur Umbrueche suchen
		CountNotePages();		// Notizen zaehlen, auch wenn Seitenzahl schon bekannt
	}

	if (nDocPages)
		aFieldData.nTotalPages = nDocPages;
	else
		aFieldData.nTotalPages = nTotalPages;

	SetDateTime( Date(), Time() );

	aFieldData.aTitle		= pDocShell->GetTitle();
	const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
	aFieldData.aLongDocName	= rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
	if ( aFieldData.aLongDocName.Len() )
		aFieldData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
	else
		aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle;

	//	Druckereinstellungen (Orientation, Paper) jetzt erst bei DoPrint
}

Size ScPrintFunc::GetDataSize() const
{
	Size aSize = aPageSize;
	aSize.Width()  -= nLeftMargin + nRightMargin;
	aSize.Height() -= nTopMargin + nBottomMargin;
	aSize.Height() -= aHdr.nHeight + aFtr.nHeight;
	return aSize;
}

void ScPrintFunc::GetScaleData( Size& rPhysSize, long& rDocHdr, long& rDocFtr )
{
	rPhysSize = aPageSize;
	rPhysSize.Width()  -= nLeftMargin + nRightMargin;
	rPhysSize.Height() -= nTopMargin + nBottomMargin;

	rDocHdr = aHdr.nHeight;
	rDocFtr = aFtr.nHeight;
}

void ScPrintFunc::SetDateTime( const Date& rDate, const Time& rTime )
{
	aFieldData.aDate = rDate;
	aFieldData.aTime = rTime;
}

void lcl_DrawGraphic( const Graphic &rGraphic, OutputDevice *pOut,
                      const Rectangle &rGrf, const Rectangle &rOut )
{
    const FASTBOOL bNotInside = !rOut.IsInside( rGrf );
    if ( bNotInside )
    {
        pOut->Push();
        pOut->IntersectClipRegion( rOut );
    }

    ((Graphic&)rGraphic).Draw( pOut, rGrf.TopLeft(), rGrf.GetSize() );

    if ( bNotInside )
        pOut->Pop();
}

void lcl_DrawGraphic( const SvxBrushItem &rBrush, OutputDevice *pOut, OutputDevice* pRefDev,
						const Rectangle &rOrg, const Rectangle &rOut )
{
	Size aGrfSize(0,0);
	const Graphic *pGraphic = rBrush.GetGraphic();
	SvxGraphicPosition ePos;
	if ( pGraphic && pGraphic->IsSupportedGraphic() )
	{
		const MapMode aMapMM( MAP_100TH_MM );
		if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
			aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM );
		else
			aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
									pGraphic->GetPrefMapMode(), aMapMM );
		ePos = rBrush.GetGraphicPos();
	}
	else
		ePos = GPOS_NONE;

	Point aPos;
	Size aDrawSize = aGrfSize;

	FASTBOOL bDraw = sal_True;
//	FASTBOOL bRetouche = sal_True;
	switch ( ePos )
	{
		case GPOS_LT: aPos = rOrg.TopLeft();
					  break;
		case GPOS_MT: aPos.Y() = rOrg.Top();
					  aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
					  break;
		case GPOS_RT: aPos.Y() = rOrg.Top();
					  aPos.X() = rOrg.Right() - aGrfSize.Width();
					  break;

		case GPOS_LM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
					  aPos.X() = rOrg.Left();
					  break;
		case GPOS_MM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
					  aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
					  break;
		case GPOS_RM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
					  aPos.X() = rOrg.Right() - aGrfSize.Width();
					  break;

		case GPOS_LB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
					  aPos.X() = rOrg.Left();
					  break;
		case GPOS_MB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
					  aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
					  break;
		case GPOS_RB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
					  aPos.X() = rOrg.Right() - aGrfSize.Width();
					  break;

		case GPOS_AREA:
					  aPos = rOrg.TopLeft();
					  aDrawSize = rOrg.GetSize();
//					  bRetouche = sal_False;
					  break;
		case GPOS_TILED:
					{
						//	#104004# use GraphicObject::DrawTiled instead of an own loop
						//	(pixel rounding is handled correctly, and a very small bitmap
						//	is duplicated into a bigger one for better performance)

						GraphicObject aObject( *pGraphic );

                        if( pOut->GetPDFWriter() &&
                            (aObject.GetType() == GRAPHIC_BITMAP || aObject.GetType() == GRAPHIC_DEFAULT) )
                        {
                            // #104004# For PDF export, every draw
                            // operation for bitmaps takes a noticeable
                            // amount of place (~50 characters). Thus,
                            // optimize between tile bitmap size and
                            // number of drawing operations here.
                            //
                            //                  A_out
                            // n_chars = k1 *  ---------- + k2 * A_bitmap
                            //                  A_bitmap
                            //
                            // minimum n_chars is obtained for (derive for
                            // A_bitmap, set to 0, take positive
                            // solution):
                            //                   k1
                            // A_bitmap = Sqrt( ---- A_out )
                            //                   k2
                            //
                            // where k1 is the number of chars per draw
                            // operation, and k2 is the number of chars
                            // per bitmap pixel. This is approximately 50
                            // and 7 for current PDF writer, respectively.
                            //
                            const double	k1( 50 );
                            const double	k2( 7 );
                            const Size 		aSize( rOrg.GetSize() );
                            const double 	Abitmap( k1/k2 * aSize.Width()*aSize.Height() );

                            aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0),
                                               NULL, GRFMGR_DRAW_STANDARD,
                                               ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
                        }
                        else
                        {
                            aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0) );
                        }

						bDraw = sal_False;
//						bRetouche = sal_False;
					}
					break;

		case GPOS_NONE:
					  bDraw = sal_False;
					  break;

		default: DBG_ASSERT( !pOut, "new Graphic position?" );
	}
	Rectangle aGrf( aPos,aDrawSize );
	if ( bDraw && aGrf.IsOver( rOut ) )
	{
		lcl_DrawGraphic( *pGraphic, pOut, aGrf, rOut );
	}
}

//	Rahmen wird nach innen gezeichnet

void ScPrintFunc::DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH,
								const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground,
								const SvxShadowItem* pShadow )
{
	//!		direkte Ausgabe aus SvxBoxItem !!!

	if (pBorderData)
		if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() &&
										!pBorderData->GetRight() )
			pBorderData = NULL;

	if (!pBorderData && !pBackground && !pShadow)
		return;										// nichts zu tun

	long nLeft   = 0;
	long nRight  = 0;
	long nTop    = 0;
	long nBottom = 0;

	//	aFrameRect - aussen um die Umrandung, ohne Schatten
	if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
	{
		nLeft	+= (long) ( pShadow->CalcShadowSpace(SHADOW_LEFT)	* nScaleX );
		nRight	+= (long) ( pShadow->CalcShadowSpace(SHADOW_RIGHT)	* nScaleX );
		nTop	+= (long) ( pShadow->CalcShadowSpace(SHADOW_TOP)	* nScaleY );
		nBottom	+= (long) ( pShadow->CalcShadowSpace(SHADOW_BOTTOM)	* nScaleY );
	}
	Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop),
						  Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) );

	//	Mitte der Umrandung, um Linien ueber OutputData zu zeichnen:
	if (pBorderData)
	{
		nLeft   += (long) ( lcl_LineTotal(pBorderData->GetLeft())   * nScaleX / 2 );
		nRight  += (long) ( lcl_LineTotal(pBorderData->GetRight())  * nScaleX / 2 );
		nTop    += (long) ( lcl_LineTotal(pBorderData->GetTop())    * nScaleY / 2 );
		nBottom += (long) ( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 );
	}
	long nEffHeight = nScrH - nTop - nBottom;
	long nEffWidth = nScrW - nLeft - nRight;
	if (nEffHeight<=0 || nEffWidth<=0)
		return;											// leer

	//	#105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
	sal_Bool bCellContrast = bUseStyleColor &&
			Application::GetSettings().GetStyleSettings().GetHighContrastMode();

	if ( pBackground && !bCellContrast )
	{
//		Rectangle aBackRect( Point(nScrX+nLeft, nScrY+nTop), Size(nEffWidth,nEffHeight) );
		if (pBackground->GetGraphicPos() != GPOS_NONE)
		{
			OutputDevice* pRefDev;
			if ( bIsRender )
				pRefDev = pDev;					// don't use printer for PDF
			else
				pRefDev = pDoc->GetPrinter();	// use printer also for preview

			lcl_DrawGraphic( *pBackground, pDev, pRefDev, aFrameRect, aFrameRect );
		}
		else
		{
			pDev->SetFillColor(pBackground->GetColor());
			pDev->SetLineColor();
			pDev->DrawRect(aFrameRect);
		}
	}

	if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
	{
		if ( bCellContrast )
            pDev->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
		else
			pDev->SetFillColor(pShadow->GetColor());
		pDev->SetLineColor();
		long nShadowX = (long) ( pShadow->GetWidth() * nScaleX );
		long nShadowY = (long) ( pShadow->GetWidth() * nScaleY );
		switch (pShadow->GetLocation())
		{
			case SVX_SHADOW_TOPLEFT:
				pDev->DrawRect( Rectangle(
						aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
						aFrameRect.Right()-nShadowX, aFrameRect.Top() ) );
				pDev->DrawRect( Rectangle(
						aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
						aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) );
				break;
			case SVX_SHADOW_TOPRIGHT:
				pDev->DrawRect( Rectangle(
						aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY,
						aFrameRect.Right()+nShadowX, aFrameRect.Top() ) );
				pDev->DrawRect( Rectangle(
						aFrameRect.Right(), aFrameRect.Top()-nShadowY,
						aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) );
				break;
			case SVX_SHADOW_BOTTOMLEFT:
				pDev->DrawRect( Rectangle(
						aFrameRect.Left()-nShadowX, aFrameRect.Bottom(),
						aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) );
				pDev->DrawRect( Rectangle(
						aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY,
						aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) );
				break;
			case SVX_SHADOW_BOTTOMRIGHT:
				pDev->DrawRect( Rectangle(
						aFrameRect.Left()+nShadowX, aFrameRect.Bottom(),
						aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
				pDev->DrawRect( Rectangle(
						aFrameRect.Right(), aFrameRect.Top()+nShadowY,
						aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
				break;
            default:
            {
                // added to avoid warnings
            }
		}
	}

	if (pBorderData)
	{
		ScDocument* pBorderDoc = new ScDocument( SCDOCMODE_UNDO );
		pBorderDoc->InitUndo( pDoc, 0,0, sal_True,sal_True );
		if (pBorderData)
			pBorderDoc->ApplyAttr( 0,0,0, *pBorderData );

        ScTableInfo aTabInfo;
        pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0,
											nScaleX, nScaleY, sal_False, sal_False );
        DBG_ASSERT(aTabInfo.mnArrCount,"nArrCount == 0");

        aTabInfo.mpRowInfo[1].nHeight = (sal_uInt16) nEffHeight;
        aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth =
            aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = (sal_uInt16) nEffWidth;

        ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc, 0,
									nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY );
		aOutputData.SetUseStyleColor( bUseStyleColor );

//		pDev->SetMapMode(aTwipMode);

		if (pBorderData)
			aOutputData.DrawFrame();

		delete pBorderDoc;
	}
}

void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY )
{
	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
	long nLayoutSign = bLayoutRTL ? -1 : 1;

	Size aOnePixel = pDev->PixelToLogic(Size(1,1));
	long nOneX = aOnePixel.Width();
	long nOneY = aOnePixel.Height();
	SCCOL nCol;

	long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
	long nEndY = nScrY + nHeight - nOneY;

	long nPosX = nScrX;
	if ( bLayoutRTL )
	{
		for (nCol=nX1; nCol<=nX2; nCol++)
			nPosX += (long)( pDoc->GetColWidth( nCol, nPrintTab ) * nScaleX );
	}
	else
		nPosX -= nOneX;
	long nPosY = nScrY - nOneY;
	String aText;

	for (nCol=nX1; nCol<=nX2; nCol++)
	{
		sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
		if (nDocW)
		{
			long nWidth = (long) (nDocW * nScaleX);
			long nEndX = nPosX + nWidth * nLayoutSign;

			pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );

            aText = ::ScColToAlpha( nCol);
			long nTextWidth = pDev->GetTextWidth(aText);
			long nTextHeight = pDev->GetTextHeight();
			long nAddX = ( nWidth  - nTextWidth  ) / 2;
			long nAddY = ( nHeight - nTextHeight ) / 2;
			long nTextPosX = nPosX+nAddX;
			if ( bLayoutRTL )
				nTextPosX -= nWidth;
			pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText );

			nPosX = nEndX;
		}
	}
}

void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY )
{
	Size aOnePixel = pDev->PixelToLogic(Size(1,1));
	long nOneX = aOnePixel.Width();
	long nOneY = aOnePixel.Height();

	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );

	long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
	long nEndX = nScrX + nWidth;
	long nPosX = nScrX;
	if ( !bLayoutRTL )
	{
		nEndX -= nOneX;
		nPosX -= nOneX;
	}
	long nPosY = nScrY - nOneY;
	String aText;

	for (SCROW nRow=nY1; nRow<=nY2; nRow++)
	{
		sal_uInt16 nDocH = pDoc->GetRowHeight( nRow, nPrintTab );
		if (nDocH)
		{
			long nHeight = (long) (nDocH * nScaleY);
			long nEndY = nPosY + nHeight;

			pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );

			aText = String::CreateFromInt32( nRow+1 );
			long nTextWidth = pDev->GetTextWidth(aText);
			long nTextHeight = pDev->GetTextHeight();
			long nAddX = ( nWidth  - nTextWidth  ) / 2;
			long nAddY = ( nHeight - nTextHeight ) / 2;
			pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText );

			nPosY = nEndY;
		}
	}
}

void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY,
								sal_Bool bRepCol, ScPreviewLocationData& rLocationData )
{
	Size aOnePixel = pDev->PixelToLogic(Size(1,1));
	long nOneX = aOnePixel.Width();
	long nOneY = aOnePixel.Height();

	long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
	long nEndY = nScrY + nHeight - nOneY;

	long nPosX = nScrX - nOneX;
	for (SCCOL nCol=nX1; nCol<=nX2; nCol++)
	{
		sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
		if (nDocW)
			nPosX += (long) (nDocW * nScaleX);
	}
	Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY );
	rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol );
}

void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY,
								sal_Bool bRepRow, ScPreviewLocationData& rLocationData )
{
	Size aOnePixel = pDev->PixelToLogic(Size(1,1));
	long nOneX = aOnePixel.Width();
	long nOneY = aOnePixel.Height();

	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );

	long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
	long nEndX = nScrX + nWidth;
	if ( !bLayoutRTL )
		nEndX -= nOneX;

	long nPosY = nScrY - nOneY;
    nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
	Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY );
	rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow );
}

void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
								long nScrX, long nScrY, sal_Bool bRepCol, sal_Bool bRepRow,
								ScPreviewLocationData& rLocationData )
{
	//	get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer)

	Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
	long nLogStX = aLogPos.X();
	long nLogStY = aLogPos.Y();

	SCCOL nCol;
	Point aTwipOffset;
	for (nCol=0; nCol<nX1; nCol++)
		aTwipOffset.X() -= pDoc->GetColWidth( nCol, nPrintTab );
    aTwipOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nPrintTab );

	Point aMMOffset( aTwipOffset );
	aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS);
	aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS);
	aMMOffset += Point( nLogStX, nLogStY );
	MapMode aDrawMapMode( MAP_100TH_MM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() );

	//	get pixel rectangle

	Size aOnePixel = pDev->PixelToLogic(Size(1,1));
	long nOneX = aOnePixel.Width();
	long nOneY = aOnePixel.Height();

	long nPosX = nScrX - nOneX;
	for (nCol=nX1; nCol<=nX2; nCol++)
	{
		sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
		if (nDocW)
			nPosX += (long) (nDocW * nScaleX);
	}

	long nPosY = nScrY - nOneY;
    nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
	Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY );
	rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ),
								bRepCol, bRepRow, aDrawMapMode );
}

void ScPrintFunc::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 )
{
    // #i47547# nothing to do if the end of the print area is before the end of
    // the repeat columns/rows (don't use negative size for ScOutputData)
    if ( nX2 < nX1 || nY2 < nY1 )
        return;

							//!		Flag bei FillInfo uebergeben !!!!!
    ScRange aERange;
	sal_Bool bEmbed = pDoc->IsEmbedded();
	if (bEmbed)
	{
		pDoc->GetEmbedded(aERange);
		pDoc->ResetEmbedded();
	}

	Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
	long nLogStX = aPos.X();
	long nLogStY = aPos.Y();

					//	Daten zusammenstellen

    ScTableInfo aTabInfo;
    pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab,
										nScaleX, nScaleY, sal_True, aTableParam.bFormulas );
    lcl_HidePrint( aTabInfo, nX1, nX2 );

	if (bEmbed)
		pDoc->SetEmbedded(aERange);

    ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nPrintTab,
								nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );

	// #114135#
	aOutputData.SetDrawView( pDrawView );

	// test if all paint parts are hidden, then a paint is not necessary at all
	const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
    const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart()
            && pDrawView->getHideDraw() && pDrawView->getHideFormControl() );

    if(!bHideAllDrawingLayer)
	{
		pDev->SetMapMode(aLogicMode);
		//	hier kein Clipping setzen (Mapmode wird verschoben)

		// #i72502#
		aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
	}

	pDev->SetMapMode(aOffsetMode);

	aOutputData.SetShowFormulas( aTableParam.bFormulas );
	aOutputData.SetShowNullValues( aTableParam.bNullVals );
	aOutputData.SetUseStyleColor( bUseStyleColor );

	Color aGridColor( COL_BLACK );
	if ( bUseStyleColor )
        aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
	aOutputData.SetGridColor( aGridColor );

	if ( !pPrinter )
	{
		OutputDevice* pRefDev = pDoc->GetPrinter();		// auch fuer Preview den Drucker nehmen
		Fraction aPrintFrac( nZoom, 100 );				// ohne nManualZoom
		//	MapMode, wie er beim Drucken herauskommen wuerde:
		pRefDev->SetMapMode( MapMode( MAP_100TH_MM, Point(), aPrintFrac, aPrintFrac ) );

		//	when rendering (PDF), don't use printer as ref device, but printer's MapMode
		//	has to be set anyway, as charts still use it (#106409#)
		if ( !bIsRender )
			aOutputData.SetRefDevice( pRefDev );
	}

//	aOutputData.SetMetaFileMode(sal_True);
    if( aTableParam.bCellContent )
	    aOutputData.DrawBackground();

	pDev->SetClipRegion( Rectangle( aPos, Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) );
	pDev->SetClipRegion();

//	aOutputData.SetMetaFileMode(sal_False);
    if( aTableParam.bCellContent )
    {
	    aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom );
	    aOutputData.DrawFrame();
	    aOutputData.DrawStrings();

    //	pDev->SetMapMode(aLogicMode);
	    aOutputData.DrawEdit(sal_False);
    }

//	pDev->SetMapMode(aOffsetMode);
	if (aTableParam.bGrid)
		aOutputData.DrawGrid( sal_True, sal_False );	// keine Seitenumbrueche

/*!!!!!!!!!!!		Notizen in Tabelle markieren ??????????????????????????

	if (aTableParam.bNotes)
	{
		pDev->SetMapMode(aOffsetMode);
		aOutputData.PrintNoteMarks(aNotePosList);
		pDev->SetMapMode(aLogicMode);
	}
*/

    aOutputData.AddPDFNotes();      // has no effect if not rendering PDF with notes enabled

//	pDev->SetMapMode(aDrawMode);

	// test if all paint parts are hidden, then a paint is not necessary at all
	if(!bHideAllDrawingLayer)
	{
		// #i72502#
		aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
	}

	// #i72502#
	aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
	aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
}

sal_Bool ScPrintFunc::IsMirror( long nPageNo )			// Raender spiegeln ?
{
	SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
	return ( eUsage == SVX_PAGE_MIRROR && (nPageNo & 1) );
}

sal_Bool ScPrintFunc::IsLeft( long nPageNo )			// linke Fussnoten ?
{
	SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
	sal_Bool bLeft;
	if (eUsage == SVX_PAGE_LEFT)
		bLeft = sal_True;
	else if (eUsage == SVX_PAGE_RIGHT)
		bLeft = sal_False;
	else
		bLeft = (nPageNo & 1) != 0;
	return bLeft;
}

void ScPrintFunc::MakeTableString()
{
	pDoc->GetName( nPrintTab, aFieldData.aTabName );
}

void ScPrintFunc::MakeEditEngine()
{
	if (!pEditEngine)
	{
		//	can't use document's edit engine pool here,
		//	because pool must have twips as default metric
		pEditEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), sal_True );

		pEditEngine->EnableUndo(sal_False);
		pEditEngine->SetRefDevice( pDev );
		pEditEngine->SetWordDelimiters(
				ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
		pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
        pDoc->ApplyAsianEditSettings( *pEditEngine );
		pEditEngine->EnableAutoColor( bUseStyleColor );

		//	Default-Set fuer Ausrichtung
		pEditDefaults = new SfxItemSet( pEditEngine->GetEmptyItemSet() );

		const ScPatternAttr& rPattern = (const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN);
		rPattern.FillEditItemSet( pEditDefaults );
		//	FillEditItemSet adjusts font height to 1/100th mm,
		//	but for header/footer twips is needed, as in the PatternAttr:
		pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
		pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
		pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
		//	#69193# dont use font color, because background color is not used
		//!	there's no way to set the background for note pages
		pEditDefaults->ClearItem( EE_CHAR_COLOR );
		if (ScGlobal::IsSystemRTL())
			pEditDefaults->Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
	}

	pEditEngine->SetData( aFieldData );		// Seitennummer etc. setzen
}

//	nStartY = logic
void ScPrintFunc::PrintHF( long nPageNo, sal_Bool bHeader, long nStartY,
							sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
{
	const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr;

	pDev->SetMapMode( aTwipMode );			// Kopf-/Fusszeilen in Twips

	sal_Bool bLeft = IsLeft(nPageNo) && !rParam.bShared;
	const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight;

	long nLineStartX = aPageRect.Left()  + rParam.nLeft;
	long nLineEndX	 = aPageRect.Right() - rParam.nRight;
	long nLineWidth  = nLineEndX - nLineStartX + 1;

	//	Edit-Engine

	Point aStart( nLineStartX, nStartY );
	Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance );
	if ( rParam.pBorder )
	{
		long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(BOX_LINE_LEFT);
		long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(BOX_LINE_TOP);
		aStart.X() += nLeft;
		aStart.Y() += nTop;
		aPaperSize.Width() -= nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(BOX_LINE_RIGHT);
		aPaperSize.Height() -= nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
	}

	if ( rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE )
	{
		long nLeft	= rParam.pShadow->CalcShadowSpace(SHADOW_LEFT);
		long nTop	= rParam.pShadow->CalcShadowSpace(SHADOW_TOP);
		aStart.X() += nLeft;
		aStart.Y() += nTop;
		aPaperSize.Width() -= nLeft + rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT);
		aPaperSize.Height() -= nTop + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
	}

	aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo;
	MakeEditEngine();

	pEditEngine->SetPaperSize(aPaperSize);
	const EditTextObject* pObject;

	//	Rahmen / Hintergrund

	Point aBorderStart( nLineStartX, nStartY );
	Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance );
	if ( rParam.bDynamic )
	{
		//	hier nochmal anpassen, wegen geraden/ungeraden Kopf/Fusszeilen
		//	und evtl. anderen Umbruechen durch Variablen (Seitennummer etc.)

		long nMaxHeight = 0;
		nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) );
		nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) );
		nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) );
		if (rParam.pBorder)
			nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
						  lcl_LineTotal( rParam.pBorder->GetBottom() ) +
									rParam.pBorder->GetDistance(BOX_LINE_TOP) +
									rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
		if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
			nMaxHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
						  rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);

		if (nMaxHeight < rParam.nManHeight-rParam.nDistance)
			nMaxHeight = rParam.nManHeight-rParam.nDistance;		// eingestelltes Minimum

		aBorderSize.Height() = nMaxHeight;
	}

	if ( bDoPrint )
	{
		double nOldScaleX = nScaleX;
		double nOldScaleY = nScaleY;
		nScaleX = nScaleY = 1.0;			// direkt in Twips ausgeben
		DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(),
						rParam.pBorder, rParam.pBack, rParam.pShadow );
		nScaleX = nOldScaleX;
		nScaleY = nOldScaleY;

		//	Clipping fuer Text

		pDev->SetClipRegion( Rectangle( aStart, aPaperSize ) );

		//	links

		pObject = pHFItem->GetLeftArea();
		if (pObject)
		{
			pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
			pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False );
			Point aDraw = aStart;
			long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
			if (nDif > 0)
				aDraw.Y() += nDif / 2;
			pEditEngine->Draw( pDev, aDraw, 0 );
		}

		//	Mitte

		pObject = pHFItem->GetCenterArea();
		if (pObject)
		{
			pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
			pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False );
			Point aDraw = aStart;
			long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
			if (nDif > 0)
				aDraw.Y() += nDif / 2;
			pEditEngine->Draw( pDev, aDraw, 0 );
		}

		//	rechts

		pObject = pHFItem->GetRightArea();
		if (pObject)
		{
			pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
			pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False );
			Point aDraw = aStart;
			long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
			if (nDif > 0)
				aDraw.Y() += nDif / 2;
			pEditEngine->Draw( pDev, aDraw, 0 );
		}

		pDev->SetClipRegion();
	}

	if ( pLocationData )
	{
		Rectangle aHeaderRect( aBorderStart, aBorderSize );
		pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft );
	}
}

long ScPrintFunc::DoNotes( long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
{
	if (bDoPrint)
		pDev->SetMapMode(aTwipMode);

	MakeEditEngine();
	pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
	pEditEngine->SetDefaults( *pEditDefaults );

	Font aMarkFont;
	ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
	((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).GetFont( aMarkFont, eColorMode );
//?	aMarkFont.SetWeight( WEIGHT_BOLD );
	pDev->SetFont( aMarkFont );
	long nMarkLen = pDev->GetTextWidth(
			String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:")));
	// ohne Space, weil's eh selten so weit kommt

	Size aDataSize = aPageRect.GetSize();
	if ( nMarkLen > aDataSize.Width() / 2 )		// alles viel zu klein?
		nMarkLen = aDataSize.Width() / 2;		// Seite bruederlich aufteilen
	aDataSize.Width() -= nMarkLen;

	pEditEngine->SetPaperSize( aDataSize );
	long nPosX = aPageRect.Left() + nMarkLen;
	long nPosY = aPageRect.Top();

	long nCount = 0;
	sal_Bool bOk;
	do
	{
		bOk = sal_False;
		ScAddress* pPos = (ScAddress*) aNotePosList.GetObject( nNoteStart+nCount );
		if (pPos)
		{
			ScBaseCell* pCell = pDoc->GetCell( *pPos);
            if( const ScPostIt* pNote = pCell->GetNote() )
			{
				if(const EditTextObject *pEditText = pNote->GetEditTextObject())
				    pEditEngine->SetText(*pEditText);
				long nTextHeight = pEditEngine->GetTextHeight();
				if ( nPosY + nTextHeight < aPageRect.Bottom() )
				{
					if (bDoPrint)
					{
						pEditEngine->Draw( pDev, Point( nPosX, nPosY ), 0 );

						String aMarkStr;
						pPos->Format( aMarkStr, SCA_VALID, pDoc, pDoc->GetAddressConvention() );
						aMarkStr += ':';

						//	Zellposition auch per EditEngine, damit die Position stimmt
						pEditEngine->SetText(aMarkStr);
						pEditEngine->Draw( pDev, Point( aPageRect.Left(), nPosY ), 0 );
					}

					if ( pLocationData )
					{
						Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) );
						pLocationData->AddNoteText( aTextRect, *pPos );
						Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) );
						pLocationData->AddNoteMark( aMarkRect, *pPos );
					}

					nPosY += nTextHeight;
					nPosY += 200;					// Abstand
					++nCount;
					bOk = sal_True;
				}
			}
		}
	}
	while (bOk);

	return nCount;
}

long ScPrintFunc::PrintNotes( long nPageNo, long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
{
	if ( nNoteStart >= (long) aNotePosList.Count() || !aTableParam.bNotes )
		return 0;

	if ( bDoPrint && bClearWin )
	{
		//!	mit PrintPage zusammenfassen !!!

		Color aBackgroundColor( COL_WHITE );
		if ( bUseStyleColor )
            aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );

		pDev->SetMapMode(aOffsetMode);
		pDev->SetLineColor();
		pDev->SetFillColor(aBackgroundColor);
		pDev->DrawRect(Rectangle(Point(),
				Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
					 (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
	}


	//		aPageRect auf linke / rechte Seiten anpassen

	Rectangle aTempRect = Rectangle( Point(), aPageSize );
	if (IsMirror(nPageNo))
	{
		aPageRect.Left()  = ( aTempRect.Left()  + nRightMargin ) * 100 / nZoom;
		aPageRect.Right() = ( aTempRect.Right() - nLeftMargin  ) * 100 / nZoom;
	}
	else
	{
		aPageRect.Left()  = ( aTempRect.Left()  + nLeftMargin  ) * 100 / nZoom;
		aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
	}

	if ( pPrinter && bDoPrint )
    {
        DBG_ERROR( "StartPage does not exist anymore" );
		// pPrinter->StartPage();
    }

	if ( bDoPrint || pLocationData )
	{
		//	Kopf- und Fusszeilen

		if (aHdr.bEnable)
		{
			long nHeaderY = aPageRect.Top()-aHdr.nHeight;
			PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
		}
		if (aFtr.bEnable)
		{
			long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
			PrintHF( nPageNo, sal_False, nFooterY, bDoPrint, pLocationData );
		}
	}

	long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData );

	if ( pPrinter && bDoPrint )
    {
        DBG_ERROR( "EndPage does not exist anymore" );
		// pPrinter->EndPage();
    }

	return nCount;
}

void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
								sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
{
	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
	long nLayoutSign = bLayoutRTL ? -1 : 1;

	//	nPageNo is the page number within all sheets of one "start page" setting

	if ( bClearWin && bDoPrint )
	{
		//	muss genau zum Zeichnen des Rahmens in preview.cxx passen !!!

		Color aBackgroundColor( COL_WHITE );
		if ( bUseStyleColor )
            aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );

		pDev->SetMapMode(aOffsetMode);
		pDev->SetLineColor();
		pDev->SetFillColor(aBackgroundColor);
		pDev->DrawRect(Rectangle(Point(),
				Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
					 (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
	}


	//		aPageRect auf linke / rechte Seiten anpassen

	Rectangle aTempRect = Rectangle( Point(), aPageSize );
	if (IsMirror(nPageNo))
	{
		aPageRect.Left()  = ( aTempRect.Left()  + nRightMargin ) * 100 / nZoom;
		aPageRect.Right() = ( aTempRect.Right() - nLeftMargin  ) * 100 / nZoom;
	}
	else
	{
		aPageRect.Left()  = ( aTempRect.Left()  + nLeftMargin  ) * 100 / nZoom;
		aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
	}

	if ( aAreaParam.bRepeatCol )
		if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol )
			nX1 = nRepeatEndCol + 1;
	sal_Bool bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol);
	if ( aAreaParam.bRepeatRow )
		if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow )
			nY1 = nRepeatEndRow + 1;
	sal_Bool bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow);

    // use new object hide flags in SdrPaintView
    if(pDrawView)
    {
        pDrawView->setHideOle(!aTableParam.bObjects);
        pDrawView->setHideChart(!aTableParam.bCharts);
        pDrawView->setHideDraw(!aTableParam.bDrawings);
        pDrawView->setHideFormControl(!aTableParam.bDrawings);
    }

	if ( pPrinter && bDoPrint )
    {
        DBG_ERROR( "StartPage does not exist anymore" );
		// pPrinter->StartPage();
    }

	//	Kopf- und Fusszeilen (ohne Zentrierung)

	if (aHdr.bEnable)
	{
		long nHeaderY = aPageRect.Top()-aHdr.nHeight;
		PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
	}
	if (aFtr.bEnable)
	{
		long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
		PrintHF( nPageNo, sal_False, nFooterY, bDoPrint, pLocationData );
	}

	//	Position ( Raender / zentrieren )

	long nLeftSpace = aPageRect.Left();		// Document-Twips
	long nTopSpace  = aPageRect.Top();
	if ( bCenterHor || bLayoutRTL )
	{
		long nDataWidth = 0;
        SCCOL i;
		for (i=nX1; i<=nX2; i++)
			nDataWidth += pDoc->GetColWidth( i,nPrintTab );
		if (bDoRepCol)
			for (i=nRepeatStartCol; i<=nRepeatEndCol; i++)
				nDataWidth += pDoc->GetColWidth( i,nPrintTab );
		if (aTableParam.bHeaders)
			nDataWidth += (long) PRINT_HEADER_WIDTH;
		if (pBorderItem)
			nDataWidth += pBorderItem->GetDistance(BOX_LINE_LEFT) +
						   pBorderItem->GetDistance(BOX_LINE_RIGHT);		//! Line width?
		if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
			nDataWidth += pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
						   pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
		if ( bCenterHor )
		{
			nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2;		// LTR or RTL
			if (pBorderItem)
				nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft());
		}
		else if ( bLayoutRTL )
			nLeftSpace += aPageRect.GetWidth() - nDataWidth;				// align to the right edge of the page
	}
	if ( bCenterVer )
	{
        long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab);
		if (bDoRepRow)
            nDataHeight += pDoc->GetRowHeight( nRepeatStartRow,
                    nRepeatEndRow, nPrintTab);
		if (aTableParam.bHeaders)
			nDataHeight += (long) PRINT_HEADER_HEIGHT;
		if (pBorderItem)
			nDataHeight += pBorderItem->GetDistance(BOX_LINE_TOP) +
						   pBorderItem->GetDistance(BOX_LINE_BOTTOM);		//! Line width?
		if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
			nDataHeight += pShadowItem->CalcShadowSpace(SHADOW_TOP) +
						   pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
		nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2;
		if (pBorderItem)
			nTopSpace -= lcl_LineTotal(pBorderItem->GetTop());
	}

	//	calculate sizes of the elements for partitioning
	//	(header, repeat, data)

	long nHeaderWidth   = 0;
	long nHeaderHeight  = 0;
	long nRepeatWidth   = 0;
	long nRepeatHeight  = 0;
	long nContentWidth  = 0;		// scaled - not the same as nDataWidth above
	long nContentHeight = 0;
	if (aTableParam.bHeaders)
	{
		nHeaderWidth  = (long) (PRINT_HEADER_WIDTH * nScaleX);
		nHeaderHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
	}
	if (bDoRepCol)
		for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++)
			nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
	if (bDoRepRow)
        nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow,
                nRepeatEndRow, nPrintTab, nScaleY);
	for (SCCOL i=nX1; i<=nX2; i++)
		nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
    nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab,
            nScaleY);

	//	partition the page

	long nStartX = ((long) ( nLeftSpace * nScaleX ));
	long nStartY = ((long) ( nTopSpace  * nScaleY ));
//		nStartX -= aOffset.X();			// schon im MapMode
//		nStartY -= aOffset.Y();

	long nInnerStartX = nStartX;
	long nInnerStartY = nStartY;
	if (pBorderItem)
	{
		nInnerStartX += (long) ( ( lcl_LineTotal(pBorderItem->GetLeft()) +
									pBorderItem->GetDistance(BOX_LINE_LEFT) ) * nScaleX );
		nInnerStartY += (long) ( ( lcl_LineTotal(pBorderItem->GetTop()) +
									pBorderItem->GetDistance(BOX_LINE_TOP) ) * nScaleY );
	}
	if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
	{
		nInnerStartX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
		nInnerStartY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_TOP) * nScaleY );
	}

	if ( bLayoutRTL )
	{
		//	arrange elements starting from the right edge
		nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth;

		//	make rounding easier so the elements are really next to each other in preview
		Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode );
		long nOffsetOneX = aOffsetOnePixel.Width();
		nInnerStartX += nOffsetOneX / 2;
	}

	long nFrameStartX = nInnerStartX;
	long nFrameStartY = nInnerStartY;

	long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign;	// widths/heights are 0 if not used
	long nRepStartY = nInnerStartY + nHeaderHeight;
	long nDataX = nRepStartX + nRepeatWidth * nLayoutSign;
	long nDataY = nRepStartY + nRepeatHeight;
	long nEndX = nDataX + nContentWidth * nLayoutSign;
	long nEndY = nDataY + nContentHeight;
	long nFrameEndX = nEndX;
	long nFrameEndY = nEndY;

	if ( bLayoutRTL )
	{
		//	each element's start position is its left edge
		//!	subtract one pixel less?
		nInnerStartX -= nHeaderWidth;		// used for header
		nRepStartX   -= nRepeatWidth;
		nDataX       -= nContentWidth;

		//	continue right of the main elements again
		nEndX += nHeaderWidth + nRepeatWidth + nContentWidth;
	}

	//	Seiten-Rahmen / Hintergrund

	//!	nEndX/Y anpassen

	long nBorderEndX = nEndX;
	long nBorderEndY = nEndY;
	if (pBorderItem)
	{
		nBorderEndX += (long) ( ( lcl_LineTotal(pBorderItem->GetRight()) +
									pBorderItem->GetDistance(BOX_LINE_RIGHT) ) * nScaleX );
		nBorderEndY += (long) ( ( lcl_LineTotal(pBorderItem->GetBottom()) +
									pBorderItem->GetDistance(BOX_LINE_BOTTOM) ) * nScaleY );
	}
	if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
	{
		nBorderEndX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
		nBorderEndY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
	}

	if ( bDoPrint )
	{
		pDev->SetMapMode( aOffsetMode );
		DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY,
						pBorderItem, pBackgroundItem, pShadowItem );

		pDev->SetMapMode( aTwipMode );
	}

	pDev->SetMapMode( aOffsetMode );

	//	Wiederholungszeilen/Spalten ausgeben

	if (bDoRepCol && bDoRepRow)
	{
		if ( bDoPrint )
			PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
							nRepStartX,nRepStartY, sal_True,sal_True,sal_False,sal_False );
		if ( pLocationData )
			LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
							nRepStartX,nRepStartY, sal_True,sal_True, *pLocationData );
	}
	if (bDoRepCol)
	{
		if ( bDoPrint )
			PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY,
						sal_True,!bDoRepRow,sal_False,sal_True );
		if ( pLocationData )
			LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, sal_True,sal_False, *pLocationData );
	}
	if (bDoRepRow)
	{
		if ( bDoPrint )
			PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY,
						!bDoRepCol,sal_True,sal_True,sal_False );
		if ( pLocationData )
			LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, sal_False,sal_True, *pLocationData );
	}

	//	Daten ausgeben

	if ( bDoPrint )
		PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow,sal_True,sal_True );
	if ( pLocationData )
		LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, sal_False,sal_False, *pLocationData );

	//	Spalten-/Zeilenkoepfe ausgeben
	//	nach den Daten (ueber evtl. weitergezeichneten Schatten)

	Color aGridColor( COL_BLACK );
	if ( bUseStyleColor )
        aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );

	if (aTableParam.bHeaders)
	{
		if ( bDoPrint )
		{
			pDev->SetLineColor( aGridColor );
			pDev->SetFillColor();
			pDev->SetMapMode(aOffsetMode);
		}

		ScPatternAttr aPattern( pDoc->GetPool() );
		Font aFont;
		ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
		aPattern.GetFont( aFont, eColorMode, pDev );
		pDev->SetFont( aFont );

		if (bDoRepCol)
		{
			if ( bDoPrint )
				PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY );
			if ( pLocationData )
				LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, sal_True, *pLocationData );
		}
		if ( bDoPrint )
			PrintColHdr( nX1,nX2, nDataX,nInnerStartY );
		if ( pLocationData )
			LocateColHdr( nX1,nX2, nDataX,nInnerStartY, sal_False, *pLocationData );
		if (bDoRepRow)
		{
			if ( bDoPrint )
				PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY );
			if ( pLocationData )
				LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, sal_True, *pLocationData );
		}
		if ( bDoPrint )
			PrintRowHdr( nY1,nY2, nInnerStartX,nDataY );
		if ( pLocationData )
			LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, sal_False, *pLocationData );
	}

	//	einfacher Rahmen

	if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) )
	{
		Size aOnePixel = pDev->PixelToLogic(Size(1,1));
		long nOneX = aOnePixel.Width();
		long nOneY = aOnePixel.Height();

		long nLeftX   = nFrameStartX;
		long nTopY    = nFrameStartY - nOneY;
		long nRightX  = nFrameEndX;
		long nBottomY = nFrameEndY - nOneY;
		if ( !bLayoutRTL )
		{
			nLeftX   -= nOneX;
			nRightX  -= nOneX;
		}
		pDev->SetMapMode(aOffsetMode);
		pDev->SetLineColor( aGridColor );
		pDev->SetFillColor();
		pDev->DrawRect( Rectangle( nLeftX, nTopY, nRightX, nBottomY ) );
		//	nEndX/Y ohne Rahmen-Anpassung
	}

	if ( pPrinter && bDoPrint )
    {
        DBG_ERROR( "EndPage does not exist anymore" );
		// pPrinter->EndPage();
    }

	aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab );
	bSourceRangeValid = sal_True;
}

void ScPrintFunc::SetOffset( const Point& rOfs )
{
	aSrcOffset = rOfs;
}

void ScPrintFunc::SetManualZoom( sal_uInt16 nNewZoom )
{
	nManualZoom = nNewZoom;
}

void ScPrintFunc::SetClearFlag( sal_Bool bFlag )
{
	bClearWin = bFlag;
}

void ScPrintFunc::SetUseStyleColor( sal_Bool bFlag )
{
	bUseStyleColor = bFlag;
	if (pEditEngine)
		pEditEngine->EnableAutoColor( bUseStyleColor );
}

void ScPrintFunc::SetRenderFlag( sal_Bool bFlag )
{
	bIsRender = bFlag;		// set when using XRenderable (PDF)
}

void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects()
{
    aTableParam.bCellContent = false;
    aTableParam.bNotes = false;
    aTableParam.bGrid = false;
    aTableParam.bHeaders = false;
    aTableParam.bFormulas = false;
    aTableParam.bNullVals = false;
}

//
//	UpdatePages wird nur von aussen gerufen, um die Umbrueche fuer die Anzeige
//	richtig zu setzen - immer ohne UserArea
//

sal_Bool ScPrintFunc::UpdatePages()
{
	if (!pParamSet)
		return sal_False;

	//	Zoom

	nZoom = 100;
    if (aTableParam.bScalePageNum || aTableParam.bScaleTo)
		nZoom = ZOOM_MIN;						// stimmt fuer Umbrueche
	else if (aTableParam.bScaleAll)
	{
		nZoom = aTableParam.nScaleAll;
		if ( nZoom <= ZOOM_MIN )
			nZoom = ZOOM_MIN;
	}

	String aName = pDoc->GetPageStyle( nPrintTab );
	SCTAB nTabCount = pDoc->GetTableCount();
	for (SCTAB nTab=0; nTab<nTabCount; nTab++)
		if ( nTab==nPrintTab || pDoc->GetPageStyle(nTab)==aName )
		{
			//	Wiederholungszeilen / Spalten
			pDoc->SetRepeatArea( nTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );

			//	Umbrueche setzen
			ResetBreaks(nTab);
			pDocShell->PostPaint(0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID);
		}

	return sal_True;
}

long ScPrintFunc::CountPages()							// setzt auch nPagesX, nPagesY
{
	sal_Bool bAreaOk = sal_False;

	if (pDoc->HasTable( nPrintTab ))
	{
		if (aAreaParam.bPrintArea)							// Druckbereich angegeben?
		{
			if ( bPrintCurrentTable )
			{
				ScRange& rRange = aAreaParam.aPrintArea;

				//	hier kein Vergleich der Tabellen mehr, die Area gilt immer fuer diese Tabelle
				//	wenn hier verglichen werden soll, muss die Tabelle der Druckbereiche beim
				//	Einfuegen von Tabellen etc. angepasst werden !

				nStartCol = rRange.aStart.Col();
				nStartRow = rRange.aStart.Row();
				nEndCol   = rRange.aEnd  .Col();
				nEndRow   = rRange.aEnd  .Row();
				bAreaOk   = AdjustPrintArea(sal_False);			// begrenzen
			}
			else
				bAreaOk = sal_False;
		}
		else												// aus Dokument suchen
			bAreaOk = AdjustPrintArea(sal_True);
	}

	if (bAreaOk)
	{
		long nPages = 0;
		size_t nY;
		if (bMultiArea)
		{
			sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
			for (sal_uInt16 i=0; i<nRCount; i++)
			{
				CalcZoom(i);
				if ( aTableParam.bSkipEmpty )
					for (nY=0; nY<nPagesY; nY++)
                    {
                        OSL_ENSURE(nY < maPageRows.size(), "vector access error for maPageRows (!)");
                        nPages += maPageRows[nY].CountVisible();
                    }
				else
					nPages += ((long) nPagesX) * nPagesY;
				if ( pPageData )
					FillPageData();
			}
		}
		else
		{
			CalcZoom(RANGENO_NORANGE);						// Zoom berechnen
			if ( aTableParam.bSkipEmpty )
				for (nY=0; nY<nPagesY; nY++)
                {
                    OSL_ENSURE(nY < maPageRows.size(), "vector access error for maPageRows (!)");
                    nPages += maPageRows[nY].CountVisible();
                }
			else
				nPages += ((long) nPagesX) * nPagesY;
			if ( pPageData )
				FillPageData();
		}
		return nPages;
	}
	else
	{
//		nZoom = 100;						// nZoom auf letztem Wert stehenlassen !!!
		nPagesX = nPagesY = nTotalY = 0;
		return 0;
	}
}

long ScPrintFunc::CountNotePages()
{
	if ( !aTableParam.bNotes || !bPrintCurrentTable )
		return 0;

	long nCount=0;
	SCCOL nCol;
	SCROW nRow;

	sal_Bool bError = sal_False;
	if (!aAreaParam.bPrintArea)
		bError = !AdjustPrintArea(sal_True);			// komplett aus Dok suchen

	sal_uInt16 nRepeats = 1;							// wie oft durchgehen ?
	if (bMultiArea)
		nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
	if (bError)
		nRepeats = 0;

	for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
	{
		sal_Bool bDoThis = sal_True;
		if (bMultiArea)				// alle Areas durchgehen
		{
			const ScRange* pThisRange = pDoc->GetPrintRange( nPrintTab, nStep );
			if ( pThisRange )
			{
				nStartCol = pThisRange->aStart.Col();
				nStartRow = pThisRange->aStart.Row();
				nEndCol   = pThisRange->aEnd  .Col();
				nEndRow   = pThisRange->aEnd  .Row();
				bDoThis = AdjustPrintArea(sal_False);
			}
		}

		if (bDoThis)
		{
			ScHorizontalCellIterator aIter( pDoc, nPrintTab, nStartCol,nStartRow, nEndCol,nEndRow );
			ScBaseCell* pCell = aIter.GetNext( nCol, nRow );
			while (pCell)
			{
                if (pCell->HasNote())
				{
					aNotePosList.Insert( new ScAddress( nCol,nRow,nPrintTab ), LIST_APPEND );
					++nCount;
				}

				pCell = aIter.GetNext( nCol, nRow );
			}
		}
	}

	long nPages = 0;
	long nNoteNr = 0;
	long nNoteAdd;
	do
	{
		nNoteAdd = PrintNotes( nPages, nNoteNr, sal_False, NULL );
		if (nNoteAdd)
		{
			nNoteNr += nNoteAdd;
			++nPages;
		}
	}
	while (nNoteAdd);

	return nPages;
}

void ScPrintFunc::InitModes()				// aus nZoom etc. die MapModes setzen
{
	aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom );

	long nEffZoom = nZoom * (long) nManualZoom;

//	nScaleX = nScaleY = 1.0;			// Ausgabe in Twips
	nScaleX = nScaleY = HMM_PER_TWIPS;	// Ausgabe in 1/100 mm

	Fraction aZoomFract( nEffZoom,10000 );
	Fraction aHorFract = aZoomFract;

	if ( !pPrinter && !bIsRender )							// adjust scale for preview
	{
		double nFact = pDocShell->GetOutputFactor();
		aHorFract = Fraction( (long)( nEffZoom / nFact ), 10000 );
	}

	aLogicMode = MapMode( MAP_100TH_MM, Point(), aHorFract, aZoomFract );

	Point aLogicOfs( -aOffset.X(), -aOffset.Y() );
	aOffsetMode = MapMode( MAP_100TH_MM, aLogicOfs, aHorFract, aZoomFract );

	Point aTwipsOfs( (long) ( -aOffset.X() / nScaleX + 0.5 ), (long) ( -aOffset.Y() / nScaleY + 0.5 ) );
	aTwipMode = MapMode( MAP_TWIP, aTwipsOfs, aHorFract, aZoomFract );
}

//--------------------------------------------------------------------

void ScPrintFunc::ApplyPrintSettings()
{
	if ( pPrinter )
	{
		//
		//	Printer zum Drucken umstellen
		//

		Size aEnumSize = aPageSize;


        pPrinter->SetOrientation( bLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT );
        if ( bLandscape )
        {
                // landscape is always interpreted as a rotation by 90 degrees !
                // this leads to non WYSIWIG but at least it prints!
                // #i21775#
                long nTemp = aEnumSize.Width();
                aEnumSize.Width() = aEnumSize.Height();
                aEnumSize.Height() = nTemp;
        }
        Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, sal_True );
		sal_uInt16 nPaperBin = ((const SvxPaperBinItem&)pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue();

        pPrinter->SetPaper( ePaper );
        if ( PAPER_USER == ePaper )
        {
		    MapMode aPrinterMode = pPrinter->GetMapMode();
		    MapMode aLocalMode( MAP_TWIP );
		    pPrinter->SetMapMode( aLocalMode );
		    pPrinter->SetPaperSizeUser( aEnumSize );
		    pPrinter->SetMapMode( aPrinterMode );
        }

		pPrinter->SetPaperBin( nPaperBin );
	}
}

//--------------------------------------------------------------------
//	rPageRanges   = Range fuer alle Tabellen
//	nStartPage	  = in rPageRanges beginnen bei nStartPage
//	nDisplayStart = lfd. Nummer fuer Anzeige der Seitennummer

long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges,
								long nStartPage, long nDisplayStart, sal_Bool bDoPrint,
                                ScPreviewLocationData* pLocationData )
{
	DBG_ASSERT(pDev,"Device == NULL");
	if (!pParamSet)
		return 0;

	if ( pPrinter && bDoPrint )
		ApplyPrintSettings();

	//--------------------------------------------------------------------

	InitModes();
	if ( pLocationData )
	{
		pLocationData->SetCellMapMode( aOffsetMode );
		pLocationData->SetPrintTab( nPrintTab );
	}

	MakeTableString();

	//--------------------------------------------------------------------

	long nPageNo = 0;
	long nPrinted = 0;
	long nEndPage = rPageRanges.GetTotalRange().Max();

	sal_uInt16 nRepeats = 1;					// wie oft durchgehen ?
	if (bMultiArea)
		nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
	for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
	{
		if (bMultiArea)						// Bereich neu belegen ?
		{
			CalcZoom(nStep);				// setzt auch nStartCol etc. neu
			InitModes();
		}

		SCCOL nX1;
		SCROW nY1;
		SCCOL nX2;
		SCROW nY2;
		size_t nCountX;
		size_t nCountY;

		if (aTableParam.bTopDown)							// von oben nach unten
		{
			nX1 = nStartCol;
			for (nCountX=0; nCountX<nPagesX; nCountX++)
			{
                OSL_ENSURE(nCountX < maPageEndX.size(), "vector access error for maPageEndX (!)");
				nX2 = maPageEndX[nCountX];
				for (nCountY=0; nCountY<nPagesY; nCountY++)
				{
                    OSL_ENSURE(nCountY < maPageRows.size(), "vector access error for maPageRows (!)");
					nY1 = maPageRows[nCountY].GetStartRow();
					nY2 = maPageRows[nCountY].GetEndRow();
					if ( !aTableParam.bSkipEmpty || !maPageRows[nCountY].IsHidden(nCountX) )
					{
						if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
						{
							PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
										bDoPrint, pLocationData );
							++nPrinted;
						}
						++nPageNo;
					}
				}
				nX1 = nX2 + 1;
			}
		}
		else												// von links nach rechts
		{
			for (nCountY=0; nCountY<nPagesY; nCountY++)
			{
                OSL_ENSURE(nCountY < maPageRows.size(), "vector access error for maPageRows (!)");
				nY1 = maPageRows[nCountY].GetStartRow();
				nY2 = maPageRows[nCountY].GetEndRow();
				nX1 = nStartCol;
				for (nCountX=0; nCountX<nPagesX; nCountX++)
				{
                    OSL_ENSURE(nCountX < maPageEndX.size(), "vector access error for maPageEndX (!)");
					nX2 = maPageEndX[nCountX];
					if ( !aTableParam.bSkipEmpty || !maPageRows[nCountY].IsHidden(nCountX) )
					{
						if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
						{
							PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
										bDoPrint, pLocationData );
							++nPrinted;
						}
						++nPageNo;
					}
					nX1 = nX2 + 1;
				}
			}
		}
	}

	aFieldData.aTabName = ScGlobal::GetRscString( STR_NOTES );

	long nNoteNr = 0;
	long nNoteAdd;
	do
	{
		if ( nPageNo+nStartPage <= nEndPage )
		{
			sal_Bool bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 );
			nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected,
									( bPageSelected ? pLocationData : NULL ) );
			if ( nNoteAdd )
			{
				nNoteNr += nNoteAdd;
				if (bPageSelected)
				{
					++nPrinted;
					bSourceRangeValid = sal_False;		// last page was no cell range
				}
				++nPageNo;
			}
		}
		else
			nNoteAdd = 0;
	}
	while (nNoteAdd);

	if ( bMultiArea )
		ResetBreaks(nPrintTab);							// Breaks fuer Anzeige richtig

	return nPrinted;
}

void ScPrintFunc::CalcZoom( sal_uInt16 nRangeNo )						// Zoom berechnen
{
	sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
	const ScRange* pThisRange = NULL;
	if ( nRangeNo != RANGENO_NORANGE || nRangeNo < nRCount )
		pThisRange = pDoc->GetPrintRange( nPrintTab, nRangeNo );
	if ( pThisRange )
	{
		nStartCol = pThisRange->aStart.Col();
		nStartRow = pThisRange->aStart.Row();
		nEndCol   = pThisRange->aEnd  .Col();
		nEndRow   = pThisRange->aEnd  .Row();
	}

	if (!AdjustPrintArea(sal_False))						// leer
	{
		nZoom = 100;
		nPagesX = nPagesY = nTotalY = 0;
		return;
	}

	pDoc->SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );

	if (aTableParam.bScalePageNum)
	{
		nZoom = 100;
		sal_uInt16 nPagesToFit = aTableParam.nScalePageNum;

        sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
        while (true)
        {
            if (nZoom <= ZOOM_MIN)
                break;

            CalcPages();
            bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit);

            if (bFitsPage)
            {
                if (nZoom == 100)
                    // If it fits at 100 %, it's good enough for me.
                    break;
                
                nLastFitZoom = nZoom;
                nZoom = (nLastNonFitZoom + nZoom) / 2;

                if (nLastFitZoom == nZoom)
                    // It converged.  Use this zoom level.
                    break;
            }
            else
            {
                if (nZoom - nLastFitZoom <= 1)
                {
                    nZoom = nLastFitZoom;
                    CalcPages();
                    break;
                }

                nLastNonFitZoom = nZoom;
                nZoom = (nLastFitZoom + nZoom) / 2;
            }
        }
	}
    else if (aTableParam.bScaleTo)
    {
        nZoom = 100;
        sal_uInt16 nW = aTableParam.nScaleWidth;
        sal_uInt16 nH = aTableParam.nScaleHeight;

        sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
        while (true)
        {
            if (nZoom <= ZOOM_MIN)
                break;

            CalcPages();
            bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH)));

            if (bFitsPage)
            {
                if (nZoom == 100)
                    // If it fits at 100 %, it's good enough for me.
                    break;
                
                nLastFitZoom = nZoom;
                nZoom = (nLastNonFitZoom + nZoom) / 2;

                if (nLastFitZoom == nZoom)
                    // It converged.  Use this zoom level.
                    break;
            }
            else
            {
                if (nZoom - nLastFitZoom <= 1)
                {
                    nZoom = nLastFitZoom;
                    CalcPages();
                    break;
                }

                nLastNonFitZoom = nZoom;
                nZoom = (nLastFitZoom + nZoom) / 2;
            }
        }
    }
	else if (aTableParam.bScaleAll)
	{
		nZoom = aTableParam.nScaleAll;
		if ( nZoom <= ZOOM_MIN )
			nZoom = ZOOM_MIN;
		CalcPages();
	}
	else
	{
		DBG_ASSERT( aTableParam.bScaleNone, "kein Scale-Flag gesetzt" );
		nZoom = 100;
		CalcPages();
	}
}

Size ScPrintFunc::GetDocPageSize()
{
						// Hoehe Kopf-/Fusszeile anpassen

	InitModes();							// aTwipMode aus nZoom initialisieren
	pDev->SetMapMode( aTwipMode );			// Kopf-/Fusszeilen in Twips
	UpdateHFHeight( aHdr );
	UpdateHFHeight( aFtr );

						// Seitengroesse in Document-Twips
						// 	Berechnung Left / Right auch in PrintPage

	aPageRect = Rectangle( Point(), aPageSize );
	aPageRect.Left()   = ( aPageRect.Left()   + nLeftMargin					 ) * 100 / nZoom;
	aPageRect.Right()  = ( aPageRect.Right()  - nRightMargin				 ) * 100 / nZoom;
	aPageRect.Top()    = ( aPageRect.Top()    + nTopMargin    ) * 100 / nZoom + aHdr.nHeight;
	aPageRect.Bottom() = ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight;

	Size aDocPageSize = aPageRect.GetSize();
	if (aTableParam.bHeaders)
	{
		aDocPageSize.Width()  -= (long) PRINT_HEADER_WIDTH;
		aDocPageSize.Height() -= (long) PRINT_HEADER_HEIGHT;
	}
	if (pBorderItem)
	{
		aDocPageSize.Width()  -= lcl_LineTotal(pBorderItem->GetLeft()) +
								 lcl_LineTotal(pBorderItem->GetRight()) +
								 pBorderItem->GetDistance(BOX_LINE_LEFT) +
								 pBorderItem->GetDistance(BOX_LINE_RIGHT);
		aDocPageSize.Height() -= lcl_LineTotal(pBorderItem->GetTop()) +
								 lcl_LineTotal(pBorderItem->GetBottom()) +
								 pBorderItem->GetDistance(BOX_LINE_TOP) +
								 pBorderItem->GetDistance(BOX_LINE_BOTTOM);
	}
	if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
	{
		aDocPageSize.Width()  -= pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
								 pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
		aDocPageSize.Height() -= pShadowItem->CalcShadowSpace(SHADOW_TOP) +
								 pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
	}
	return aDocPageSize;
}

void ScPrintFunc::ResetBreaks( SCTAB nTab )			// Breaks fuer Anzeige richtig setzen
{
	pDoc->SetPageSize( nTab, GetDocPageSize() );
	pDoc->UpdatePageBreaks( nTab, NULL );
}

void lcl_SetHidden( ScDocument* pDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry, SCCOL nStartCol, const std::vector< SCCOL >& aPageEndX)
{
	size_t nPagesX   = rPageRowEntry.GetPagesX();
	SCROW nStartRow = rPageRowEntry.GetStartRow();
	SCROW nEndRow   = rPageRowEntry.GetEndRow();

	sal_Bool bLeftIsEmpty = sal_False;
	ScRange aTempRange;
	Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 );

	for (size_t i=0; i<nPagesX; i++)
	{
        OSL_ENSURE(i < aPageEndX.size(), "vector access error for maPageEndX (!)");
		SCCOL nEndCol = aPageEndX[i];
		if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow,
									bLeftIsEmpty, &aTempRange, &aTempRect ) )
		{
			rPageRowEntry.SetHidden(i);
			bLeftIsEmpty = sal_True;
		}
		else
			bLeftIsEmpty = sal_False;

		nStartCol = nEndCol+1;
	}
}

void ScPrintFunc::CalcPages()               // berechnet aPageRect und Seiten aus nZoom
{
    // #123672# use dynamic mem to react on size changes
    if(maPageEndX.size() < MAXCOL+1)
    {
        maPageEndX.resize(MAXCOL+1, SCCOL());
    }

    pDoc->SetPageSize( nPrintTab, GetDocPageSize() );
    if (aAreaParam.bPrintArea)
    {
        ScRange aRange( nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab );
        pDoc->UpdatePageBreaks( nPrintTab, &aRange );
    }
    else
    {
        pDoc->UpdatePageBreaks( nPrintTab, NULL );      // sonst wird das Ende markiert
    }

    const SCROW nRealCnt = nEndRow-nStartRow+1;

    // #123672# use dynamic mem to react on size changes
    if(maPageEndY.size() < nRealCnt+1)
    {
        maPageEndY.resize(nRealCnt+1, SCROW());
    }

    // #123672# use dynamic mem to react on size changes
    if(maPageRows.size() < nRealCnt+1)
    {
        maPageRows.resize(nRealCnt+1, ScPageRowEntry());
    }

    //
    //  Seiteneinteilung nach Umbruechen in Col/RowFlags
    //  Von mehreren Umbruechen in einem ausgeblendeten Bereich zaehlt nur einer.
    //

    nPagesX = 0;
    nPagesY = 0;
    nTotalY = 0;

    bool bVisCol = false;
    SCCOL nLastCol = -1;
    for (SCCOL i=nStartCol; i<=nEndCol; i++)
    {
        bool bHidden = pDoc->ColHidden(i, nPrintTab, nLastCol);
        bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE);
        if ( i>nStartCol && bVisCol && bPageBreak )
        {
            OSL_ENSURE(nPagesX < maPageEndX.size(), "vector access error for maPageEndX (!)");
            maPageEndX[nPagesX] = i-1;
            ++nPagesX;
            bVisCol = false;
        }
        if (!bHidden)
            bVisCol = true;
    }
    if (bVisCol)    // auch am Ende keine leeren Seiten
    {
        OSL_ENSURE(nPagesX < maPageEndX.size(), "vector access error for maPageEndX (!)");
        maPageEndX[nPagesX] = nEndCol;
        ++nPagesX;
    }

    bool bVisRow = false;
    SCROW nPageStartRow = nStartRow;
    SCROW nLastVisibleRow = -1;

    ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab));
    SCROW nNextPageBreak = pRowBreakIter->first();
    while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow)
        // Skip until the page break position is at the start row or greater.
        nNextPageBreak = pRowBreakIter->next();

    for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
    {
        bool bPageBreak = (nNextPageBreak == nRow);
        if (bPageBreak)
            nNextPageBreak = pRowBreakIter->next();

        if (nRow > nStartRow && bVisRow && bPageBreak )
        {
            OSL_ENSURE(nTotalY < maPageEndY.size(), "vector access error for maPageEndY (!)");
            maPageEndY[nTotalY] = nRow-1;
            ++nTotalY;

            if ( !aTableParam.bSkipEmpty ||
                    !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) )
            {
                OSL_ENSURE(nPagesY < maPageRows.size(), "vector access error for maPageRows (!)");
                maPageRows[nPagesY].SetStartRow( nPageStartRow );
                maPageRows[nPagesY].SetEndRow( nRow-1 );
                maPageRows[nPagesY].SetPagesX( nPagesX );
                if (aTableParam.bSkipEmpty)
                    lcl_SetHidden( pDoc, nPrintTab, maPageRows[nPagesY], nStartCol, maPageEndX );
                ++nPagesY;
            }

            nPageStartRow = nRow;
            bVisRow = false;
        }

        if (nRow <= nLastVisibleRow)
        {
            // This row is still visible.  Don't bother calling RowHidden() to
            // find out, for speed optimization.
            bVisRow = true;
            continue;
        }

        SCROW nLastRow = -1;
        if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow))
        {    
            bVisRow = true;
            nLastVisibleRow = nLastRow;
        }
        else
            // skip all hidden rows.
            nRow = nLastRow;
    }

    if (bVisRow)
    {
        OSL_ENSURE(nTotalY < maPageEndY.size(), "vector access error for maPageEndY (!)");
        maPageEndY[nTotalY] = nEndRow;
        ++nTotalY;

        if ( !aTableParam.bSkipEmpty ||
                !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) )
        {
            OSL_ENSURE(nPagesY < maPageRows.size(), "vector access error for maPageRows (!)");
            maPageRows[nPagesY].SetStartRow( nPageStartRow );
            maPageRows[nPagesY].SetEndRow( nEndRow );
            maPageRows[nPagesY].SetPagesX( nPagesX );
            if (aTableParam.bSkipEmpty)
                lcl_SetHidden( pDoc, nPrintTab, maPageRows[nPagesY], nStartCol, maPageEndX );
            ++nPagesY;
        }
    }
}

//------------------------------------------------------------------------
//	class ScJobSetup
//------------------------------------------------------------------------

ScJobSetup::ScJobSetup( SfxPrinter* pPrinter )
{
	eOrientation = pPrinter->GetOrientation();
	nPaperBin	 = pPrinter->GetPaperBin();
	ePaper		 = pPrinter->GetPaper();

	if ( PAPER_USER == ePaper )
	{
		aUserSize = pPrinter->GetPaperSize();
		aUserMapMode = pPrinter->GetMapMode();
	}
};





