1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gfxlink.cxx,v $
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>
50 meType ( GFX_LINK_TYPE_NONE
),
55 mpImpData ( new ImpGfxLink
)
59 // ------------------------------------------------------------------------
61 GfxLink::GfxLink( const GfxLink
& rGfxLink
) :
62 mpImpData( new ImpGfxLink
)
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" );
81 mpBuf
= new ImpBuffer( pBuf
);
84 mpBuf
= new ImpBuffer( nSize
);
85 memcpy( mpBuf
->mpBuffer
, pBuf
, nSize
);
91 // ------------------------------------------------------------------------
95 if( mpBuf
&& !( --mpBuf
->mnRefCount
) )
98 if( mpSwap
&& !( --mpSwap
->mnRefCount
) )
104 // ------------------------------------------------------------------------
106 GfxLink
& GfxLink::operator=( const GfxLink
& rGfxLink
)
108 if( &rGfxLink
!= this )
110 if ( mpBuf
&& !( --mpBuf
->mnRefCount
) )
113 if( mpSwap
&& !( --mpSwap
->mnRefCount
) )
116 ImplCopy( rGfxLink
);
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 ) )
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
;
159 mpSwap
->mnRefCount
++;
162 // ------------------------------------------------------------------------
164 GfxLinkType
GfxLink::GetType() const
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
183 // ------------------------------------------------------------------------
185 const BYTE
* GfxLink::GetData() const
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
)
243 if( IsNative() && mnBufSize
)
245 const BYTE
* pData
= GetData();
249 SvMemoryStream aMemStm
;
252 aMemStm
.SetBuffer( (char*) pData
, mnBufSize
, FALSE
, mnBufSize
);
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
) )
275 // ------------------------------------------------------------------------
277 void GfxLink::SwapOut()
279 if( !IsSwappedOut() && mpBuf
)
281 mpSwap
= new ImpSwap( mpBuf
->mpBuffer
, mnBufSize
);
283 if( !mpSwap
->IsSwapped() )
290 if( !( --mpBuf
->mnRefCount
) )
298 // ------------------------------------------------------------------------
300 void GfxLink::SwapIn()
304 mpBuf
= new ImpBuffer( mpSwap
->GetData() );
306 if( !( --mpSwap
->mnRefCount
) )
313 // ------------------------------------------------------------------------
315 BOOL
GfxLink::ExportNative( SvStream
& rOStream
) const
320 mpSwap
->WriteTo( rOStream
);
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 );
335 rOStream
<< (UINT16
) rGfxLink
.GetType() << rGfxLink
.GetDataSize() << rGfxLink
.GetUserId();
338 rOStream
<< rGfxLink
.GetPrefSize() << rGfxLink
.GetPrefMapMode();
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() );
353 // ------------------------------------------------------------------------
355 SvStream
& operator>>( SvStream
& rIStream
, GfxLink
& rGfxLink
)
363 bool bMapAndSizeValid( false );
364 VersionCompat
* pCompat
= new VersionCompat( rIStream
, STREAM_READ
);
367 rIStream
>> nType
>> nSize
>> nUserId
;
369 if( pCompat
->GetVersion() >= 2 )
371 rIStream
>> aSize
>> aMapMode
;
372 bMapAndSizeValid
= true;
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
);
396 ImpSwap::ImpSwap( BYTE
* pData
, ULONG nDataSize
) :
397 mnDataSize( nDataSize
),
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
);
412 pOStm
->Write( pData
, mnDataSize
);
413 sal_Bool bError
= ( ERRCODE_NONE
!= pOStm
->GetError() );
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 // ------------------------------------------------------------------------
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
483 SvStream
* pIStm
= ::utl::UcbStreamHelper::CreateStream( maURL
.GetMainURL( INetURLObject::NO_DECODE
), STREAM_READWRITE
);
487 pData
= new BYTE
[ mnDataSize
];
488 pIStm
->Read( pData
, mnDataSize
);
489 sal_Bool bError
= ( ERRCODE_NONE
!= pIStm
->GetError() );
493 delete[] pData
, pData
= NULL
;
504 // ------------------------------------------------------------------------
506 void ImpSwap::WriteTo( SvStream
& rOStm
) const
508 BYTE
* pData
= GetData();
512 rOStm
.Write( pData
, mnDataSize
);