Update ooo320-m1
[ooovba.git] / vcl / source / gdi / gfxlink.cxx
blob2a4f5aa8ab165e8c3c142ee12918b79429c11a98
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gfxlink.cxx,v $
10 * $Revision: 1.19 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include <tools/vcompat.hxx>
35 #include <tools/urlobj.hxx>
36 #include <tools/debug.hxx>
37 #include <unotools/ucbstreamhelper.hxx>
38 #include <unotools/tempfile.hxx>
39 #include <ucbhelper/content.hxx>
40 #include <vcl/graph.hxx>
41 #include <vcl/gfxlink.hxx>
42 #include <vcl/cvtgrf.hxx>
43 #include <com/sun/star/ucb/CommandAbortedException.hpp>
45 // -----------
46 // - GfxLink -
47 // -----------
49 GfxLink::GfxLink() :
50 meType ( GFX_LINK_TYPE_NONE ),
51 mpBuf ( NULL ),
52 mpSwap ( NULL ),
53 mnBufSize ( 0 ),
54 mnUserId ( 0UL ),
55 mpImpData ( new ImpGfxLink )
59 // ------------------------------------------------------------------------
61 GfxLink::GfxLink( const GfxLink& rGfxLink ) :
62 mpImpData( new ImpGfxLink )
64 ImplCopy( rGfxLink );
67 // ------------------------------------------------------------------------
69 GfxLink::GfxLink( BYTE* pBuf, sal_uInt32 nSize, GfxLinkType nType, BOOL bOwns ) :
70 mpImpData( new ImpGfxLink )
72 DBG_ASSERT( (pBuf != NULL && nSize) || (!bOwns && nSize == 0),
73 "GfxLink::GfxLink(): empty/NULL buffer given" );
75 meType = nType;
76 mnBufSize = nSize;
77 mpSwap = NULL;
78 mnUserId = 0UL;
80 if( bOwns )
81 mpBuf = new ImpBuffer( pBuf );
82 else if( nSize )
84 mpBuf = new ImpBuffer( nSize );
85 memcpy( mpBuf->mpBuffer, pBuf, nSize );
87 else
88 mpBuf = NULL;
91 // ------------------------------------------------------------------------
93 GfxLink::~GfxLink()
95 if( mpBuf && !( --mpBuf->mnRefCount ) )
96 delete mpBuf;
98 if( mpSwap && !( --mpSwap->mnRefCount ) )
99 delete mpSwap;
101 delete mpImpData;
104 // ------------------------------------------------------------------------
106 GfxLink& GfxLink::operator=( const GfxLink& rGfxLink )
108 if( &rGfxLink != this )
110 if ( mpBuf && !( --mpBuf->mnRefCount ) )
111 delete mpBuf;
113 if( mpSwap && !( --mpSwap->mnRefCount ) )
114 delete mpSwap;
116 ImplCopy( rGfxLink );
119 return *this;
122 // ------------------------------------------------------------------------
124 sal_Bool GfxLink::IsEqual( const GfxLink& rGfxLink ) const
126 sal_Bool bIsEqual = sal_False;
128 if ( ( mnBufSize == rGfxLink.mnBufSize ) && ( meType == rGfxLink.meType ) )
130 const sal_uInt8* pSource = GetData();
131 const sal_uInt8* pDest = rGfxLink.GetData();
132 sal_uInt32 nSourceSize = GetDataSize();
133 sal_uInt32 nDestSize = rGfxLink.GetDataSize();
134 if ( pSource && pDest && ( nSourceSize == nDestSize ) )
136 bIsEqual = memcmp( pSource, pDest, nSourceSize ) == 0;
138 else if ( ( pSource == 0 ) && ( pDest == 0 ) )
139 bIsEqual = sal_True;
141 return bIsEqual;
144 // ------------------------------------------------------------------------
146 void GfxLink::ImplCopy( const GfxLink& rGfxLink )
148 mnBufSize = rGfxLink.mnBufSize;
149 meType = rGfxLink.meType;
150 mpBuf = rGfxLink.mpBuf;
151 mpSwap = rGfxLink.mpSwap;
152 mnUserId = rGfxLink.mnUserId;
153 *mpImpData = *rGfxLink.mpImpData;
155 if( mpBuf )
156 mpBuf->mnRefCount++;
158 if( mpSwap )
159 mpSwap->mnRefCount++;
162 // ------------------------------------------------------------------------
164 GfxLinkType GfxLink::GetType() const
166 return meType;
169 // ------------------------------------------------------------------------
171 BOOL GfxLink::IsNative() const
173 return( meType >= GFX_LINK_FIRST_NATIVE_ID && meType <= GFX_LINK_LAST_NATIVE_ID );
176 // ------------------------------------------------------------------------
178 sal_uInt32 GfxLink::GetDataSize() const
180 return mnBufSize;
183 // ------------------------------------------------------------------------
185 const BYTE* GfxLink::GetData() const
187 if( IsSwappedOut() )
188 ( (GfxLink*) this )->SwapIn();
190 return( mpBuf ? mpBuf->mpBuffer : NULL );
193 // ------------------------------------------------------------------------
195 const Size& GfxLink::GetPrefSize() const
197 return mpImpData->maPrefSize;
200 // ------------------------------------------------------------------------
202 void GfxLink::SetPrefSize( const Size& rPrefSize )
204 mpImpData->maPrefSize = rPrefSize;
205 mpImpData->mbPrefSizeValid = true;
208 // ------------------------------------------------------------------------
210 bool GfxLink::IsPrefSizeValid()
212 return mpImpData->mbPrefSizeValid;
215 // ------------------------------------------------------------------------
217 const MapMode& GfxLink::GetPrefMapMode() const
219 return mpImpData->maPrefMapMode;
222 // ------------------------------------------------------------------------
224 void GfxLink::SetPrefMapMode( const MapMode& rPrefMapMode )
226 mpImpData->maPrefMapMode = rPrefMapMode;
227 mpImpData->mbPrefMapModeValid = true;
230 // ------------------------------------------------------------------------
232 bool GfxLink::IsPrefMapModeValid()
234 return mpImpData->mbPrefMapModeValid;
237 // ------------------------------------------------------------------------
239 BOOL GfxLink::LoadNative( Graphic& rGraphic )
241 BOOL bRet = FALSE;
243 if( IsNative() && mnBufSize )
245 const BYTE* pData = GetData();
247 if( pData )
249 SvMemoryStream aMemStm;
250 ULONG nCvtType;
252 aMemStm.SetBuffer( (char*) pData, mnBufSize, FALSE, mnBufSize );
254 switch( meType )
256 case( GFX_LINK_TYPE_NATIVE_GIF ): nCvtType = CVT_GIF; break;
257 case( GFX_LINK_TYPE_NATIVE_JPG ): nCvtType = CVT_JPG; break;
258 case( GFX_LINK_TYPE_NATIVE_PNG ): nCvtType = CVT_PNG; break;
259 case( GFX_LINK_TYPE_NATIVE_TIF ): nCvtType = CVT_TIF; break;
260 case( GFX_LINK_TYPE_NATIVE_WMF ): nCvtType = CVT_WMF; break;
261 case( GFX_LINK_TYPE_NATIVE_MET ): nCvtType = CVT_MET; break;
262 case( GFX_LINK_TYPE_NATIVE_PCT ): nCvtType = CVT_PCT; break;
264 default: nCvtType = CVT_UNKNOWN; break;
267 if( nCvtType && ( GraphicConverter::Import( aMemStm, rGraphic, nCvtType ) == ERRCODE_NONE ) )
268 bRet = TRUE;
272 return bRet;
275 // ------------------------------------------------------------------------
277 void GfxLink::SwapOut()
279 if( !IsSwappedOut() && mpBuf )
281 mpSwap = new ImpSwap( mpBuf->mpBuffer, mnBufSize );
283 if( !mpSwap->IsSwapped() )
285 delete mpSwap;
286 mpSwap = NULL;
288 else
290 if( !( --mpBuf->mnRefCount ) )
291 delete mpBuf;
293 mpBuf = NULL;
298 // ------------------------------------------------------------------------
300 void GfxLink::SwapIn()
302 if( IsSwappedOut() )
304 mpBuf = new ImpBuffer( mpSwap->GetData() );
306 if( !( --mpSwap->mnRefCount ) )
307 delete mpSwap;
309 mpSwap = NULL;
313 // ------------------------------------------------------------------------
315 BOOL GfxLink::ExportNative( SvStream& rOStream ) const
317 if( GetDataSize() )
319 if( IsSwappedOut() )
320 mpSwap->WriteTo( rOStream );
321 else if( GetData() )
322 rOStream.Write( GetData(), GetDataSize() );
325 return ( rOStream.GetError() == ERRCODE_NONE );
328 // ------------------------------------------------------------------------
330 SvStream& operator<<( SvStream& rOStream, const GfxLink& rGfxLink )
332 VersionCompat* pCompat = new VersionCompat( rOStream, STREAM_WRITE, 2 );
334 // Version 1
335 rOStream << (UINT16) rGfxLink.GetType() << rGfxLink.GetDataSize() << rGfxLink.GetUserId();
337 // Version 2
338 rOStream << rGfxLink.GetPrefSize() << rGfxLink.GetPrefMapMode();
340 delete pCompat;
342 if( rGfxLink.GetDataSize() )
344 if( rGfxLink.IsSwappedOut() )
345 rGfxLink.mpSwap->WriteTo( rOStream );
346 else if( rGfxLink.GetData() )
347 rOStream.Write( rGfxLink.GetData(), rGfxLink.GetDataSize() );
350 return rOStream;
353 // ------------------------------------------------------------------------
355 SvStream& operator>>( SvStream& rIStream, GfxLink& rGfxLink)
357 Size aSize;
358 MapMode aMapMode;
359 sal_uInt32 nSize;
360 sal_uInt32 nUserId;
361 UINT16 nType;
362 BYTE* pBuf;
363 bool bMapAndSizeValid( false );
364 VersionCompat* pCompat = new VersionCompat( rIStream, STREAM_READ );
366 // Version 1
367 rIStream >> nType >> nSize >> nUserId;
369 if( pCompat->GetVersion() >= 2 )
371 rIStream >> aSize >> aMapMode;
372 bMapAndSizeValid = true;
375 delete pCompat;
377 pBuf = new BYTE[ nSize ];
378 rIStream.Read( pBuf, nSize );
380 rGfxLink = GfxLink( pBuf, nSize, (GfxLinkType) nType, TRUE );
381 rGfxLink.SetUserId( nUserId );
383 if( bMapAndSizeValid )
385 rGfxLink.SetPrefSize( aSize );
386 rGfxLink.SetPrefMapMode( aMapMode );
389 return rIStream;
392 // -----------
393 // - ImpSwap -
394 // -----------
396 ImpSwap::ImpSwap( BYTE* pData, ULONG nDataSize ) :
397 mnDataSize( nDataSize ),
398 mnRefCount( 1UL )
400 if( pData && mnDataSize )
402 ::utl::TempFile aTempFile;
404 maURL = INetURLObject(aTempFile.GetURL());
406 if( maURL.GetMainURL( INetURLObject::NO_DECODE ).getLength() )
408 SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( maURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
410 if( pOStm )
412 pOStm->Write( pData, mnDataSize );
413 sal_Bool bError = ( ERRCODE_NONE != pOStm->GetError() );
414 delete pOStm;
416 if( bError )
420 ::ucbhelper::Content aCnt( maURL.GetMainURL( INetURLObject::NO_DECODE ),
421 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
423 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
424 ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
426 catch( const ::com::sun::star::ucb::ContentCreationException& )
429 catch( const ::com::sun::star::uno::RuntimeException& )
432 catch( const ::com::sun::star::ucb::CommandAbortedException& )
435 catch( const ::com::sun::star::uno::Exception& )
439 maURL = INetURLObject();
446 // ------------------------------------------------------------------------
448 ImpSwap::~ImpSwap()
450 if( IsSwapped() )
454 ::ucbhelper::Content aCnt( maURL.GetMainURL( INetURLObject::NO_DECODE ),
455 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
457 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
458 ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
460 catch( const ::com::sun::star::ucb::ContentCreationException& )
463 catch( const ::com::sun::star::uno::RuntimeException& )
466 catch( const ::com::sun::star::ucb::CommandAbortedException& )
469 catch( const ::com::sun::star::uno::Exception& )
475 // ------------------------------------------------------------------------
477 BYTE* ImpSwap::GetData() const
479 BYTE* pData;
481 if( IsSwapped() )
483 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( maURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE );
485 if( pIStm )
487 pData = new BYTE[ mnDataSize ];
488 pIStm->Read( pData, mnDataSize );
489 sal_Bool bError = ( ERRCODE_NONE != pIStm->GetError() );
490 delete pIStm;
492 if( bError )
493 delete[] pData, pData = NULL;
495 else
496 pData = NULL;
498 else
499 pData = NULL;
501 return pData;
504 // ------------------------------------------------------------------------
506 void ImpSwap::WriteTo( SvStream& rOStm ) const
508 BYTE* pData = GetData();
510 if( pData )
512 rOStm.Write( pData, mnDataSize );
513 delete[] pData;