/**************************************************************
 * 
 * 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_svtools.hxx"

#define ENABLE_BYTESTRING_STREAM_OPERATORS

#include <algorithm>

#include <tools/vcompat.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <unotools/localfilehelper.hxx>
#include <unotools/tempfile.hxx>
#include <vcl/svapp.hxx>
#include <vcl/cvtgrf.hxx>
#include <vcl/metaact.hxx>
#include <vcl/virdev.hxx>
#include <vcl/salbtype.hxx>
#include <unotools/cacheoptions.hxx>
#include <svtools/grfmgr.hxx>

// --> OD 2010-01-04 #i105243#
#include <vcl/pdfextoutdevdata.hxx>
// <--

// -----------
// - Defines -
// -----------

#define WATERMARK_LUM_OFFSET				50
#define WATERMARK_CON_OFFSET				-70

// -----------
// - statics -
// -----------

GraphicManager* GraphicObject::mpGlobalMgr = NULL;

// ---------------------
// - GrfDirectCacheObj -
// ---------------------

struct GrfSimpleCacheObj
{
	Graphic		maGraphic;
	GraphicAttr	maAttr;

				GrfSimpleCacheObj( const Graphic& rGraphic, const GraphicAttr& rAttr ) :
					maGraphic( rGraphic ), maAttr( rAttr ) {}
};

// -----------------
// - GraphicObject -
// -----------------

TYPEINIT1_AUTOFACTORY( GraphicObject, SvDataCopyStream );

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

GraphicObject::GraphicObject( const GraphicManager* pMgr ) :
	mpLink		( NULL ),
	mpUserData	( NULL )
{
	ImplConstruct();
	ImplAssignGraphicData();
	ImplSetGraphicManager( pMgr );
}

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

GraphicObject::GraphicObject( const Graphic& rGraphic, const GraphicManager* pMgr ) :
	maGraphic	( rGraphic ),
	mpLink		( NULL ),
	mpUserData	( NULL )
{
	ImplConstruct();
	ImplAssignGraphicData();
	ImplSetGraphicManager( pMgr );
}

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

GraphicObject::GraphicObject( const Graphic& rGraphic, const String& rLink, const GraphicManager* pMgr ) :
	maGraphic	( rGraphic ),
	mpLink		( rLink.Len() ? ( new String( rLink ) ) : NULL ),
	mpUserData	( NULL )
{
	ImplConstruct();
	ImplAssignGraphicData();
	ImplSetGraphicManager( pMgr );
}

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

GraphicObject::GraphicObject( const GraphicObject& rGraphicObj, const GraphicManager* pMgr ) :
    SvDataCopyStream(),
	maGraphic	( rGraphicObj.GetGraphic() ),
	maAttr		( rGraphicObj.maAttr ),
	mpLink		( rGraphicObj.mpLink ? ( new String( *rGraphicObj.mpLink ) ) : NULL ),
	mpUserData	( rGraphicObj.mpUserData ? ( new String( *rGraphicObj.mpUserData ) ) : NULL )
{
	ImplConstruct();
	ImplAssignGraphicData();
	ImplSetGraphicManager( pMgr, NULL, &rGraphicObj );
}

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

GraphicObject::GraphicObject( const ByteString& rUniqueID, const GraphicManager* pMgr ) :
	mpLink		( NULL ),
	mpUserData	( NULL )
{
	ImplConstruct();

	// assign default properties
	ImplAssignGraphicData();

	ImplSetGraphicManager( pMgr, &rUniqueID );

	// update properties
	ImplAssignGraphicData();
}

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

GraphicObject::~GraphicObject()
{
	if( mpMgr )
	{
		mpMgr->ImplUnregisterObj( *this );

		if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() )
			delete mpGlobalMgr, mpGlobalMgr = NULL;
	}

	delete mpSwapOutTimer;
	delete mpSwapStreamHdl;
	delete mpLink;
	delete mpUserData;
	delete mpSimpleCache;
}

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

void GraphicObject::ImplConstruct()
{
	mpMgr = NULL;
	mpSwapStreamHdl = NULL;
	mpSwapOutTimer = NULL;
	mpSimpleCache = NULL;
    mnAnimationLoopCount = 0;
	mbAutoSwapped = sal_False;
	mbIsInSwapIn = sal_False;
	mbIsInSwapOut = sal_False;
}

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

void GraphicObject::ImplAssignGraphicData()
{
	maPrefSize = maGraphic.GetPrefSize();
	maPrefMapMode = maGraphic.GetPrefMapMode();
	mnSizeBytes = maGraphic.GetSizeBytes();
	meType = maGraphic.GetType();
	mbTransparent = maGraphic.IsTransparent();
	mbAlpha = maGraphic.IsAlpha();
	mbAnimated = maGraphic.IsAnimated();
	mbEPS = maGraphic.IsEPS();
    mnAnimationLoopCount = ( mbAnimated ? maGraphic.GetAnimationLoopCount() : 0 );
}

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

void GraphicObject::ImplSetGraphicManager( const GraphicManager* pMgr, const ByteString* pID, const GraphicObject* pCopyObj )
{
	if( !mpMgr || ( pMgr != mpMgr ) )
	{
		if( !pMgr && mpMgr && ( mpMgr == mpGlobalMgr ) )
			return;
		else
		{
			if( mpMgr )
			{
				mpMgr->ImplUnregisterObj( *this );

				if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() )
					delete mpGlobalMgr, mpGlobalMgr = NULL;
			}

			if( !pMgr )
			{
				if( !mpGlobalMgr )
				{
                    SvtCacheOptions aCacheOptions;

					mpGlobalMgr = new GraphicManager( aCacheOptions.GetGraphicManagerTotalCacheSize(),
                                                      aCacheOptions.GetGraphicManagerObjectCacheSize() );
                    mpGlobalMgr->SetCacheTimeout( aCacheOptions.GetGraphicManagerObjectReleaseTime() );
				}

				mpMgr = mpGlobalMgr;
			}
			else
				mpMgr = (GraphicManager*) pMgr;

			mpMgr->ImplRegisterObj( *this, maGraphic, pID, pCopyObj );
		}
	}
}

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

void GraphicObject::ImplAutoSwapIn()
{
	if( IsSwappedOut() )
	{
		if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
			mbAutoSwapped = sal_False;
		else
		{
			mbIsInSwapIn = sal_True;

			if( maGraphic.SwapIn() )
				mbAutoSwapped = sal_False;
			else
			{
				SvStream* pStream = GetSwapStream();

				if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
				{
					if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
					{
						if( HasLink() )
						{
							String aURLStr;

							if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( GetLink(), aURLStr ) )
							{
								SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_READ );

								if( pIStm )
								{
									(*pIStm) >> maGraphic;
									mbAutoSwapped = ( maGraphic.GetType() != GRAPHIC_NONE );
									delete pIStm;
								}
							}
						}
					}
					else if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
						mbAutoSwapped = !maGraphic.SwapIn();
					else if( GRFMGR_AUTOSWAPSTREAM_LOADED == pStream )
						mbAutoSwapped = maGraphic.IsSwapOut();
					else
					{
						mbAutoSwapped = !maGraphic.SwapIn( pStream );
						delete pStream;
					}
				}
				else
				{
					DBG_ASSERT( ( GRAPHIC_NONE == meType ) || ( GRAPHIC_DEFAULT == meType ),
								"GraphicObject::ImplAutoSwapIn: could not get stream to swap in graphic! (=>KA)" );
				}
			}

			mbIsInSwapIn = sal_False;

			if( !mbAutoSwapped && mpMgr )
				mpMgr->ImplGraphicObjectWasSwappedIn( *this );
		}
	}
}

// -----------------------------------------------------------------------------
sal_Bool GraphicObject::ImplGetCropParams( OutputDevice* pOut, Point& rPt, Size& rSz, const GraphicAttr* pAttr,
									   PolyPolygon& rClipPolyPoly, sal_Bool& bRectClipRegion ) const
{
	sal_Bool bRet = sal_False;

	if( GetType() != GRAPHIC_NONE )
	{
		Polygon			aClipPoly( Rectangle( rPt, rSz ) );
		const sal_uInt16	nRot10 = pAttr->GetRotation() % 3600;
		const Point		aOldOrigin( rPt );
        // --> OD 2005-09-30 #i54875# - It's not needed to get the graphic again.
//        const Graphic&  rGraphic = GetGraphic();
        // <--
		const MapMode	aMap100( MAP_100TH_MM );
		Size			aSize100;
		long			nTotalWidth, nTotalHeight;
		long			nNewLeft, nNewTop, nNewRight, nNewBottom;
		double			fScale;

		if( nRot10 )
		{
			aClipPoly.Rotate( rPt, nRot10 );
			bRectClipRegion = sal_False;
		}
		else
			bRectClipRegion = sal_True;

		rClipPolyPoly = aClipPoly;

        // --> OD 2005-09-30 #i54875# - directly access member <maGraphic> to
        // get <PrefSize> and <PrefMapMode>.
//        if( rGraphic.GetPrefMapMode() == MAP_PIXEL )
//            aSize100 = Application::GetDefaultDevice()->PixelToLogic( rGraphic.GetPrefSize(), aMap100 );
//        else
//            aSize100 = pOut->LogicToLogic( rGraphic.GetPrefSize(), rGraphic.GetPrefMapMode(), aMap100 );
        if( maGraphic.GetPrefMapMode() == MAP_PIXEL )
            aSize100 = Application::GetDefaultDevice()->PixelToLogic( maGraphic.GetPrefSize(), aMap100 );
        else
        {
            MapMode m(maGraphic.GetPrefMapMode());
            aSize100 = pOut->LogicToLogic( maGraphic.GetPrefSize(), &m, &aMap100 );
        }
        // <--

		nTotalWidth = aSize100.Width() - pAttr->GetLeftCrop() - pAttr->GetRightCrop();
		nTotalHeight = aSize100.Height() - pAttr->GetTopCrop() - pAttr->GetBottomCrop();

		if( aSize100.Width() > 0 && aSize100.Height() > 0 && nTotalWidth > 0 && nTotalHeight > 0 )
		{
			fScale = (double) aSize100.Width() / nTotalWidth;
			nNewLeft = -FRound( ( ( pAttr->GetMirrorFlags() & BMP_MIRROR_HORZ ) ? pAttr->GetRightCrop() : pAttr->GetLeftCrop() ) * fScale );
			nNewRight = nNewLeft + FRound( aSize100.Width() * fScale ) - 1;

			fScale = (double) rSz.Width() / aSize100.Width();
			rPt.X() += FRound( nNewLeft * fScale );
			rSz.Width() = FRound( ( nNewRight - nNewLeft + 1 ) * fScale );

			fScale = (double) aSize100.Height() / nTotalHeight;
			nNewTop = -FRound( ( ( pAttr->GetMirrorFlags() & BMP_MIRROR_VERT ) ? pAttr->GetBottomCrop() : pAttr->GetTopCrop() ) * fScale );
			nNewBottom = nNewTop + FRound( aSize100.Height() * fScale ) - 1;

			fScale = (double) rSz.Height() / aSize100.Height();
			rPt.Y() += FRound( nNewTop * fScale );
			rSz.Height() = FRound( ( nNewBottom - nNewTop + 1 ) * fScale );

			if( nRot10 )
			{
				Polygon aOriginPoly( 1 );

				aOriginPoly[ 0 ] = rPt;
				aOriginPoly.Rotate( aOldOrigin, nRot10 );
				rPt = aOriginPoly[ 0 ];
			}

			bRet = sal_True;
		}
	}

	return bRet;
}

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

GraphicObject& GraphicObject::operator=( const GraphicObject& rGraphicObj )
{
	if( &rGraphicObj != this )
	{
		mpMgr->ImplUnregisterObj( *this );

		delete mpSwapStreamHdl, mpSwapStreamHdl = NULL;
		delete mpSimpleCache, mpSimpleCache = NULL;
		delete mpLink;
		delete mpUserData;

		maGraphic = rGraphicObj.GetGraphic();
		maAttr = rGraphicObj.maAttr;
		mpLink = rGraphicObj.mpLink ? new String( *rGraphicObj.mpLink ) : NULL;
		mpUserData = rGraphicObj.mpUserData ? new String( *rGraphicObj.mpUserData ) : NULL;
		ImplAssignGraphicData();
		mbAutoSwapped = sal_False;
		mpMgr = rGraphicObj.mpMgr;

		mpMgr->ImplRegisterObj( *this, maGraphic, NULL, &rGraphicObj );
	}

	return *this;
}

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

sal_Bool GraphicObject::operator==( const GraphicObject& rGraphicObj ) const
{
	return(	( rGraphicObj.maGraphic == maGraphic ) &&
			( rGraphicObj.maAttr == maAttr ) &&
			( rGraphicObj.GetLink() == GetLink() ) );
}

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

void GraphicObject::Load( SvStream& rIStm )
{
    rIStm >> *this;
}

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

void GraphicObject::Save( SvStream& rOStm )
{
    rOStm << *this;
}

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

void GraphicObject::Assign( const SvDataCopyStream& rCopyStream )
{
    *this = (const GraphicObject& ) rCopyStream;
}

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

ByteString GraphicObject::GetUniqueID() const
{
	if ( !IsInSwapIn() && IsEPS() )
		const_cast<GraphicObject*>(this)->FireSwapInRequest();

	ByteString aRet;

	if( mpMgr )
		aRet = mpMgr->ImplGetUniqueID( *this );

	return aRet;
}

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

sal_uLong GraphicObject::GetChecksum() const
{
	return( ( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() ) ? maGraphic.GetChecksum() : 0 );
}

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

SvStream* GraphicObject::GetSwapStream() const
{
	return( HasSwapStreamHdl() ? (SvStream*) mpSwapStreamHdl->Call( (void*) this ) : GRFMGR_AUTOSWAPSTREAM_NONE );
}

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

// !!! to be removed
sal_uLong GraphicObject::GetReleaseFromCache() const
{
	return 0;
}

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

void GraphicObject::SetAttr( const GraphicAttr& rAttr )
{
	maAttr = rAttr;

	if( mpSimpleCache && ( mpSimpleCache->maAttr != rAttr ) )
		delete mpSimpleCache, mpSimpleCache = NULL;
}

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

void GraphicObject::SetLink()
{
	if( mpLink )
		delete mpLink, mpLink = NULL;
}

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

void GraphicObject::SetLink( const String& rLink )
{
	delete mpLink, mpLink = new String( rLink );
}

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

String GraphicObject::GetLink() const
{
	if( mpLink )
		return *mpLink;
	else
		return String();
}

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

void GraphicObject::SetUserData()
{
	if( mpUserData )
		delete mpUserData, mpUserData = NULL;
}

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

void GraphicObject::SetUserData( const String& rUserData )
{
	delete mpUserData, mpUserData = new String( rUserData );
}

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

String GraphicObject::GetUserData() const
{
	if( mpUserData )
		return *mpUserData;
	else
		return String();
}

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

void GraphicObject::SetSwapStreamHdl()
{
	if( mpSwapStreamHdl )
	{
		delete mpSwapOutTimer, mpSwapOutTimer = NULL;
		delete mpSwapStreamHdl, mpSwapStreamHdl = NULL;
	}
}

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

void GraphicObject::SetSwapStreamHdl( const Link& rHdl, const sal_uLong nSwapOutTimeout )
{
	delete mpSwapStreamHdl,	mpSwapStreamHdl = new Link( rHdl );

	if( nSwapOutTimeout )
	{
		if( !mpSwapOutTimer )
		{
			mpSwapOutTimer = new Timer;
			mpSwapOutTimer->SetTimeoutHdl( LINK( this, GraphicObject, ImplAutoSwapOutHdl ) );
		}

		mpSwapOutTimer->SetTimeout( nSwapOutTimeout );
		mpSwapOutTimer->Start();
	}
	else
		delete mpSwapOutTimer, mpSwapOutTimer = NULL;
}

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

Link GraphicObject::GetSwapStreamHdl() const
{
	if( mpSwapStreamHdl )
		return *mpSwapStreamHdl;
	else
		return Link();
}

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

void GraphicObject::FireSwapInRequest()
{
	ImplAutoSwapIn();
}

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

void GraphicObject::FireSwapOutRequest()
{
	ImplAutoSwapOutHdl( NULL );
}

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

void GraphicObject::GraphicManagerDestroyed()
{
	// we're alive, but our manager doesn't live anymore ==> connect to default manager
	mpMgr = NULL;
	ImplSetGraphicManager( NULL );
}

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

void GraphicObject::SetGraphicManager( const GraphicManager& rMgr )
{
	ImplSetGraphicManager( &rMgr );
}

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

sal_Bool GraphicObject::IsCached( OutputDevice* pOut, const Point& rPt, const Size& rSz,
							  const GraphicAttr* pAttr, sal_uLong nFlags ) const
{
	sal_Bool bRet;

	if( nFlags & GRFMGR_DRAW_CACHED )
    {
        // --> OD 2005-10-11 #i54875# - Consider cropped graphics.
        // Note: The graphic manager caches a cropped graphic with its
        //       uncropped position and size.
//        bRet = mpMgr->IsInCache( pOut, rPt, rSz, *this, ( pAttr ? *pAttr : GetAttr() ) );
        Point aPt( rPt );
        Size aSz( rSz );
        if ( pAttr->IsCropped() )
        {
            PolyPolygon aClipPolyPoly;
            sal_Bool        bRectClip;
            ImplGetCropParams( pOut, aPt, aSz, pAttr, aClipPolyPoly, bRectClip );
        }
        bRet = mpMgr->IsInCache( pOut, aPt, aSz, *this, ( pAttr ? *pAttr : GetAttr() ) );
    }
	else
		bRet = sal_False;

	return bRet;
}

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

void GraphicObject::ReleaseFromCache()
{

	mpMgr->ReleaseFromCache( *this );
}

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

void GraphicObject::SetAnimationNotifyHdl( const Link& rLink )
{
	maGraphic.SetAnimationNotifyHdl( rLink );
}

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

List* GraphicObject::GetAnimationInfoList() const
{
	return maGraphic.GetAnimationInfoList();
}

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

sal_Bool GraphicObject::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
						  const GraphicAttr* pAttr, sal_uLong nFlags )
{
	GraphicAttr	        aAttr( pAttr ? *pAttr : GetAttr() );
	Point 		        aPt( rPt );
	Size  	            aSz( rSz );
    const sal_uInt32    nOldDrawMode = pOut->GetDrawMode();
	sal_Bool		        bCropped = aAttr.IsCropped();
	sal_Bool		        bCached = sal_False;
	sal_Bool		        bRet;

    // #i29534# Provide output rects for PDF writer
    Rectangle			aCropRect;

    if( !( GRFMGR_DRAW_USE_DRAWMODE_SETTINGS & nFlags ) )
        pOut->SetDrawMode( nOldDrawMode & ( ~( DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT ) ) );

	// mirrored horizontically
	if( aSz.Width() < 0L )
	{
		aPt.X() += aSz.Width() + 1;
		aSz.Width() = -aSz.Width();
		aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_HORZ );
	}

	// mirrored vertically
	if( aSz.Height() < 0L )
	{
		aPt.Y() += aSz.Height() + 1;
		aSz.Height() = -aSz.Height();
		aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_VERT );
	}

	if( bCropped )
	{
		PolyPolygon aClipPolyPoly;
		sal_Bool		bRectClip;
		const sal_Bool	bCrop = ImplGetCropParams( pOut, aPt, aSz, &aAttr, aClipPolyPoly, bRectClip );

		pOut->Push( PUSH_CLIPREGION );

		if( bCrop )
		{
			if( bRectClip )
            {
                // #i29534# Store crop rect for later forwarding to
                // PDF writer
                aCropRect = aClipPolyPoly.GetBoundRect();
				pOut->IntersectClipRegion( aCropRect );
            }
			else
            {
				pOut->IntersectClipRegion( aClipPolyPoly );
            }
		}
	}

	bRet = mpMgr->DrawObj( pOut, aPt, aSz, *this, aAttr, nFlags, bCached );

	if( bCropped )
		pOut->Pop();

    pOut->SetDrawMode( nOldDrawMode );

    // #i29534# Moved below OutDev restoration, to avoid multiple swap-ins
    // (code above needs to call GetGraphic twice)
	if( bCached )
	{
		if( mpSwapOutTimer )
			mpSwapOutTimer->Start();
		else
			FireSwapOutRequest();
	}

	return bRet;
}

// --> OD 2010-01-04 #i105243#
sal_Bool GraphicObject::DrawWithPDFHandling( OutputDevice& rOutDev,
                                         const Point& rPt, const Size& rSz,
                                         const GraphicAttr* pGrfAttr,
                                         const sal_uLong nFlags )
{
    const GraphicAttr aGrfAttr( pGrfAttr ? *pGrfAttr : GetAttr() );

    // Notify PDF writer about linked graphic (if any)
    sal_Bool bWritingPdfLinkedGraphic( sal_False );
    Point aPt( rPt );
    Size aSz( rSz );
    Rectangle aCropRect;
    vcl::PDFExtOutDevData* pPDFExtOutDevData =
            dynamic_cast<vcl::PDFExtOutDevData*>(rOutDev.GetExtOutDevData());
    if( pPDFExtOutDevData )
    {
        // only delegate image handling to PDF, if no special treatment is necessary
        if( GetGraphic().IsLink() &&
            rSz.Width() > 0L &&
            rSz.Height() > 0L &&
            !aGrfAttr.IsSpecialDrawMode() &&
            !aGrfAttr.IsMirrored() &&
            !aGrfAttr.IsRotated() &&
            !aGrfAttr.IsAdjusted() )
        {
            bWritingPdfLinkedGraphic = true;

            if( aGrfAttr.IsCropped() )
            {
                PolyPolygon aClipPolyPoly;
                sal_Bool bRectClip;
                const sal_Bool bCrop = ImplGetCropParams( &rOutDev,
                                                      aPt, aSz,
                                                      &aGrfAttr,
                                                      aClipPolyPoly,
                                                      bRectClip );
                if ( bCrop && bRectClip )
                {
                    aCropRect = aClipPolyPoly.GetBoundRect();
                }
            }

            pPDFExtOutDevData->BeginGroup();
        }
    }

    sal_Bool bRet = Draw( &rOutDev, rPt, rSz, &aGrfAttr, nFlags );

    // Notify PDF writer about linked graphic (if any)
    if( bWritingPdfLinkedGraphic )
    {
        pPDFExtOutDevData->EndGroup( const_cast< Graphic& >(GetGraphic()),
                                     aGrfAttr.GetTransparency(),
                                     Rectangle( aPt, aSz ),
                                     aCropRect );
    }

    return bRet;
}
// <--

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

sal_Bool GraphicObject::DrawTiled( OutputDevice* pOut, const Rectangle& rArea, const Size& rSize,
                               const Size& rOffset, const GraphicAttr* pAttr, sal_uLong nFlags, int nTileCacheSize1D )
{
    if( pOut == NULL || rSize.Width() == 0 || rSize.Height() == 0 )
        return sal_False;

    const MapMode 	aOutMapMode( pOut->GetMapMode() );
    const MapMode	aMapMode( aOutMapMode.GetMapUnit(), Point(), aOutMapMode.GetScaleX(), aOutMapMode.GetScaleY() );
    // #106258# Clamp size to 1 for zero values. This is okay, since
    // logical size of zero is handled above already
    const Size		aOutTileSize( ::std::max( 1L, pOut->LogicToPixel( rSize, aOutMapMode ).Width() ),
                                  ::std::max( 1L, pOut->LogicToPixel( rSize, aOutMapMode ).Height() ) );

	//#i69780 clip final tile size to a sane max size
    while (((sal_Int64)rSize.Width() * nTileCacheSize1D) > SAL_MAX_UINT16)
        nTileCacheSize1D /= 2;
    while (((sal_Int64)rSize.Height() * nTileCacheSize1D) > SAL_MAX_UINT16)
        nTileCacheSize1D /= 2;

    return ImplDrawTiled( pOut, rArea, aOutTileSize, rOffset, pAttr, nFlags, nTileCacheSize1D );
}

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

sal_Bool GraphicObject::StartAnimation( OutputDevice* pOut, const Point& rPt, const Size& rSz,
									long nExtraData, const GraphicAttr* pAttr, sal_uLong /*nFlags*/,
									OutputDevice* pFirstFrameOutDev )
{
	sal_Bool bRet = sal_False;

	GetGraphic();

	if( !IsSwappedOut() )
	{
    	const GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() );

		if( mbAnimated )
		{
			Point   aPt( rPt );
			Size	aSz( rSz );
			sal_Bool	bCropped = aAttr.IsCropped();

			if( bCropped )
			{
				PolyPolygon aClipPolyPoly;
				sal_Bool		bRectClip;
				const sal_Bool	bCrop = ImplGetCropParams( pOut, aPt, aSz, &aAttr, aClipPolyPoly, bRectClip );

				pOut->Push( PUSH_CLIPREGION );

				if( bCrop )
				{
					if( bRectClip )
						pOut->IntersectClipRegion( aClipPolyPoly.GetBoundRect() );
					else
						pOut->IntersectClipRegion( aClipPolyPoly );
				}
			}

			if( !mpSimpleCache || ( mpSimpleCache->maAttr != aAttr ) || pFirstFrameOutDev )
			{
				if( mpSimpleCache )
					delete mpSimpleCache;

				mpSimpleCache = new GrfSimpleCacheObj( GetTransformedGraphic( &aAttr ), aAttr );
				mpSimpleCache->maGraphic.SetAnimationNotifyHdl( GetAnimationNotifyHdl() );
			}

			mpSimpleCache->maGraphic.StartAnimation( pOut, aPt, aSz, nExtraData, pFirstFrameOutDev );

			if( bCropped )
				pOut->Pop();

			bRet = sal_True;
		}
		else
			bRet = Draw( pOut, rPt, rSz, &aAttr, GRFMGR_DRAW_STANDARD );
	}

	return bRet;
}

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

void GraphicObject::StopAnimation( OutputDevice* pOut, long nExtraData )
{
	if( mpSimpleCache )
		mpSimpleCache->maGraphic.StopAnimation( pOut, nExtraData );
}

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

const Graphic& GraphicObject::GetGraphic() const
{
	if( mbAutoSwapped )
		( (GraphicObject*) this )->ImplAutoSwapIn();

	return maGraphic;
}

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

void GraphicObject::SetGraphic( const Graphic& rGraphic, const GraphicObject* pCopyObj )
{
	mpMgr->ImplUnregisterObj( *this );

	if( mpSwapOutTimer )
		mpSwapOutTimer->Stop();

	maGraphic = rGraphic;
	mbAutoSwapped = sal_False;
	ImplAssignGraphicData();
	delete mpLink, mpLink = NULL;
	delete mpSimpleCache, mpSimpleCache = NULL;

	mpMgr->ImplRegisterObj( *this, maGraphic, 0, pCopyObj);

	if( mpSwapOutTimer )
		mpSwapOutTimer->Start();
}

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

void GraphicObject::SetGraphic( const Graphic& rGraphic, const String& rLink )
{
	SetGraphic( rGraphic );
	mpLink = new String( rLink );
}

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

Graphic GraphicObject::GetTransformedGraphic( const Size& rDestSize, const MapMode& rDestMap, const GraphicAttr& rAttr ) const
{
    // #104550# Extracted from svx/source/svdraw/svdograf.cxx
	Graphic		    	aTransGraphic( maGraphic );
	const GraphicType	eType = GetType();
    const Size      	aSrcSize( aTransGraphic.GetPrefSize() );

    // #104115# Convert the crop margins to graphic object mapmode
    const MapMode aMapGraph( aTransGraphic.GetPrefMapMode() );
    const MapMode aMap100( MAP_100TH_MM );

    Size aCropLeftTop;
    Size aCropRightBottom;

    if( GRAPHIC_GDIMETAFILE == eType )
    {
        GDIMetaFile aMtf( aTransGraphic.GetGDIMetaFile() );

        if( aMapGraph == MAP_PIXEL )
        {
            aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetLeftCrop(),
                                                                                rAttr.GetTopCrop() ),
                                                                          aMap100 );
            aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetRightCrop(),
                                                                                    rAttr.GetBottomCrop() ),
                                                                              aMap100 );
        }
        else
        {
            aCropLeftTop = OutputDevice::LogicToLogic( Size( rAttr.GetLeftCrop(),
                                                             rAttr.GetTopCrop() ),
                                                       aMap100,
                                                       aMapGraph );
            aCropRightBottom = OutputDevice::LogicToLogic( Size( rAttr.GetRightCrop(),
                                                                 rAttr.GetBottomCrop() ),
                                                           aMap100,
                                                           aMapGraph );
        }

        // #104115# If the metafile is cropped, give it a special
        // treatment: clip against the remaining area, scale up such
        // that this area later fills the desired size, and move the
        // origin to the upper left edge of that area.
        if( rAttr.IsCropped() )
        {
            const MapMode aMtfMapMode( aMtf.GetPrefMapMode() );

            Rectangle aClipRect( aMtfMapMode.GetOrigin().X() + aCropLeftTop.Width(),
                                 aMtfMapMode.GetOrigin().Y() + aCropLeftTop.Height(),
                                 aMtfMapMode.GetOrigin().X() + aSrcSize.Width() - aCropRightBottom.Width(),
                                 aMtfMapMode.GetOrigin().Y() + aSrcSize.Height() - aCropRightBottom.Height() );

            // #104115# To correctly crop rotated metafiles, clip by view rectangle
            aMtf.AddAction( new MetaISectRectClipRegionAction( aClipRect ), 0 );

            // #104115# To crop the metafile, scale larger than the output rectangle
            aMtf.Scale( (double)rDestSize.Width() / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()),
                        (double)rDestSize.Height() / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) );

            // #104115# Adapt the pref size by hand (scale changes it
            // proportionally, but we want it to be smaller than the
            // former size, to crop the excess out)
            aMtf.SetPrefSize( Size( (long)((double)rDestSize.Width() *  (1.0 + (aCropLeftTop.Width() + aCropRightBottom.Width()) / aSrcSize.Width())  + .5),
                                    (long)((double)rDestSize.Height() * (1.0 + (aCropLeftTop.Height() + aCropRightBottom.Height()) / aSrcSize.Height()) + .5) ) );

            // #104115# Adapt the origin of the new mapmode, such that it
            // is shifted to the place where the cropped output starts
            Point aNewOrigin( (long)((double)aMtfMapMode.GetOrigin().X() + rDestSize.Width() * aCropLeftTop.Width() / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()) + .5),
                              (long)((double)aMtfMapMode.GetOrigin().Y() + rDestSize.Height() * aCropLeftTop.Height() / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) + .5) );
            MapMode aNewMap( rDestMap );
            aNewMap.SetOrigin( OutputDevice::LogicToLogic(aNewOrigin, aMtfMapMode, rDestMap) );
            aMtf.SetPrefMapMode( aNewMap );
        }
        else
        {
            aMtf.Scale( Fraction( rDestSize.Width(), aSrcSize.Width() ), Fraction( rDestSize.Height(), aSrcSize.Height() ) );
            aMtf.SetPrefMapMode( rDestMap );
        }

        aTransGraphic = aMtf;
    }
    else if( GRAPHIC_BITMAP == eType )
    {
        BitmapEx    aBitmapEx( aTransGraphic.GetBitmapEx() );

        // convert crops to pixel
        aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetLeftCrop(),
                                                                            rAttr.GetTopCrop() ),
                                                                      aMap100 );
        aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetRightCrop(),
                                                                                rAttr.GetBottomCrop() ),
                                                                          aMap100 );

        // convert from prefmapmode to pixel
        const Size aSrcSizePixel( Application::GetDefaultDevice()->LogicToPixel( aSrcSize,
                                                                                 aMapGraph ) );

        // setup crop rectangle in pixel
        Rectangle aCropRect( aCropLeftTop.Width(), aCropLeftTop.Height(),
                             aSrcSizePixel.Width() - aCropRightBottom.Width(),
                             aSrcSizePixel.Height() - aCropRightBottom.Height() );

        // #105641# Also crop animations
        if( aTransGraphic.IsAnimated() )
        {
            sal_uInt16 nFrame;
            Animation aAnim( aTransGraphic.GetAnimation() );

            for( nFrame=0; nFrame<aAnim.Count(); ++nFrame )
            {
                AnimationBitmap aAnimBmp( aAnim.Get( nFrame ) );

                if( !aCropRect.IsInside( Rectangle(aAnimBmp.aPosPix, aAnimBmp.aSizePix) ) )
                {
                    // setup actual cropping (relative to frame position)
                    Rectangle aCropRectRel( aCropRect );
                    aCropRectRel.Move( -aAnimBmp.aPosPix.X(),
                                       -aAnimBmp.aPosPix.Y() );

                    // cropping affects this frame, apply it then
                    // do _not_ apply enlargement, this is done below
                    ImplTransformBitmap( aAnimBmp.aBmpEx, rAttr, Size(), Size(),
                                         aCropRectRel, rDestSize, sal_False );

                    aAnim.Replace( aAnimBmp, nFrame );
                }
                // else: bitmap completely within crop area,
                // i.e. nothing is cropped away
            }

            // now, apply enlargement (if any) through global animation size
            if( aCropLeftTop.Width() < 0 ||
                aCropLeftTop.Height() < 0 ||
                aCropRightBottom.Width() < 0 ||
                aCropRightBottom.Height() < 0 )
            {
                Size aNewSize( aAnim.GetDisplaySizePixel() );
                aNewSize.Width() += aCropRightBottom.Width() < 0 ? -aCropRightBottom.Width() : 0;
                aNewSize.Width() += aCropLeftTop.Width() < 0 ? -aCropLeftTop.Width() : 0;
                aNewSize.Height() += aCropRightBottom.Height() < 0 ? -aCropRightBottom.Height() : 0;
                aNewSize.Height() += aCropLeftTop.Height() < 0 ? -aCropLeftTop.Height() : 0;
                aAnim.SetDisplaySizePixel( aNewSize );
            }

            // if topleft has changed, we must move all frames to the
            // right and bottom, resp.
            if( aCropLeftTop.Width() < 0 ||
                aCropLeftTop.Height() < 0 )
            {
                Point aPosOffset( aCropLeftTop.Width() < 0 ? -aCropLeftTop.Width() : 0,
                                  aCropLeftTop.Height() < 0 ? -aCropLeftTop.Height() : 0 );

                for( nFrame=0; nFrame<aAnim.Count(); ++nFrame )
                {
                    AnimationBitmap aAnimBmp( aAnim.Get( nFrame ) );

                    aAnimBmp.aPosPix += aPosOffset;

                    aAnim.Replace( aAnimBmp, nFrame );
                }
            }

            aTransGraphic = aAnim;
        }
        else
        {
            BitmapEx aBmpEx( aTransGraphic.GetBitmapEx() );

            ImplTransformBitmap( aBmpEx, rAttr, aCropLeftTop, aCropRightBottom,
                                 aCropRect, rDestSize, sal_True );

            aTransGraphic = aBmpEx;
        }

        aTransGraphic.SetPrefSize( rDestSize );
        aTransGraphic.SetPrefMapMode( rDestMap );
    }

    GraphicObject aGrfObj( aTransGraphic );
    aTransGraphic = aGrfObj.GetTransformedGraphic( &rAttr );

	return aTransGraphic;
}

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

Graphic GraphicObject::GetTransformedGraphic( const GraphicAttr* pAttr ) const // TODO: Change to Impl
{
	GetGraphic();

	Graphic     aGraphic;
    GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() );

	if( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() )
	{
		if( aAttr.IsSpecialDrawMode() || aAttr.IsAdjusted() || aAttr.IsMirrored() || aAttr.IsRotated() || aAttr.IsTransparent() )
		{
			if( GetType() == GRAPHIC_BITMAP )
			{
				if( IsAnimated() )
				{
					Animation aAnimation( maGraphic.GetAnimation() );
					GraphicManager::ImplAdjust( aAnimation, aAttr, ADJUSTMENT_ALL );
                    aAnimation.SetLoopCount( mnAnimationLoopCount );
					aGraphic = aAnimation;
				}
				else
				{
					BitmapEx aBmpEx( maGraphic.GetBitmapEx() );
					GraphicManager::ImplAdjust( aBmpEx, aAttr, ADJUSTMENT_ALL );
					aGraphic = aBmpEx;
				}
			}
			else
			{
				GDIMetaFile aMtf( maGraphic.GetGDIMetaFile() );
				GraphicManager::ImplAdjust( aMtf, aAttr, ADJUSTMENT_ALL );
				aGraphic = aMtf;
			}
		}
		else
        {
			if( ( GetType() == GRAPHIC_BITMAP ) && IsAnimated() )
			{
				Animation aAnimation( maGraphic.GetAnimation() );
                aAnimation.SetLoopCount( mnAnimationLoopCount );
				aGraphic = aAnimation;
			}
            else
			    aGraphic = maGraphic;
        }
	}

	return aGraphic;
}

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

void GraphicObject::ResetAnimationLoopCount()
{
	if( IsAnimated() && !IsSwappedOut() )
	{
		maGraphic.ResetAnimationLoopCount();

		if( mpSimpleCache )
			mpSimpleCache->maGraphic.ResetAnimationLoopCount();
	}
}

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

sal_Bool GraphicObject::SwapOut()
{
	sal_Bool bRet = ( !mbAutoSwapped ? maGraphic.SwapOut() : sal_False );

	if( bRet && mpMgr )
		mpMgr->ImplGraphicObjectWasSwappedOut( *this );

	return bRet;
}

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

sal_Bool GraphicObject::SwapOut( SvStream* pOStm )
{
	sal_Bool bRet = ( !mbAutoSwapped ? maGraphic.SwapOut( pOStm ) : sal_False );

	if( bRet && mpMgr )
		mpMgr->ImplGraphicObjectWasSwappedOut( *this );

	return bRet;
}

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

sal_Bool GraphicObject::SwapIn()
{
	sal_Bool bRet;

	if( mbAutoSwapped )
	{
		ImplAutoSwapIn();
		bRet = sal_True;
	}
	else if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
		bRet = sal_True;
	else
	{
		bRet = maGraphic.SwapIn();

		if( bRet && mpMgr )
			mpMgr->ImplGraphicObjectWasSwappedIn( *this );
	}

	if( bRet )
		ImplAssignGraphicData();

	return bRet;
}

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

sal_Bool GraphicObject::SwapIn( SvStream* pIStm )
{
	sal_Bool bRet;

	if( mbAutoSwapped )
	{
		ImplAutoSwapIn();
		bRet = sal_True;
	}
	else if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
		bRet = sal_True;
	else
	{
		bRet = maGraphic.SwapIn( pIStm );

		if( bRet && mpMgr )
			mpMgr->ImplGraphicObjectWasSwappedIn( *this );
	}

	if( bRet )
		ImplAssignGraphicData();

	return bRet;
}

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

void GraphicObject::SetSwapState()
{
	if( !IsSwappedOut() )
	{
		mbAutoSwapped = sal_True;

		if( mpMgr )
			mpMgr->ImplGraphicObjectWasSwappedOut( *this );
	}
}

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

IMPL_LINK( GraphicObject, ImplAutoSwapOutHdl, void*, EMPTYARG )
{
	if( !IsSwappedOut() )
	{
		mbIsInSwapOut = sal_True;

		SvStream* pStream = GetSwapStream();

		if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
		{
			if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
				mbAutoSwapped = SwapOut( NULL );
			else
			{
				if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
					mbAutoSwapped = SwapOut();
				else
				{
					mbAutoSwapped = SwapOut( pStream );
					delete pStream;
				}
			}
		}

		mbIsInSwapOut = sal_False;
	}

	if( mpSwapOutTimer )
		mpSwapOutTimer->Start();

	return 0L;
}

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

SvStream& operator>>( SvStream& rIStm, GraphicObject& rGraphicObj )
{
	VersionCompat	aCompat( rIStm, STREAM_READ );
	Graphic			aGraphic;
	GraphicAttr		aAttr;
	ByteString		aLink;
	sal_Bool			bLink;

	rIStm >> aGraphic >> aAttr >> bLink;

	rGraphicObj.SetGraphic( aGraphic );
	rGraphicObj.SetAttr( aAttr );

	if( bLink )
	{
		rIStm >> aLink;
		rGraphicObj.SetLink( UniString( aLink, RTL_TEXTENCODING_UTF8 ) );
	}
	else
		rGraphicObj.SetLink();

	rGraphicObj.SetSwapStreamHdl();

	return rIStm;
}

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

SvStream& operator<<( SvStream& rOStm, const GraphicObject& rGraphicObj )
{
	VersionCompat	aCompat( rOStm, STREAM_WRITE, 1 );
	const sal_Bool		bLink =  rGraphicObj.HasLink();

	rOStm << rGraphicObj.GetGraphic() << rGraphicObj.GetAttr() << bLink;

	if( bLink )
		rOStm << ByteString( rGraphicObj.GetLink(), RTL_TEXTENCODING_UTF8 );

	return rOStm;
}

#define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"

GraphicObject GraphicObject::CreateGraphicObjectFromURL( const ::rtl::OUString &rURL )
{
	const String aURL( rURL ), aPrefix( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX) );
	if( aURL.Search( aPrefix ) == 0 )
	{
		// graphic manager url
		ByteString aUniqueID( String(rURL.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX ) - 1 )), RTL_TEXTENCODING_UTF8 );
		return GraphicObject( aUniqueID );
	}
	else
	{
		Graphic		aGraphic;
		if ( aURL.Len() )
		{
			SvStream*	pStream = utl::UcbStreamHelper::CreateStream( aURL, STREAM_READ );
			if( pStream )
				GraphicConverter::Import( *pStream, aGraphic );
		}

		return GraphicObject( aGraphic );
	}
}
