<commit_before>/*************************************************************************
 *
 *  $RCSfile: svdograf.cxx,v $
 *
 *  $Revision: 1.45 $
 *
 *  last change: $Author: cl $ $Date: 2002-05-08 09:43:28 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#define _ANIMATION
#define ITEMID_GRF_CROP 0

#ifndef SVX_LIGHT
#include <so3/lnkbase.hxx>
#else
#include <svtools/pathoptions.hxx>
#endif

#include <math.h>
#include <vcl/salbtype.hxx>
#include <sot/formats.hxx>
#include <so3/svstor.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <unotools/localfilehelper.hxx>
#include <svtools/style.hxx>
#include <svtools/filter.hxx>
#include <svtools/urihelper.hxx>
#include <goodies/grfmgr.hxx>
#include "linkmgr.hxx"
#include "svdxout.hxx"
#include "svdio.hxx"
#include "svdetc.hxx"
#include "svdglob.hxx"
#include "svdstr.hrc"
#include "svdpool.hxx"
#include "svdmodel.hxx"
#include "svdpage.hxx"
#include "svdmrkv.hxx"
#include "svdpagv.hxx"
#include "svdviter.hxx"
#include "svdview.hxx"
#include "impgrf.hxx"
#include "svdograf.hxx"
#include "svdogrp.hxx"
#include "xbitmap.hxx"
#include "xbtmpit.hxx"
#include "xflbmtit.hxx"
#include "svdundo.hxx"
#include "svdfmtf.hxx"
#include "sdgcpitm.hxx"

#ifndef _EEITEM_HXX
#include "eeitem.hxx"
#endif

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

#define GRAFSTREAMPOS_INVALID 0xffffffff

#ifndef SVX_LIGHT

// ------------------
// - SdrGraphicLink -
// ------------------

class SdrGraphicLink : public so3::SvBaseLink
{
    SdrGrafObj*         pGrafObj;

public:
                        SdrGraphicLink(SdrGrafObj* pObj);
    virtual             ~SdrGraphicLink();

    virtual void        Closed();
    virtual void        DataChanged( const String& rMimeType,
                                const ::com::sun::star::uno::Any & rValue );

    BOOL                Connect() { return 0 != GetRealObject(); }
    void                UpdateSynchron();
};

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

SdrGraphicLink::SdrGraphicLink(SdrGrafObj* pObj):
    ::so3::SvBaseLink( ::so3::LINKUPDATE_ONCALL, SOT_FORMATSTR_ID_SVXB ),
    pGrafObj(pObj)
{
    SetSynchron( FALSE );
}

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

SdrGraphicLink::~SdrGraphicLink()
{
}

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

void SdrGraphicLink::DataChanged( const String& rMimeType,
                                const ::com::sun::star::uno::Any & rValue )
{
    SdrModel*       pModel      = pGrafObj ? pGrafObj->GetModel() : 0;
    SvxLinkManager* pLinkManager= pModel  ? pModel->GetLinkManager() : 0;

    if( pLinkManager && rValue.hasValue() )
    {
        pLinkManager->GetDisplayNames( this, 0, &pGrafObj->aFileName, 0, &pGrafObj->aFilterName );

        Graphic aGraphic;
        if( SvxLinkManager::GetGraphicFromAny( rMimeType, rValue, aGraphic ))
        {
            GraphicType eOldGraphicType = pGrafObj->GetGraphicType();  // kein Hereinswappen
            BOOL bIsChanged = pModel->IsChanged();

            pGrafObj->SetGraphic( aGraphic );
            if( GRAPHIC_NONE != eOldGraphicType )
                pGrafObj->SetChanged();
            else
                pModel->SetChanged( bIsChanged );
        }
        else if( SotExchange::GetFormatIdFromMimeType( rMimeType ) !=
                    SvxLinkManager::RegisterStatusInfoId() )
            pGrafObj->SendRepaintBroadcast();
    }
}

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

void SdrGraphicLink::Closed()
{
    // Die Verbindung wird aufgehoben; pLink des Objekts auf NULL setzen, da die Link-Instanz ja gerade destruiert wird.
    pGrafObj->ForceSwapIn();
    pGrafObj->pGraphicLink=NULL;
    pGrafObj->ReleaseGraphicLink();
    SvBaseLink::Closed();
}

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

void SdrGraphicLink::UpdateSynchron()
{
    if( GetObj() )
    {
        String aMimeType( SotExchange::GetFormatMimeType( GetContentType() ));
        ::com::sun::star::uno::Any aValue;
        GetObj()->GetData( aValue, aMimeType, TRUE );
        DataChanged( aMimeType, aValue );
    }
}

#else

GraphicFilter* SVX_LIGHT_pGrapicFilter = NULL;

GraphicFilter* GetGrfFilter()
{
    if( !SVX_LIGHT_pGrapicFilter )
    {
        const SvtPathOptions aPathOptions;

        SVX_LIGHT_pGrapicFilter = new GraphicFilter( FALSE );
        SVX_LIGHT_pGrapicFilter->SetFilterPath( aPathOptions.GetFilterPath() );
    }

    return SVX_LIGHT_pGrapicFilter;
}


#endif // SVX_LIGHT

// --------------
// - SdrGrafObj -
// --------------

TYPEINIT1(SdrGrafObj,SdrRectObj);

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

SdrGrafObj::SdrGrafObj():
    bMirrored       ( FALSE ),
    pGraphicLink    ( NULL )
{
    pGraphic = new GraphicObject;
    pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), Application::IsRemoteServer() ? 60000 : 20000 );
    nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    bNoShear = TRUE;
    bCopyToPoolOnAfterRead = FALSE;
}

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

SdrGrafObj::SdrGrafObj(const Graphic& rGrf, const Rectangle& rRect):
    SdrRectObj      ( rRect ),
    bMirrored       ( FALSE ),
    pGraphicLink    ( NULL )
{
    pGraphic = new GraphicObject( rGrf );
    pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), Application::IsRemoteServer() ? 60000 : 20000 );
    nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    bNoShear = TRUE;
    bCopyToPoolOnAfterRead = FALSE;
}

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

SdrGrafObj::SdrGrafObj( const Graphic& rGrf ):
    bMirrored       ( FALSE ),
    pGraphicLink    ( NULL )
{
    pGraphic = new GraphicObject( rGrf );
    pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), Application::IsRemoteServer() ? 60000 : 20000 );
    nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    bNoShear = TRUE;
    bCopyToPoolOnAfterRead = FALSE;
}

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

SdrGrafObj::~SdrGrafObj()
{
    delete pGraphic;
    ImpLinkAbmeldung();
}

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

void SdrGrafObj::SetGraphicObject( const GraphicObject& rGrfObj )
{
    *pGraphic = rGrfObj;
    pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), Application::IsRemoteServer() ? 60000 : 20000 );
    pGraphic->SetUserData();
    nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    SetChanged();
    SendRepaintBroadcast();
}

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

const GraphicObject& SdrGrafObj::GetGraphicObject() const
{
    ForceSwapIn();
    return *pGraphic;
}

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

void SdrGrafObj::SetGraphic( const Graphic& rGrf )
{
    pGraphic->SetGraphic( rGrf );
    pGraphic->SetUserData();
    nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    SetChanged();
    SendRepaintBroadcast();
}

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

const Graphic& SdrGrafObj::GetGraphic() const
{
    ForceSwapIn();
    return pGraphic->GetGraphic();
}

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

Graphic SdrGrafObj::GetTransformedGraphic( ULONG nTransformFlags ) const
{
    Graphic     aTransGraphic;
    GraphicType eType = GetGraphicType();

    if( SDRGRAFOBJ_TRANSFORMATTR_NONE == nTransformFlags )
        aTransGraphic = GetGraphic();
    else if( eType != GRAPHIC_NONE )
    {
        ( (SdrGrafObj*) this )->ImpSetAttrToGrafInfo();

        GraphicAttr aActAttr( aGrafInfo );

        if( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_MIRROR )
        {
            USHORT      nMirrorCase = ( aGeo.nDrehWink == 18000 ) ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 );
            FASTBOOL    bHMirr = nMirrorCase == 2 || nMirrorCase == 4;
            FASTBOOL    bVMirr = nMirrorCase == 3 || nMirrorCase == 4;

            aActAttr.SetMirrorFlags( ( bHMirr ? BMP_MIRROR_HORZ : 0 ) | ( bVMirr ? BMP_MIRROR_VERT : 0 ) );
        }

        if( ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_ROTATE ) &&
            ( aGeo.nDrehWink && aGeo.nDrehWink != 18000 ) && ( GRAPHIC_NONE != eType ) && !IsAnimated() )
        {
            aActAttr.SetRotation( aGeo.nDrehWink / 10 );
        }

        aTransGraphic = pGraphic->GetTransformedGraphic( &aActAttr );
    }

    return aTransGraphic;
}

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

GraphicType SdrGrafObj::GetGraphicType() const
{
    return pGraphic->GetType();
}

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

FASTBOOL SdrGrafObj::IsAnimated() const
{
    return pGraphic->IsAnimated();
}

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

FASTBOOL SdrGrafObj::IsTransparent() const
{
    return pGraphic->IsTransparent();
}

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

FASTBOOL SdrGrafObj::IsEPS() const
{
    return pGraphic->IsEPS();
}

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

const MapMode& SdrGrafObj::GetGrafPrefMapMode() const
{
    return pGraphic->GetPrefMapMode();
}

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

const Size& SdrGrafObj::GetGrafPrefSize() const
{
    return pGraphic->GetPrefSize();
}

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

void SdrGrafObj::SetGrafStreamURL( const String& rGraphicStreamURL )
{
    if( !rGraphicStreamURL.Len() )
    {
        pGraphic->SetUserData();
        nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    }
    else if( pModel->IsSwapGraphics() && ( pModel->GetSwapGraphicsMode() & SDR_SWAPGRAPHICSMODE_DOC ) )
    {
        pGraphic->SetUserData( rGraphicStreamURL );
        nGrafStreamPos = GRAFSTREAMPOS_INVALID;

        // set state of graphic object to 'swapped out'
        if( pGraphic->GetType() == GRAPHIC_NONE )
            pGraphic->SetSwapState();
    }
}

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

String SdrGrafObj::GetGrafStreamURL() const
{
    return pGraphic->GetUserData();
}

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

void SdrGrafObj::SetFileName(const String& rFileName)
{
    aFileName = rFileName;
    SetChanged();
}

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

void SdrGrafObj::SetFilterName(const String& rFilterName)
{
    aFilterName = rFilterName;
    SetChanged();
}

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

FASTBOOL SdrGrafObj::HasSetName() const
{
    return TRUE;
}

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

void SdrGrafObj::SetName(const XubString& rStr)
{
    aName = rStr;
    SetChanged();
}

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

XubString SdrGrafObj::GetName() const
{
    return aName;
}

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

void SdrGrafObj::ForceSwapIn() const
{
    pGraphic->FireSwapInRequest();

    if( pGraphic->IsSwappedOut() ||
        ( pGraphic->GetType() == GRAPHIC_NONE ) ||
        ( pGraphic->GetType() == GRAPHIC_DEFAULT ) )
    {
        Graphic aDefaultGraphic;
        aDefaultGraphic.SetDefaultType();
        pGraphic->SetGraphic( aDefaultGraphic );
    }
}

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

void SdrGrafObj::ForceSwapOut() const
{
    pGraphic->FireSwapOutRequest();
}

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

void SdrGrafObj::ImpLinkAnmeldung()
{
#ifndef SVX_LIGHT

    SvxLinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;

    if( pLinkManager != NULL && pGraphicLink == NULL )
    {
        if( aFileName.Len() )
        {
            pGraphicLink = new SdrGraphicLink( this );
            pLinkManager->InsertFileLink( *pGraphicLink, OBJECT_CLIENT_GRF, aFileName, ( aFilterName.Len() ? &aFilterName : NULL ), NULL );
            pGraphicLink->Connect();
        }
    }

#endif // SVX_LIGHT
}

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

void SdrGrafObj::ImpLinkAbmeldung()
{
#ifndef SVX_LIGHT

    SvxLinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;

    if( pLinkManager != NULL && pGraphicLink!=NULL)
    {
        // Bei Remove wird *pGraphicLink implizit deleted
        pLinkManager->Remove( pGraphicLink );
        pGraphicLink=NULL;
    }

#endif // SVX_LIGHT
}

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

void SdrGrafObj::SetGraphicLink( const String& rFileName, const String& rFilterName )
{
    ImpLinkAbmeldung();
    aFileName = rFileName;
    aFilterName = rFilterName;
    ImpLinkAnmeldung();
    pGraphic->SetUserData();

    // #92205# A linked graphic is per definition swapped out (has to be loaded)
    pGraphic->SetSwapState();
}

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

void SdrGrafObj::ReleaseGraphicLink()
{
    ImpLinkAbmeldung();
    aFileName = String();
    aFilterName = String();
}

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

void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
{
    FASTBOOL bTrans = pGraphic->IsTransparent();
    FASTBOOL bAnim = pGraphic->IsAnimated();
    FASTBOOL bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj;

    rInfo.bResizeFreeAllowed = aGeo.nDrehWink % 9000 == 0 ||
                               aGeo.nDrehWink % 18000 == 0 ||
                               aGeo.nDrehWink % 27000 == 0;

    rInfo.bResizePropAllowed = TRUE;
    rInfo.bRotateFreeAllowed = bNoPresGrf && !bAnim;
    rInfo.bRotate90Allowed = bNoPresGrf && !bAnim;
    rInfo.bMirrorFreeAllowed = bNoPresGrf && !bAnim;
    rInfo.bMirror45Allowed = bNoPresGrf && !bAnim;
    rInfo.bMirror90Allowed = !bEmptyPresObj;
    rInfo.bTransparenceAllowed = FALSE;
    rInfo.bGradientAllowed = FALSE;
    rInfo.bShearAllowed = FALSE;
    rInfo.bEdgeRadiusAllowed=FALSE;
    rInfo.bCanConvToPath = FALSE;
    rInfo.bCanConvToPathLineToArea = FALSE;
    rInfo.bCanConvToPolyLineToArea = FALSE;
    rInfo.bCanConvToPoly = !IsEPS();
    rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
}

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

UINT16 SdrGrafObj::GetObjIdentifier() const
{
    return UINT16( OBJ_GRAF );
}

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

sal_Bool SdrGrafObj::ImpUpdateGraphicLink() const
{
    sal_Bool    bRet = sal_False;

#ifndef SVX_LIGHT
    if( pGraphicLink )
    {
        BOOL bIsChanged = pModel->IsChanged();
        pGraphicLink->UpdateSynchron();
        pModel->SetChanged( bIsChanged );

        bRet = sal_True;
    }
#else
    if( aFileName.Len() )
    {
        // #92205# Load linked graphics for player
        SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aFileName, STREAM_READ | STREAM_SHARE_DENYNONE );

        if( pIStm )
        {
            Graphic         aGraphic;
            GraphicFilter*  pFilter = GetGrfFilter();
            USHORT          nError = pFilter->ImportGraphic( aGraphic, aFileName, *pIStm );

            pGraphic->SetGraphic( aGraphic );

            delete pIStm;
        }

        bRet = sal_True;
    }
#endif

    return bRet;
}

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

// Liefert FALSE, wenn die Pres-Bitmap zu gross ist
FASTBOOL SdrGrafObj::ImpPaintEmptyPres( OutputDevice* pOutDev ) const
{
    const MapMode   aDstMapMode( pOutDev->GetMapMode().GetMapUnit() );
    Point           aPos( aRect.Center() );
    Size            aSize;
    FASTBOOL        bRet;

    if( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
        aSize = pOutDev->PixelToLogic( pGraphic->GetPrefSize(), aDstMapMode );
    else
        aSize = pOutDev->LogicToLogic( pGraphic->GetPrefSize(), pGraphic->GetPrefMapMode(), aDstMapMode );

    aPos.X() -= ( aSize.Width() >> 1 );
    aPos.Y() -= ( aSize.Height() >> 1 );

    if( aPos.X() >= aRect.Left() && aPos.Y() >= aRect.Top() )
    {
        const Graphic& rGraphic = pGraphic->GetGraphic();

        if( pGraphic->GetType() == GRAPHIC_BITMAP )
            pGraphic->Draw( pOutDev, aPos, aSize, NULL );
        else
        {
            const ULONG nOldDrawMode = pOutDev->GetDrawMode();

            if( ( nOldDrawMode & DRAWMODE_GRAYBITMAP ) != 0 )
            {
                // Falls Modus GRAYBITMAP, wollen wir auch Mtf's als Graustufen darstellen
                ULONG nNewDrawMode = nOldDrawMode;
                nNewDrawMode &= ~( DRAWMODE_BLACKLINE | DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL | DRAWMODE_NOFILL );
                pOutDev->SetDrawMode( nNewDrawMode |= DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL  );
            }

            rGraphic.Draw( pOutDev, aPos, aSize );
            pOutDev->SetDrawMode( nOldDrawMode );
        }

        bRet = TRUE;
    }
    else
        bRet = FALSE;

    return bRet;
}

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

void SdrGrafObj::ImpPaintReplacement(OutputDevice* pOutDev, const XubString& rText, const Bitmap* pBmp, FASTBOOL bFill) const
{
    if( bFill )
    {
        pOutDev->SetLineColor();
        pOutDev->SetFillColor( COL_LIGHTGRAY );
    }

    Rectangle aRect1(pOutDev->LogicToPixel(aRect));
    Rectangle aTextRect(aRect1);
    Rectangle aRect2(aRect1);
    aRect2.Left()++; aRect2.Top()++; aRect2.Right()--; aRect2.Bottom()--;
    Point aTopLeft(aRect1.TopLeft());
    Point aBmpPos(aTopLeft);

    if( pBmp != NULL )
    {
        Size        aBmpSize(pBmp->GetSizePixel());
        long        nRectWdt=aTextRect.Right()-aTextRect.Left();
        long        nRectHgt=aTextRect.Bottom()-aTextRect.Top();
        long        nBmpWdt=aBmpSize.Width();
        long        nBmpHgt=aBmpSize.Height();
        BOOL        bText = rText.Len() > 0;

        long nMinWdt = nBmpWdt;
        long nMinHgt = nBmpHgt;

        if( bText )
        {
            nMinWdt=2 + nBmpWdt * 2 + 3;
            nMinHgt=2 + nBmpHgt * 2 + 3;
        }

        if( nRectWdt < nMinWdt || nRectHgt < nMinHgt )
            pBmp=NULL;
        else
        {
            aTextRect.Left() += nBmpWdt;

            if( bText )
                aTextRect.Left()+=2+3;
        }

        aBmpPos.X() += 2;
        aBmpPos.Y() += 2;

        if( aGeo.nDrehWink!=0 )
        {
            Point aRef(aBmpPos);
            aRef.X()-=aBmpSize.Width()/2+2;
            aRef.Y()-=aBmpSize.Height()/2+2;
            double nSin=sin(aGeo.nDrehWink*nPi180);
            double nCos=cos(aGeo.nDrehWink*nPi180);
            RotatePoint(aBmpPos,aRef,nSin,nCos);
        }
    }

    const BOOL bOldMap = pOutDev->IsMapModeEnabled();
    pOutDev->EnableMapMode( FALSE );

    if( aGeo.nDrehWink == 0 && aGeo.nShearWink == 0 )
    {
        if (bFill)
            pOutDev->DrawRect(aRect);

        if (pBmp!=NULL)
            pOutDev->DrawBitmap(aBmpPos,*pBmp);

        const StyleSettings& rStyleSettings = pOutDev->GetSettings().GetStyleSettings();

        pOutDev->SetFillColor();
        pOutDev->SetLineColor( rStyleSettings.GetShadowColor() );
        pOutDev->DrawLine(aRect1.TopLeft(),aRect1.TopRight()); pOutDev->DrawLine(aRect1.TopLeft(),aRect1.BottomLeft());


        pOutDev->SetLineColor( rStyleSettings.GetLightColor() );
        pOutDev->DrawLine(aRect1.TopRight(),aRect1.BottomRight()); pOutDev->DrawLine(aRect1.BottomLeft(),aRect1.BottomRight());

        pOutDev->SetLineColor( rStyleSettings.GetLightColor() );
        pOutDev->DrawLine(aRect2.TopLeft(),aRect2.TopRight()); pOutDev->DrawLine(aRect2.TopLeft(),aRect2.BottomLeft());

        pOutDev->SetLineColor( rStyleSettings.GetShadowColor() );
        pOutDev->DrawLine(aRect2.TopRight(),aRect2.BottomRight()); pOutDev->DrawLine(aRect2.BottomLeft(),aRect2.BottomRight());
    }
    else
    {
        Polygon aPoly1(Rect2Poly(aRect1,aGeo));
        Polygon aPoly2(5);
        aPoly2[0]=aRect2.TopLeft();
        aPoly2[1]=aRect2.TopRight();
        aPoly2[2]=aRect2.BottomRight();
        aPoly2[3]=aRect2.BottomLeft();
        aPoly2[4]=aRect2.TopLeft();

        if (aGeo.nShearWink != 0)
            ShearPoly(aPoly2,aTopLeft,aGeo.nTan);

        if( aGeo.nDrehWink != 0 )
            RotatePoly(aPoly2,aTopLeft,aGeo.nSin,aGeo.nCos);

        if( bFill )
            pOutDev->DrawPolygon(aPoly1);

        if( pBmp != NULL )
            pOutDev->DrawBitmap( aBmpPos, *pBmp );

        pOutDev->SetFillColor();

        long        nHWink=NormAngle360(aGeo.nDrehWink);
        long        nVWink=NormAngle360(aGeo.nDrehWink-aGeo.nShearWink);
        FASTBOOL    bHorzChg=nHWink>13500 && nHWink<=31500;
        FASTBOOL    bVertChg=nVWink>4500 && nVWink<=22500;

        const StyleSettings& rStyleSettings = pOutDev->GetSettings().GetStyleSettings();
        Color a3DLightColor( rStyleSettings.GetLightColor() );
        Color a3DShadowColor( rStyleSettings.GetShadowColor() );

        pOutDev->SetLineColor( bHorzChg ? a3DShadowColor : a3DLightColor);
        pOutDev->DrawLine(aPoly2[0],aPoly2[1]);

        pOutDev->SetLineColor( bHorzChg ? a3DLightColor  : a3DShadowColor);
        pOutDev->DrawLine(aPoly2[2],aPoly2[3]);

        pOutDev->SetLineColor( bVertChg ? a3DLightColor  : a3DShadowColor);
        pOutDev->DrawLine(aPoly2[1],aPoly2[2]);

        pOutDev->SetLineColor( bVertChg ? a3DShadowColor : a3DLightColor);
        pOutDev->DrawLine(aPoly2[3],aPoly2[4]);

        pOutDev->SetLineColor( bHorzChg ? a3DLightColor  : a3DShadowColor);
        pOutDev->DrawLine(aPoly1[0],aPoly1[1]);

        pOutDev->SetLineColor( bHorzChg ? a3DShadowColor : a3DLightColor);
        pOutDev->DrawLine(aPoly1[2],aPoly1[3]);

        pOutDev->SetLineColor( bVertChg ? a3DShadowColor : a3DLightColor);
        pOutDev->DrawLine(aPoly1[1],aPoly1[2]);

        pOutDev->SetLineColor( bVertChg ? a3DLightColor  : a3DShadowColor);
        pOutDev->DrawLine(aPoly1[3],aPoly1[4]);
    }
    XubString aNam(rText);

    if(aNam.Len())
    {
        Size aOutSize(aTextRect.GetSize()); aOutSize.Width()-=6; aOutSize.Height()-=6;

        if (aOutSize.Width()>=4 || aOutSize.Height()>=4)
        {
            Point aOutPos(aTextRect.TopLeft()); aOutPos.X()+=3; aOutPos.Y()+=3;
            long nMaxOutY=aOutPos.Y()+aOutSize.Height();
            Font aFontMerk(pOutDev->GetFont());
            Font aFont( OutputDevice::GetDefaultFont( DEFAULTFONT_SANS_UNICODE, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ) );
            aFont.SetColor(COL_LIGHTRED);
            aFont.SetTransparent(TRUE);
            aFont.SetLineOrientation(USHORT(NormAngle360(aGeo.nDrehWink)/10));

            if (IsLinkedGraphic())
                aFont.SetUnderline(UNDERLINE_SINGLE);
            Size aFontSize(Size(0,aGeo.nDrehWink % 9000==0 ? 12 : 14));

            if (aFontSize.Height()>aOutSize.Height())
                aFontSize.Height()=aOutSize.Height();
            aFont.SetSize(aFontSize);
            pOutDev->SetFont(aFont);
            String aOutStr(aNam);

            while(aOutStr.Len() && aOutPos.Y() <= nMaxOutY)
            {
                String aStr1(aOutStr);
                INT32 nTextWidth = pOutDev->GetTextWidth(aStr1);
                INT32 nTextHeight = pOutDev->GetTextHeight();

                while(aStr1.Len() && nTextWidth > aOutSize.Width())
                {
                    aStr1.Erase(aStr1.Len() - 1);
                    nTextWidth = pOutDev->GetTextWidth(aStr1);
                    nTextHeight = pOutDev->GetTextHeight();
                }
                Point aPos(aOutPos);
                aOutPos.Y() += nTextHeight;

                if (aOutPos.Y()<=nMaxOutY)
                {
                    if (aGeo.nShearWink!=0) ShearPoint(aPos,aTopLeft,aGeo.nTan);
                    if (aGeo.nDrehWink!=0) RotatePoint(aPos,aTopLeft,aGeo.nSin,aGeo.nCos);
                    pOutDev->DrawText(aPos,aStr1);
                    aOutStr.Erase(0, aStr1.Len());
                }
            }
            pOutDev->SetFont(aFontMerk);
        }
    }
    pOutDev->EnableMapMode( bOldMap );
}

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

FASTBOOL SdrGrafObj::Paint( ExtOutputDevice& rOut, const SdrPaintInfoRec& rInfoRec ) const
{
    // Hidden objects on masterpages, draw nothing
    if( ( ( rInfoRec.nPaintMode & SDRPAINTMODE_MASTERPAGE ) && bNotVisibleAsMaster ) ||
        ( ( OUTDEV_PRINTER == rOut.GetOutDev()->GetOutDevType() ) && bEmptyPresObj ) )
    {
        return TRUE;
    }

    FASTBOOL        bDraft = ( 0 != ( rInfoRec.nPaintMode & SDRPAINTMODE_DRAFTGRAF ) );
    FASTBOOL        bSwappedOut = pGraphic->IsSwappedOut() || ( pGraphic->GetType() == GRAPHIC_NONE );
    FASTBOOL        bLoading = FALSE;
    OutputDevice*   pOutDev = rOut.GetOutDev();
    GDIMetaFile*    pRecMetaFile = pOutDev->GetConnectMetaFile();
    FASTBOOL        bMtfRecording = ( pRecMetaFile && pRecMetaFile->IsRecord() && !pRecMetaFile->IsPause() );
    const SdrView*  pView = ( rInfoRec.pPV ? &rInfoRec.pPV->GetView() : NULL );

    if( bSwappedOut && !bDraft )
    {
        if( !ImpUpdateGraphicLink() )
        {
            if( ( OUTDEV_WINDOW == pOutDev->GetOutDevType() ) && !bMtfRecording && pView && pView->IsSwapAsynchron() )
            {
                ( (SdrView*) pView )->ImpAddAsyncObj( this, pOutDev );
                bLoading = TRUE;
            }
            else
                ForceSwapIn();
        }
    }

    if( pGraphic->IsSwappedOut() || ( pGraphic->GetType() == GRAPHIC_NONE ) || ( pGraphic->GetType() == GRAPHIC_DEFAULT ) )
        bDraft=TRUE;

    long          nDrehWink = aGeo.nDrehWink, nShearWink = aGeo.nShearWink;
    FASTBOOL      bRotate = ( nDrehWink != 0 && nDrehWink != 18000 );
    FASTBOOL      bShear = ( nShearWink != 0 );
    FASTBOOL      bRota180 = nDrehWink == 18000;
    USHORT        nMirrorCase = ( bRota180 ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 ) );   //  4 | 3   H&V gespiegelt | nur Vertikal
    FASTBOOL      bHMirr = ( ( 2 == nMirrorCase ) || ( 4 == nMirrorCase ) );                    // ---+---  ---------------+-----------------
    FASTBOOL      bVMirr = ( ( 3 == nMirrorCase ) || ( 4 == nMirrorCase ) );                    //  2 | 1   nur Horizontal | nicht gespiegelt

    if( !bEmptyPresObj && !bDraft )
    {
        Point       aLogPos( aRect.TopLeft() );
        Size        aLogSize( aRect.GetSize() );
        GraphicAttr aAttr( aGrafInfo );

        aAttr.SetMirrorFlags( ( bHMirr ? BMP_MIRROR_HORZ : 0 ) | ( bVMirr ? BMP_MIRROR_VERT : 0 ) );

        if( bRota180 )
        {
            aLogPos.X() -= ( aLogSize.Width() - 1L );
            aLogPos.Y() -= ( aLogSize.Height() - 1L );
        }

        if( pGraphic->GetType() == GRAPHIC_BITMAP )
        {
            if( pGraphic->IsAnimated() )
            {
                SdrAnimationMode    eAnimMode = SDR_ANIMATION_ANIMATE;
                FASTBOOL            bEnable = TRUE;

                if( rInfoRec.pPV != NULL )
                {
                    eAnimMode= ((SdrPaintView&) rInfoRec.pPV->GetView()).GetAnimationMode();
                    bEnable = eAnimMode != SDR_ANIMATION_DISABLE;
                }

                if( bEnable )
                {
                    if( eAnimMode == SDR_ANIMATION_ANIMATE )
                    {
                        pGraphic->SetAnimationNotifyHdl( LINK( this, SdrGrafObj, ImpAnimationHdl ) );
                        pGraphic->StartAnimation( pOutDev, aLogPos, aLogSize, 0, &aAttr );
                    }<commit_msg>#98825# Look if graphics animation is disabled by accessibility options<commit_after>/*************************************************************************
 *
 *  $RCSfile: svdograf.cxx,v $
 *
 *  $Revision: 1.46 $
 *
 *  last change: $Author: aw $ $Date: 2002-05-15 13:25:16 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#define _ANIMATION
#define ITEMID_GRF_CROP 0

#ifndef SVX_LIGHT
#include <so3/lnkbase.hxx>
#else
#include <svtools/pathoptions.hxx>
#endif

#include <math.h>
#include <vcl/salbtype.hxx>
#include <sot/formats.hxx>
#include <so3/svstor.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <unotools/localfilehelper.hxx>
#include <svtools/style.hxx>
#include <svtools/filter.hxx>
#include <svtools/urihelper.hxx>
#include <goodies/grfmgr.hxx>
#include "linkmgr.hxx"
#include "svdxout.hxx"
#include "svdio.hxx"
#include "svdetc.hxx"
#include "svdglob.hxx"
#include "svdstr.hrc"
#include "svdpool.hxx"
#include "svdmodel.hxx"
#include "svdpage.hxx"
#include "svdmrkv.hxx"
#include "svdpagv.hxx"
#include "svdviter.hxx"
#include "svdview.hxx"
#include "impgrf.hxx"
#include "svdograf.hxx"
#include "svdogrp.hxx"
#include "xbitmap.hxx"
#include "xbtmpit.hxx"
#include "xflbmtit.hxx"
#include "svdundo.hxx"
#include "svdfmtf.hxx"
#include "sdgcpitm.hxx"

#ifndef _EEITEM_HXX
#include "eeitem.hxx"
#endif

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

#define GRAFSTREAMPOS_INVALID 0xffffffff

#ifndef SVX_LIGHT

// ------------------
// - SdrGraphicLink -
// ------------------

class SdrGraphicLink : public so3::SvBaseLink
{
    SdrGrafObj*         pGrafObj;

public:
                        SdrGraphicLink(SdrGrafObj* pObj);
    virtual             ~SdrGraphicLink();

    virtual void        Closed();
    virtual void        DataChanged( const String& rMimeType,
                                const ::com::sun::star::uno::Any & rValue );

    BOOL                Connect() { return 0 != GetRealObject(); }
    void                UpdateSynchron();
};

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

SdrGraphicLink::SdrGraphicLink(SdrGrafObj* pObj):
    ::so3::SvBaseLink( ::so3::LINKUPDATE_ONCALL, SOT_FORMATSTR_ID_SVXB ),
    pGrafObj(pObj)
{
    SetSynchron( FALSE );
}

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

SdrGraphicLink::~SdrGraphicLink()
{
}

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

void SdrGraphicLink::DataChanged( const String& rMimeType,
                                const ::com::sun::star::uno::Any & rValue )
{
    SdrModel*       pModel      = pGrafObj ? pGrafObj->GetModel() : 0;
    SvxLinkManager* pLinkManager= pModel  ? pModel->GetLinkManager() : 0;

    if( pLinkManager && rValue.hasValue() )
    {
        pLinkManager->GetDisplayNames( this, 0, &pGrafObj->aFileName, 0, &pGrafObj->aFilterName );

        Graphic aGraphic;
        if( SvxLinkManager::GetGraphicFromAny( rMimeType, rValue, aGraphic ))
        {
            GraphicType eOldGraphicType = pGrafObj->GetGraphicType();  // kein Hereinswappen
            BOOL bIsChanged = pModel->IsChanged();

            pGrafObj->SetGraphic( aGraphic );
            if( GRAPHIC_NONE != eOldGraphicType )
                pGrafObj->SetChanged();
            else
                pModel->SetChanged( bIsChanged );
        }
        else if( SotExchange::GetFormatIdFromMimeType( rMimeType ) !=
                    SvxLinkManager::RegisterStatusInfoId() )
            pGrafObj->SendRepaintBroadcast();
    }
}

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

void SdrGraphicLink::Closed()
{
    // Die Verbindung wird aufgehoben; pLink des Objekts auf NULL setzen, da die Link-Instanz ja gerade destruiert wird.
    pGrafObj->ForceSwapIn();
    pGrafObj->pGraphicLink=NULL;
    pGrafObj->ReleaseGraphicLink();
    SvBaseLink::Closed();
}

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

void SdrGraphicLink::UpdateSynchron()
{
    if( GetObj() )
    {
        String aMimeType( SotExchange::GetFormatMimeType( GetContentType() ));
        ::com::sun::star::uno::Any aValue;
        GetObj()->GetData( aValue, aMimeType, TRUE );
        DataChanged( aMimeType, aValue );
    }
}

#else

GraphicFilter* SVX_LIGHT_pGrapicFilter = NULL;

GraphicFilter* GetGrfFilter()
{
    if( !SVX_LIGHT_pGrapicFilter )
    {
        const SvtPathOptions aPathOptions;

        SVX_LIGHT_pGrapicFilter = new GraphicFilter( FALSE );
        SVX_LIGHT_pGrapicFilter->SetFilterPath( aPathOptions.GetFilterPath() );
    }

    return SVX_LIGHT_pGrapicFilter;
}


#endif // SVX_LIGHT

// --------------
// - SdrGrafObj -
// --------------

TYPEINIT1(SdrGrafObj,SdrRectObj);

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

SdrGrafObj::SdrGrafObj():
    bMirrored       ( FALSE ),
    pGraphicLink    ( NULL )
{
    pGraphic = new GraphicObject;
    pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), Application::IsRemoteServer() ? 60000 : 20000 );
    nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    bNoShear = TRUE;
    bCopyToPoolOnAfterRead = FALSE;
}

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

SdrGrafObj::SdrGrafObj(const Graphic& rGrf, const Rectangle& rRect):
    SdrRectObj      ( rRect ),
    bMirrored       ( FALSE ),
    pGraphicLink    ( NULL )
{
    pGraphic = new GraphicObject( rGrf );
    pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), Application::IsRemoteServer() ? 60000 : 20000 );
    nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    bNoShear = TRUE;
    bCopyToPoolOnAfterRead = FALSE;
}

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

SdrGrafObj::SdrGrafObj( const Graphic& rGrf ):
    bMirrored       ( FALSE ),
    pGraphicLink    ( NULL )
{
    pGraphic = new GraphicObject( rGrf );
    pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), Application::IsRemoteServer() ? 60000 : 20000 );
    nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    bNoShear = TRUE;
    bCopyToPoolOnAfterRead = FALSE;
}

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

SdrGrafObj::~SdrGrafObj()
{
    delete pGraphic;
    ImpLinkAbmeldung();
}

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

void SdrGrafObj::SetGraphicObject( const GraphicObject& rGrfObj )
{
    *pGraphic = rGrfObj;
    pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), Application::IsRemoteServer() ? 60000 : 20000 );
    pGraphic->SetUserData();
    nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    SetChanged();
    SendRepaintBroadcast();
}

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

const GraphicObject& SdrGrafObj::GetGraphicObject() const
{
    ForceSwapIn();
    return *pGraphic;
}

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

void SdrGrafObj::SetGraphic( const Graphic& rGrf )
{
    pGraphic->SetGraphic( rGrf );
    pGraphic->SetUserData();
    nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    SetChanged();
    SendRepaintBroadcast();
}

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

const Graphic& SdrGrafObj::GetGraphic() const
{
    ForceSwapIn();
    return pGraphic->GetGraphic();
}

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

Graphic SdrGrafObj::GetTransformedGraphic( ULONG nTransformFlags ) const
{
    Graphic     aTransGraphic;
    GraphicType eType = GetGraphicType();

    if( SDRGRAFOBJ_TRANSFORMATTR_NONE == nTransformFlags )
        aTransGraphic = GetGraphic();
    else if( eType != GRAPHIC_NONE )
    {
        ( (SdrGrafObj*) this )->ImpSetAttrToGrafInfo();

        GraphicAttr aActAttr( aGrafInfo );

        if( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_MIRROR )
        {
            USHORT      nMirrorCase = ( aGeo.nDrehWink == 18000 ) ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 );
            FASTBOOL    bHMirr = nMirrorCase == 2 || nMirrorCase == 4;
            FASTBOOL    bVMirr = nMirrorCase == 3 || nMirrorCase == 4;

            aActAttr.SetMirrorFlags( ( bHMirr ? BMP_MIRROR_HORZ : 0 ) | ( bVMirr ? BMP_MIRROR_VERT : 0 ) );
        }

        if( ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_ROTATE ) &&
            ( aGeo.nDrehWink && aGeo.nDrehWink != 18000 ) && ( GRAPHIC_NONE != eType ) && !IsAnimated() )
        {
            aActAttr.SetRotation( aGeo.nDrehWink / 10 );
        }

        aTransGraphic = pGraphic->GetTransformedGraphic( &aActAttr );
    }

    return aTransGraphic;
}

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

GraphicType SdrGrafObj::GetGraphicType() const
{
    return pGraphic->GetType();
}

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

FASTBOOL SdrGrafObj::IsAnimated() const
{
    return pGraphic->IsAnimated();
}

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

FASTBOOL SdrGrafObj::IsTransparent() const
{
    return pGraphic->IsTransparent();
}

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

FASTBOOL SdrGrafObj::IsEPS() const
{
    return pGraphic->IsEPS();
}

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

const MapMode& SdrGrafObj::GetGrafPrefMapMode() const
{
    return pGraphic->GetPrefMapMode();
}

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

const Size& SdrGrafObj::GetGrafPrefSize() const
{
    return pGraphic->GetPrefSize();
}

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

void SdrGrafObj::SetGrafStreamURL( const String& rGraphicStreamURL )
{
    if( !rGraphicStreamURL.Len() )
    {
        pGraphic->SetUserData();
        nGrafStreamPos = GRAFSTREAMPOS_INVALID;
    }
    else if( pModel->IsSwapGraphics() && ( pModel->GetSwapGraphicsMode() & SDR_SWAPGRAPHICSMODE_DOC ) )
    {
        pGraphic->SetUserData( rGraphicStreamURL );
        nGrafStreamPos = GRAFSTREAMPOS_INVALID;

        // set state of graphic object to 'swapped out'
        if( pGraphic->GetType() == GRAPHIC_NONE )
            pGraphic->SetSwapState();
    }
}

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

String SdrGrafObj::GetGrafStreamURL() const
{
    return pGraphic->GetUserData();
}

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

void SdrGrafObj::SetFileName(const String& rFileName)
{
    aFileName = rFileName;
    SetChanged();
}

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

void SdrGrafObj::SetFilterName(const String& rFilterName)
{
    aFilterName = rFilterName;
    SetChanged();
}

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

FASTBOOL SdrGrafObj::HasSetName() const
{
    return TRUE;
}

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

void SdrGrafObj::SetName(const XubString& rStr)
{
    aName = rStr;
    SetChanged();
}

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

XubString SdrGrafObj::GetName() const
{
    return aName;
}

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

void SdrGrafObj::ForceSwapIn() const
{
    pGraphic->FireSwapInRequest();

    if( pGraphic->IsSwappedOut() ||
        ( pGraphic->GetType() == GRAPHIC_NONE ) ||
        ( pGraphic->GetType() == GRAPHIC_DEFAULT ) )
    {
        Graphic aDefaultGraphic;
        aDefaultGraphic.SetDefaultType();
        pGraphic->SetGraphic( aDefaultGraphic );
    }
}

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

void SdrGrafObj::ForceSwapOut() const
{
    pGraphic->FireSwapOutRequest();
}

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

void SdrGrafObj::ImpLinkAnmeldung()
{
#ifndef SVX_LIGHT

    SvxLinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;

    if( pLinkManager != NULL && pGraphicLink == NULL )
    {
        if( aFileName.Len() )
        {
            pGraphicLink = new SdrGraphicLink( this );
            pLinkManager->InsertFileLink( *pGraphicLink, OBJECT_CLIENT_GRF, aFileName, ( aFilterName.Len() ? &aFilterName : NULL ), NULL );
            pGraphicLink->Connect();
        }
    }

#endif // SVX_LIGHT
}

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

void SdrGrafObj::ImpLinkAbmeldung()
{
#ifndef SVX_LIGHT

    SvxLinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;

    if( pLinkManager != NULL && pGraphicLink!=NULL)
    {
        // Bei Remove wird *pGraphicLink implizit deleted
        pLinkManager->Remove( pGraphicLink );
        pGraphicLink=NULL;
    }

#endif // SVX_LIGHT
}

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

void SdrGrafObj::SetGraphicLink( const String& rFileName, const String& rFilterName )
{
    ImpLinkAbmeldung();
    aFileName = rFileName;
    aFilterName = rFilterName;
    ImpLinkAnmeldung();
    pGraphic->SetUserData();

    // #92205# A linked graphic is per definition swapped out (has to be loaded)
    pGraphic->SetSwapState();
}

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

void SdrGrafObj::ReleaseGraphicLink()
{
    ImpLinkAbmeldung();
    aFileName = String();
    aFilterName = String();
}

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

void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
{
    FASTBOOL bTrans = pGraphic->IsTransparent();
    FASTBOOL bAnim = pGraphic->IsAnimated();
    FASTBOOL bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj;

    rInfo.bResizeFreeAllowed = aGeo.nDrehWink % 9000 == 0 ||
                               aGeo.nDrehWink % 18000 == 0 ||
                               aGeo.nDrehWink % 27000 == 0;

    rInfo.bResizePropAllowed = TRUE;
    rInfo.bRotateFreeAllowed = bNoPresGrf && !bAnim;
    rInfo.bRotate90Allowed = bNoPresGrf && !bAnim;
    rInfo.bMirrorFreeAllowed = bNoPresGrf && !bAnim;
    rInfo.bMirror45Allowed = bNoPresGrf && !bAnim;
    rInfo.bMirror90Allowed = !bEmptyPresObj;
    rInfo.bTransparenceAllowed = FALSE;
    rInfo.bGradientAllowed = FALSE;
    rInfo.bShearAllowed = FALSE;
    rInfo.bEdgeRadiusAllowed=FALSE;
    rInfo.bCanConvToPath = FALSE;
    rInfo.bCanConvToPathLineToArea = FALSE;
    rInfo.bCanConvToPolyLineToArea = FALSE;
    rInfo.bCanConvToPoly = !IsEPS();
    rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
}

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

UINT16 SdrGrafObj::GetObjIdentifier() const
{
    return UINT16( OBJ_GRAF );
}

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

sal_Bool SdrGrafObj::ImpUpdateGraphicLink() const
{
    sal_Bool    bRet = sal_False;

#ifndef SVX_LIGHT
    if( pGraphicLink )
    {
        BOOL bIsChanged = pModel->IsChanged();
        pGraphicLink->UpdateSynchron();
        pModel->SetChanged( bIsChanged );

        bRet = sal_True;
    }
#else
    if( aFileName.Len() )
    {
        // #92205# Load linked graphics for player
        SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aFileName, STREAM_READ | STREAM_SHARE_DENYNONE );

        if( pIStm )
        {
            Graphic         aGraphic;
            GraphicFilter*  pFilter = GetGrfFilter();
            USHORT          nError = pFilter->ImportGraphic( aGraphic, aFileName, *pIStm );

            pGraphic->SetGraphic( aGraphic );

            delete pIStm;
        }

        bRet = sal_True;
    }
#endif

    return bRet;
}

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

// Liefert FALSE, wenn die Pres-Bitmap zu gross ist
FASTBOOL SdrGrafObj::ImpPaintEmptyPres( OutputDevice* pOutDev ) const
{
    const MapMode   aDstMapMode( pOutDev->GetMapMode().GetMapUnit() );
    Point           aPos( aRect.Center() );
    Size            aSize;
    FASTBOOL        bRet;

    if( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
        aSize = pOutDev->PixelToLogic( pGraphic->GetPrefSize(), aDstMapMode );
    else
        aSize = pOutDev->LogicToLogic( pGraphic->GetPrefSize(), pGraphic->GetPrefMapMode(), aDstMapMode );

    aPos.X() -= ( aSize.Width() >> 1 );
    aPos.Y() -= ( aSize.Height() >> 1 );

    if( aPos.X() >= aRect.Left() && aPos.Y() >= aRect.Top() )
    {
        const Graphic& rGraphic = pGraphic->GetGraphic();

        if( pGraphic->GetType() == GRAPHIC_BITMAP )
            pGraphic->Draw( pOutDev, aPos, aSize, NULL );
        else
        {
            const ULONG nOldDrawMode = pOutDev->GetDrawMode();

            if( ( nOldDrawMode & DRAWMODE_GRAYBITMAP ) != 0 )
            {
                // Falls Modus GRAYBITMAP, wollen wir auch Mtf's als Graustufen darstellen
                ULONG nNewDrawMode = nOldDrawMode;
                nNewDrawMode &= ~( DRAWMODE_BLACKLINE | DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL | DRAWMODE_NOFILL );
                pOutDev->SetDrawMode( nNewDrawMode |= DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL  );
            }

            rGraphic.Draw( pOutDev, aPos, aSize );
            pOutDev->SetDrawMode( nOldDrawMode );
        }

        bRet = TRUE;
    }
    else
        bRet = FALSE;

    return bRet;
}

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

void SdrGrafObj::ImpPaintReplacement(OutputDevice* pOutDev, const XubString& rText, const Bitmap* pBmp, FASTBOOL bFill) const
{
    if( bFill )
    {
        pOutDev->SetLineColor();
        pOutDev->SetFillColor( COL_LIGHTGRAY );
    }

    Rectangle aRect1(pOutDev->LogicToPixel(aRect));
    Rectangle aTextRect(aRect1);
    Rectangle aRect2(aRect1);
    aRect2.Left()++; aRect2.Top()++; aRect2.Right()--; aRect2.Bottom()--;
    Point aTopLeft(aRect1.TopLeft());
    Point aBmpPos(aTopLeft);

    if( pBmp != NULL )
    {
        Size        aBmpSize(pBmp->GetSizePixel());
        long        nRectWdt=aTextRect.Right()-aTextRect.Left();
        long        nRectHgt=aTextRect.Bottom()-aTextRect.Top();
        long        nBmpWdt=aBmpSize.Width();
        long        nBmpHgt=aBmpSize.Height();
        BOOL        bText = rText.Len() > 0;

        long nMinWdt = nBmpWdt;
        long nMinHgt = nBmpHgt;

        if( bText )
        {
            nMinWdt=2 + nBmpWdt * 2 + 3;
            nMinHgt=2 + nBmpHgt * 2 + 3;
        }

        if( nRectWdt < nMinWdt || nRectHgt < nMinHgt )
            pBmp=NULL;
        else
        {
            aTextRect.Left() += nBmpWdt;

            if( bText )
                aTextRect.Left()+=2+3;
        }

        aBmpPos.X() += 2;
        aBmpPos.Y() += 2;

        if( aGeo.nDrehWink!=0 )
        {
            Point aRef(aBmpPos);
            aRef.X()-=aBmpSize.Width()/2+2;
            aRef.Y()-=aBmpSize.Height()/2+2;
            double nSin=sin(aGeo.nDrehWink*nPi180);
            double nCos=cos(aGeo.nDrehWink*nPi180);
            RotatePoint(aBmpPos,aRef,nSin,nCos);
        }
    }

    const BOOL bOldMap = pOutDev->IsMapModeEnabled();
    pOutDev->EnableMapMode( FALSE );

    if( aGeo.nDrehWink == 0 && aGeo.nShearWink == 0 )
    {
        if (bFill)
            pOutDev->DrawRect(aRect);

        if (pBmp!=NULL)
            pOutDev->DrawBitmap(aBmpPos,*pBmp);

        const StyleSettings& rStyleSettings = pOutDev->GetSettings().GetStyleSettings();

        pOutDev->SetFillColor();
        pOutDev->SetLineColor( rStyleSettings.GetShadowColor() );
        pOutDev->DrawLine(aRect1.TopLeft(),aRect1.TopRight()); pOutDev->DrawLine(aRect1.TopLeft(),aRect1.BottomLeft());


        pOutDev->SetLineColor( rStyleSettings.GetLightColor() );
        pOutDev->DrawLine(aRect1.TopRight(),aRect1.BottomRight()); pOutDev->DrawLine(aRect1.BottomLeft(),aRect1.BottomRight());

        pOutDev->SetLineColor( rStyleSettings.GetLightColor() );
        pOutDev->DrawLine(aRect2.TopLeft(),aRect2.TopRight()); pOutDev->DrawLine(aRect2.TopLeft(),aRect2.BottomLeft());

        pOutDev->SetLineColor( rStyleSettings.GetShadowColor() );
        pOutDev->DrawLine(aRect2.TopRight(),aRect2.BottomRight()); pOutDev->DrawLine(aRect2.BottomLeft(),aRect2.BottomRight());
    }
    else
    {
        Polygon aPoly1(Rect2Poly(aRect1,aGeo));
        Polygon aPoly2(5);
        aPoly2[0]=aRect2.TopLeft();
        aPoly2[1]=aRect2.TopRight();
        aPoly2[2]=aRect2.BottomRight();
        aPoly2[3]=aRect2.BottomLeft();
        aPoly2[4]=aRect2.TopLeft();

        if (aGeo.nShearWink != 0)
            ShearPoly(aPoly2,aTopLeft,aGeo.nTan);

        if( aGeo.nDrehWink != 0 )
            RotatePoly(aPoly2,aTopLeft,aGeo.nSin,aGeo.nCos);

        if( bFill )
            pOutDev->DrawPolygon(aPoly1);

        if( pBmp != NULL )
            pOutDev->DrawBitmap( aBmpPos, *pBmp );

        pOutDev->SetFillColor();

        long        nHWink=NormAngle360(aGeo.nDrehWink);
        long        nVWink=NormAngle360(aGeo.nDrehWink-aGeo.nShearWink);
        FASTBOOL    bHorzChg=nHWink>13500 && nHWink<=31500;
        FASTBOOL    bVertChg=nVWink>4500 && nVWink<=22500;

        const StyleSettings& rStyleSettings = pOutDev->GetSettings().GetStyleSettings();
        Color a3DLightColor( rStyleSettings.GetLightColor() );
        Color a3DShadowColor( rStyleSettings.GetShadowColor() );

        pOutDev->SetLineColor( bHorzChg ? a3DShadowColor : a3DLightColor);
        pOutDev->DrawLine(aPoly2[0],aPoly2[1]);

        pOutDev->SetLineColor( bHorzChg ? a3DLightColor  : a3DShadowColor);
        pOutDev->DrawLine(aPoly2[2],aPoly2[3]);

        pOutDev->SetLineColor( bVertChg ? a3DLightColor  : a3DShadowColor);
        pOutDev->DrawLine(aPoly2[1],aPoly2[2]);

        pOutDev->SetLineColor( bVertChg ? a3DShadowColor : a3DLightColor);
        pOutDev->DrawLine(aPoly2[3],aPoly2[4]);

        pOutDev->SetLineColor( bHorzChg ? a3DLightColor  : a3DShadowColor);
        pOutDev->DrawLine(aPoly1[0],aPoly1[1]);

        pOutDev->SetLineColor( bHorzChg ? a3DShadowColor : a3DLightColor);
        pOutDev->DrawLine(aPoly1[2],aPoly1[3]);

        pOutDev->SetLineColor( bVertChg ? a3DShadowColor : a3DLightColor);
        pOutDev->DrawLine(aPoly1[1],aPoly1[2]);

        pOutDev->SetLineColor( bVertChg ? a3DLightColor  : a3DShadowColor);
        pOutDev->DrawLine(aPoly1[3],aPoly1[4]);
    }
    XubString aNam(rText);

    if(aNam.Len())
    {
        Size aOutSize(aTextRect.GetSize()); aOutSize.Width()-=6; aOutSize.Height()-=6;

        if (aOutSize.Width()>=4 || aOutSize.Height()>=4)
        {
            Point aOutPos(aTextRect.TopLeft()); aOutPos.X()+=3; aOutPos.Y()+=3;
            long nMaxOutY=aOutPos.Y()+aOutSize.Height();
            Font aFontMerk(pOutDev->GetFont());
            Font aFont( OutputDevice::GetDefaultFont( DEFAULTFONT_SANS_UNICODE, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ) );
            aFont.SetColor(COL_LIGHTRED);
            aFont.SetTransparent(TRUE);
            aFont.SetLineOrientation(USHORT(NormAngle360(aGeo.nDrehWink)/10));

            if (IsLinkedGraphic())
                aFont.SetUnderline(UNDERLINE_SINGLE);
            Size aFontSize(Size(0,aGeo.nDrehWink % 9000==0 ? 12 : 14));

            if (aFontSize.Height()>aOutSize.Height())
                aFontSize.Height()=aOutSize.Height();
            aFont.SetSize(aFontSize);
            pOutDev->SetFont(aFont);
            String aOutStr(aNam);

            while(aOutStr.Len() && aOutPos.Y() <= nMaxOutY)
            {
                String aStr1(aOutStr);
                INT32 nTextWidth = pOutDev->GetTextWidth(aStr1);
                INT32 nTextHeight = pOutDev->GetTextHeight();

                while(aStr1.Len() && nTextWidth > aOutSize.Width())
                {
                    aStr1.Erase(aStr1.Len() - 1);
                    nTextWidth = pOutDev->GetTextWidth(aStr1);
                    nTextHeight = pOutDev->GetTextHeight();
                }
                Point aPos(aOutPos);
                aOutPos.Y() += nTextHeight;

                if (aOutPos.Y()<=nMaxOutY)
                {
                    if (aGeo.nShearWink!=0) ShearPoint(aPos,aTopLeft,aGeo.nTan);
                    if (aGeo.nDrehWink!=0) RotatePoint(aPos,aTopLeft,aGeo.nSin,aGeo.nCos);
                    pOutDev->DrawText(aPos,aStr1);
                    aOutStr.Erase(0, aStr1.Len());
                }
            }
            pOutDev->SetFont(aFontMerk);
        }
    }
    pOutDev->EnableMapMode( bOldMap );
}

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

FASTBOOL SdrGrafObj::Paint( ExtOutputDevice& rOut, const SdrPaintInfoRec& rInfoRec ) const
{
    // Hidden objects on masterpages, draw nothing
    if( ( ( rInfoRec.nPaintMode & SDRPAINTMODE_MASTERPAGE ) && bNotVisibleAsMaster ) ||
        ( ( OUTDEV_PRINTER == rOut.GetOutDev()->GetOutDevType() ) && bEmptyPresObj ) )
    {
        return TRUE;
    }

    FASTBOOL        bDraft = ( 0 != ( rInfoRec.nPaintMode & SDRPAINTMODE_DRAFTGRAF ) );
    FASTBOOL        bSwappedOut = pGraphic->IsSwappedOut() || ( pGraphic->GetType() == GRAPHIC_NONE );
    FASTBOOL        bLoading = FALSE;
    OutputDevice*   pOutDev = rOut.GetOutDev();
    GDIMetaFile*    pRecMetaFile = pOutDev->GetConnectMetaFile();
    FASTBOOL        bMtfRecording = ( pRecMetaFile && pRecMetaFile->IsRecord() && !pRecMetaFile->IsPause() );
    const SdrView*  pView = ( rInfoRec.pPV ? &rInfoRec.pPV->GetView() : NULL );

    if( bSwappedOut && !bDraft )
    {
        if( !ImpUpdateGraphicLink() )
        {
            if( ( OUTDEV_WINDOW == pOutDev->GetOutDevType() ) && !bMtfRecording && pView && pView->IsSwapAsynchron() )
            {
                ( (SdrView*) pView )->ImpAddAsyncObj( this, pOutDev );
                bLoading = TRUE;
            }
            else
                ForceSwapIn();
        }
    }

    if( pGraphic->IsSwappedOut() || ( pGraphic->GetType() == GRAPHIC_NONE ) || ( pGraphic->GetType() == GRAPHIC_DEFAULT ) )
        bDraft=TRUE;

    long          nDrehWink = aGeo.nDrehWink, nShearWink = aGeo.nShearWink;
    FASTBOOL      bRotate = ( nDrehWink != 0 && nDrehWink != 18000 );
    FASTBOOL      bShear = ( nShearWink != 0 );
    FASTBOOL      bRota180 = nDrehWink == 18000;
    USHORT        nMirrorCase = ( bRota180 ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 ) );   //  4 | 3   H&V gespiegelt | nur Vertikal
    FASTBOOL      bHMirr = ( ( 2 == nMirrorCase ) || ( 4 == nMirrorCase ) );                    // ---+---  ---------------+-----------------
    FASTBOOL      bVMirr = ( ( 3 == nMirrorCase ) || ( 4 == nMirrorCase ) );                    //  2 | 1   nur Horizontal | nicht gespiegelt

    if( !bEmptyPresObj && !bDraft )
    {
        Point       aLogPos( aRect.TopLeft() );
        Size        aLogSize( aRect.GetSize() );
        GraphicAttr aAttr( aGrafInfo );

        aAttr.SetMirrorFlags( ( bHMirr ? BMP_MIRROR_HORZ : 0 ) | ( bVMirr ? BMP_MIRROR_VERT : 0 ) );

        if( bRota180 )
        {
            aLogPos.X() -= ( aLogSize.Width() - 1L );
            aLogPos.Y() -= ( aLogSize.Height() - 1L );
        }

        if( pGraphic->GetType() == GRAPHIC_BITMAP )
        {
            if( pGraphic->IsAnimated() )
            {
                SdrAnimationMode    eAnimMode = SDR_ANIMATION_ANIMATE;
                FASTBOOL            bEnable = TRUE;

                if( rInfoRec.pPV != NULL )
                {
                    eAnimMode= ((SdrPaintView&) rInfoRec.pPV->GetView()).GetAnimationMode();
                    bEnable = eAnimMode != SDR_ANIMATION_DISABLE;
                }

                // #98825# Look if graphics animation is disabled by
                // accessibility options
                if(bEnable)
                {
                    const SdrView& rTargetView = rInfoRec.pPV->GetView();
                    const SvtAccessibilityOptions& rOpt = ((SdrView&)rTargetView).getAccessibilityOptions();
                    sal_Bool bIsAllowedAnimatedGraphics = rOpt.GetIsAllowAnimatedGraphics();

                    if(!bIsAllowedAnimatedGraphics)
                    {
                        bEnable = FALSE;

                        // extra work to be done to make graphic visible at all
                        pGraphic->StopAnimation();
                        pGraphic->Draw(pOutDev, aLogPos, aLogSize, &aAttr);
                    }
                }

                if( bEnable )
                {
                    if( eAnimMode == SDR_ANIMATION_ANIMATE )
                    {
                        pGraphic->SetAnimationNotifyHdl( LINK( this, SdrGrafObj, ImpAnimationHdl ) );
                        pGraphic->StartAnimation( pOutDev, aLogPos, aLogSize, 0, &aAttr );
                    }
{'fraction_non_alphanumeric': 0.21735164280245647, 'fraction_numerical': 0.013292283633875775, 'mean_word_length': 1.822658513035082, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 340, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3603977', 'n_tokens_mistral': 20203, 'n_tokens_neox': 19310, 'n_words': 3402}