Files
libreoffice/vcl/source/gdi/gfxlink.cxx

482 lines
13 KiB
C++
Raw Normal View History

2000-09-18 16:07:07 +00:00
/*************************************************************************
*
* $RCSfile: gfxlink.cxx,v $
*
* $Revision: 1.7 $
2000-09-18 16:07:07 +00:00
*
* last change: $Author: ka $ $Date: 2002-07-19 12:59:17 $
2000-09-18 16:07:07 +00:00
*
* 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): _______________________________________
*
*
************************************************************************/
#include <tools/vcompat.hxx>
#include <tools/urlobj.hxx>
#include <tools/debug.hxx>
2000-11-07 16:09:05 +00:00
#include <unotools/ucbstreamhelper.hxx>
#include <unotools/tempfile.hxx>
2000-09-18 16:07:07 +00:00
#include <ucbhelper/content.hxx>
#include "graph.hxx"
#include "gfxlink.hxx"
#include "cvtgrf.hxx"
#ifndef _COM_SUN_STAR_UCB_COMMANDABORTEDEXCEPTION_HPP_
#include <com/sun/star/ucb/CommandAbortedException.hpp>
#endif
2000-09-18 16:07:07 +00:00
// -----------
// - GfxLink -
// -----------
GfxLink::GfxLink() :
meType ( GFX_LINK_TYPE_NONE ),
mnBufSize ( 0 ),
mpBuf ( NULL ),
mpSwap ( NULL ),
mnUserId ( 0UL ),
mpImpData ( new ImpGfxLink )
2000-09-18 16:07:07 +00:00
{
}
// ------------------------------------------------------------------------
GfxLink::GfxLink( const GfxLink& rGfxLink ) :
mpImpData( new ImpGfxLink )
2000-09-18 16:07:07 +00:00
{
ImplCopy( rGfxLink );
}
// ------------------------------------------------------------------------
GfxLink::GfxLink( BYTE* pBuf, ULONG nSize, GfxLinkType nType, BOOL bOwns ) :
mpImpData( new ImpGfxLink )
2000-09-18 16:07:07 +00:00
{
meType = nType;
mnBufSize = nSize;
mpSwap = NULL;
mnUserId = 0UL;
if( bOwns )
mpBuf = new ImpBuffer( pBuf );
else if( nSize )
{
mpBuf = new ImpBuffer( nSize );
memcpy( mpBuf->mpBuffer, pBuf, nSize );
}
else
mpBuf = NULL;
}
// ------------------------------------------------------------------------
GfxLink::~GfxLink()
{
if( mpBuf && !( --mpBuf->mnRefCount ) )
delete mpBuf;
if( mpSwap && !( --mpSwap->mnRefCount ) )
delete mpSwap;
delete mpImpData;
2000-09-18 16:07:07 +00:00
}
// ------------------------------------------------------------------------
GfxLink& GfxLink::operator=( const GfxLink& rGfxLink )
{
if( &rGfxLink != this )
{
if ( mpBuf && !( --mpBuf->mnRefCount ) )
delete mpBuf;
if( mpSwap && !( --mpSwap->mnRefCount ) )
delete mpSwap;
ImplCopy( rGfxLink );
}
return *this;
}
// ------------------------------------------------------------------------
void GfxLink::ImplCopy( const GfxLink& rGfxLink )
{
mnBufSize = rGfxLink.mnBufSize;
meType = rGfxLink.meType;
mpBuf = rGfxLink.mpBuf;
mpSwap = rGfxLink.mpSwap;
mnUserId = rGfxLink.mnUserId;
*mpImpData = *rGfxLink.mpImpData;
2000-09-18 16:07:07 +00:00
if( mpBuf )
mpBuf->mnRefCount++;
if( mpSwap )
mpSwap->mnRefCount++;
}
// ------------------------------------------------------------------------
GfxLinkType GfxLink::GetType() const
{
return meType;
}
// ------------------------------------------------------------------------
BOOL GfxLink::IsNative() const
{
return( meType >= GFX_LINK_FIRST_NATIVE_ID && meType <= GFX_LINK_LAST_NATIVE_ID );
}
// ------------------------------------------------------------------------
ULONG GfxLink::GetDataSize() const
{
return mnBufSize;
}
// ------------------------------------------------------------------------
const BYTE* GfxLink::GetData() const
{
if( IsSwappedOut() )
( (GfxLink*) this )->SwapIn();
return( mpBuf ? mpBuf->mpBuffer : NULL );
}
// ------------------------------------------------------------------------
const Size& GfxLink::GetPrefSize() const
{
return mpImpData->maPrefSize;
}
// ------------------------------------------------------------------------
void GfxLink::SetPrefSize( const Size& rPrefSize )
{
mpImpData->maPrefSize = rPrefSize;
}
// ------------------------------------------------------------------------
const MapMode& GfxLink::GetPrefMapMode() const
{
return mpImpData->maPrefMapMode;
}
// ------------------------------------------------------------------------
void GfxLink::SetPrefMapMode( const MapMode& rPrefMapMode )
{
mpImpData->maPrefMapMode = rPrefMapMode;
}
// ------------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
BOOL GfxLink::LoadNative( Graphic& rGraphic )
{
BOOL bRet = FALSE;
if( IsNative() && mnBufSize )
{
const BYTE* pData = GetData();
if( pData )
{
SvMemoryStream aMemStm;
ULONG nCvtType;
aMemStm.SetBuffer( (char*) pData, mnBufSize, FALSE, mnBufSize );
switch( meType )
{
case( GFX_LINK_TYPE_NATIVE_GIF ): nCvtType = CVT_GIF; break;
case( GFX_LINK_TYPE_NATIVE_JPG ): nCvtType = CVT_JPG; break;
case( GFX_LINK_TYPE_NATIVE_PNG ): nCvtType = CVT_PNG; break;
case( GFX_LINK_TYPE_NATIVE_TIF ): nCvtType = CVT_TIF; break;
case( GFX_LINK_TYPE_NATIVE_WMF ): nCvtType = CVT_WMF; break;
case( GFX_LINK_TYPE_NATIVE_MET ): nCvtType = CVT_MET; break;
case( GFX_LINK_TYPE_NATIVE_PCT ): nCvtType = CVT_PCT; break;
default: nCvtType = CVT_UNKNOWN; break;
}
if( nCvtType && ( GraphicConverter::Import( aMemStm, rGraphic, nCvtType ) == ERRCODE_NONE ) )
bRet = TRUE;
}
}
return bRet;
}
// ------------------------------------------------------------------------
void GfxLink::SwapOut()
{
if( !IsSwappedOut() && mpBuf )
{
mpSwap = new ImpSwap( mpBuf->mpBuffer, mnBufSize );
if( !mpSwap->IsSwapped() )
{
delete mpSwap;
mpSwap = NULL;
}
else if( !( --mpBuf->mnRefCount ) )
delete mpBuf;
mpBuf = NULL;
}
}
// ------------------------------------------------------------------------
void GfxLink::SwapIn()
{
if( IsSwappedOut() )
{
mpBuf = new ImpBuffer( mpSwap->GetData() );
if( !( --mpSwap->mnRefCount ) )
delete mpSwap;
mpSwap = NULL;
}
}
// ------------------------------------------------------------------------
SvStream& operator<<( SvStream& rOStream, const GfxLink& rGfxLink )
{
VersionCompat* pCompat = new VersionCompat( rOStream, STREAM_WRITE, 2 );
2000-09-18 16:07:07 +00:00
// Version 1
2000-09-18 16:07:07 +00:00
rOStream << (UINT16) rGfxLink.GetType() << rGfxLink.GetDataSize() << rGfxLink.GetUserId();
// Version 2
rOStream << rGfxLink.GetPrefSize() << rGfxLink.GetPrefMapMode();
2000-09-18 16:07:07 +00:00
delete pCompat;
if( rGfxLink.GetDataSize() )
{
if( rGfxLink.IsSwappedOut() )
rGfxLink.mpSwap->WriteTo( rOStream );
else
rOStream.Write( rGfxLink.GetData(), rGfxLink.GetDataSize() );
}
return rOStream;
}
// ------------------------------------------------------------------------
SvStream& operator>>( SvStream& rIStream, GfxLink& rGfxLink)
{
Size aSize;
MapMode aMapMode;
2000-09-18 16:07:07 +00:00
ULONG nSize;
ULONG nUserId;
UINT16 nType;
BYTE* pBuf;
VersionCompat* pCompat = new VersionCompat( rIStream, STREAM_READ );
// Version 1
2000-09-18 16:07:07 +00:00
rIStream >> nType >> nSize >> nUserId;
if( pCompat->GetVersion() >= 2 )
{
rIStream >> aSize >> aMapMode;
}
2000-09-18 16:07:07 +00:00
delete pCompat;
pBuf = new BYTE[ nSize ];
rIStream.Read( pBuf, nSize );
rGfxLink = GfxLink( pBuf, nSize, (GfxLinkType) nType, TRUE );
rGfxLink.SetUserId( nUserId );
rGfxLink.SetPrefSize( aSize );
rGfxLink.SetPrefMapMode( aMapMode );
2000-09-18 16:07:07 +00:00
return rIStream;
}
// -----------
// - ImpSwap -
// -----------
ImpSwap::ImpSwap( BYTE* pData, ULONG nDataSize ) :
mnDataSize( nDataSize ),
mnRefCount( 1UL )
{
if( pData && mnDataSize )
{
2000-11-07 16:09:05 +00:00
::utl::TempFile aTempFile;
2000-09-18 16:07:07 +00:00
2000-11-07 16:09:05 +00:00
maURL = aTempFile.GetURL();
2000-09-18 16:07:07 +00:00
if( maURL.GetMainURL( INetURLObject::NO_DECODE ).Len() )
2000-11-07 16:09:05 +00:00
{
SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( maURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
2000-09-18 16:07:07 +00:00
2000-11-07 16:09:05 +00:00
if( pOStm )
2000-09-18 16:07:07 +00:00
{
2000-11-07 16:09:05 +00:00
pOStm->Write( pData, mnDataSize );
sal_Bool bError = ( ERRCODE_NONE != pOStm->GetError() );
delete pOStm;
2000-09-18 16:07:07 +00:00
2000-11-07 16:09:05 +00:00
if( bError )
2000-09-18 16:07:07 +00:00
{
2000-11-07 16:09:05 +00:00
try
{
::ucb::Content aCnt( maURL.GetMainURL( INetURLObject::NO_DECODE ),
2000-11-07 16:09:05 +00:00
::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
}
2001-01-25 14:50:03 +00:00
catch( const ::com::sun::star::ucb::ContentCreationException& )
2000-11-07 16:09:05 +00:00
{
}
2001-01-25 14:50:03 +00:00
catch( const ::com::sun::star::uno::RuntimeException& )
2000-11-07 16:09:05 +00:00
{
2001-01-25 14:50:03 +00:00
}
catch( const ::com::sun::star::ucb::CommandAbortedException& )
{
2001-06-11 12:26:43 +00:00
}
catch( const ::com::sun::star::uno::Exception& )
{
2000-11-07 16:09:05 +00:00
}
maURL = INetURLObject();
2000-09-18 16:07:07 +00:00
}
}
}
}
}
// ------------------------------------------------------------------------
ImpSwap::~ImpSwap()
{
if( IsSwapped() )
{
try
{
::ucb::Content aCnt( maURL.GetMainURL( INetURLObject::NO_DECODE ),
2000-09-18 16:07:07 +00:00
::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
}
2001-01-25 14:50:03 +00:00
catch( const ::com::sun::star::ucb::ContentCreationException& )
{
}
catch( const ::com::sun::star::uno::RuntimeException& )
2000-09-18 16:07:07 +00:00
{
}
2001-01-25 14:50:03 +00:00
catch( const ::com::sun::star::ucb::CommandAbortedException& )
2000-09-18 16:07:07 +00:00
{
2001-06-11 12:26:43 +00:00
}
catch( const ::com::sun::star::uno::Exception& )
{
2000-09-18 16:07:07 +00:00
}
}
}
// ------------------------------------------------------------------------
BYTE* ImpSwap::GetData() const
{
BYTE* pData;
if( IsSwapped() )
{
SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( maURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE );
2000-09-18 16:07:07 +00:00
2000-11-07 16:09:05 +00:00
if( pIStm )
2000-09-18 16:07:07 +00:00
{
2000-11-07 16:09:05 +00:00
pData = new BYTE[ mnDataSize ];
pIStm->Read( pData, mnDataSize );
sal_Bool bError = ( ERRCODE_NONE != pIStm->GetError() );
delete pIStm;
if( bError )
delete[] pData, pData = NULL;
2000-09-18 16:07:07 +00:00
}
2000-11-07 16:09:05 +00:00
else
pData = NULL;
2000-09-18 16:07:07 +00:00
}
else
pData = NULL;
return pData;
}
// ------------------------------------------------------------------------
void ImpSwap::WriteTo( SvStream& rOStm ) const
{
BYTE* pData = GetData();
if( pData )
{
rOStm.Write( pData, mnDataSize );
delete[] pData;
}
}