bump product version to 4.2.0.1
[LibreOffice.git] / vcl / source / gdi / gfxlink.cxx
blob4dc576faa2b2dcaa0ceb2b9942c366a1a8aec978
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <osl/file.h>
22 #include <tools/vcompat.hxx>
23 #include <tools/debug.hxx>
24 #include <unotools/ucbstreamhelper.hxx>
25 #include <unotools/tempfile.hxx>
26 #include <ucbhelper/content.hxx>
27 #include <vcl/graph.hxx>
28 #include <vcl/gfxlink.hxx>
29 #include <vcl/cvtgrf.hxx>
30 #include <com/sun/star/ucb/CommandAbortedException.hpp>
32 GfxLink::GfxLink() :
33 meType ( GFX_LINK_TYPE_NONE ),
34 mpBuf ( NULL ),
35 mpSwap ( NULL ),
36 mnBufSize ( 0 ),
37 mnUserId ( 0UL ),
38 mpImpData ( new ImpGfxLink )
42 GfxLink::GfxLink( const GfxLink& rGfxLink ) :
43 mpImpData( new ImpGfxLink )
45 ImplCopy( rGfxLink );
48 GfxLink::GfxLink( sal_uInt8* pBuf, sal_uInt32 nSize, GfxLinkType nType, sal_Bool bOwns ) :
49 mpImpData( new ImpGfxLink )
51 DBG_ASSERT( (pBuf != NULL && nSize) || (!bOwns && nSize == 0),
52 "GfxLink::GfxLink(): empty/NULL buffer given" );
54 meType = nType;
55 mnBufSize = nSize;
56 mpSwap = NULL;
57 mnUserId = 0UL;
59 if( bOwns )
60 mpBuf = new ImpBuffer( pBuf );
61 else if( nSize )
63 mpBuf = new ImpBuffer( nSize );
64 memcpy( mpBuf->mpBuffer, pBuf, nSize );
66 else
67 mpBuf = NULL;
70 GfxLink::~GfxLink()
72 if( mpBuf && !( --mpBuf->mnRefCount ) )
73 delete mpBuf;
75 if( mpSwap && !( --mpSwap->mnRefCount ) )
76 delete mpSwap;
78 delete mpImpData;
81 GfxLink& GfxLink::operator=( const GfxLink& rGfxLink )
83 if( &rGfxLink != this )
85 if ( mpBuf && !( --mpBuf->mnRefCount ) )
86 delete mpBuf;
88 if( mpSwap && !( --mpSwap->mnRefCount ) )
89 delete mpSwap;
91 ImplCopy( rGfxLink );
94 return *this;
97 sal_Bool GfxLink::IsEqual( const GfxLink& rGfxLink ) const
99 sal_Bool bIsEqual = sal_False;
101 if ( ( mnBufSize == rGfxLink.mnBufSize ) && ( meType == rGfxLink.meType ) )
103 const sal_uInt8* pSource = GetData();
104 const sal_uInt8* pDest = rGfxLink.GetData();
105 sal_uInt32 nSourceSize = GetDataSize();
106 sal_uInt32 nDestSize = rGfxLink.GetDataSize();
107 if ( pSource && pDest && ( nSourceSize == nDestSize ) )
109 bIsEqual = memcmp( pSource, pDest, nSourceSize ) == 0;
111 else if ( ( pSource == 0 ) && ( pDest == 0 ) )
112 bIsEqual = sal_True;
114 return bIsEqual;
117 void GfxLink::ImplCopy( const GfxLink& rGfxLink )
119 mnBufSize = rGfxLink.mnBufSize;
120 meType = rGfxLink.meType;
121 mpBuf = rGfxLink.mpBuf;
122 mpSwap = rGfxLink.mpSwap;
123 mnUserId = rGfxLink.mnUserId;
124 *mpImpData = *rGfxLink.mpImpData;
126 if( mpBuf )
127 mpBuf->mnRefCount++;
129 if( mpSwap )
130 mpSwap->mnRefCount++;
133 GfxLinkType GfxLink::GetType() const
135 return meType;
138 sal_Bool GfxLink::IsNative() const
140 return( meType >= GFX_LINK_FIRST_NATIVE_ID && meType <= GFX_LINK_LAST_NATIVE_ID );
143 sal_uInt32 GfxLink::GetDataSize() const
145 return mnBufSize;
148 const sal_uInt8* GfxLink::GetData() const
150 if( IsSwappedOut() )
151 ( (GfxLink*) this )->SwapIn();
153 return( mpBuf ? mpBuf->mpBuffer : NULL );
156 const Size& GfxLink::GetPrefSize() const
158 return mpImpData->maPrefSize;
161 void GfxLink::SetPrefSize( const Size& rPrefSize )
163 mpImpData->maPrefSize = rPrefSize;
164 mpImpData->mbPrefSizeValid = true;
167 bool GfxLink::IsPrefSizeValid()
169 return mpImpData->mbPrefSizeValid;
172 const MapMode& GfxLink::GetPrefMapMode() const
174 return mpImpData->maPrefMapMode;
177 void GfxLink::SetPrefMapMode( const MapMode& rPrefMapMode )
179 mpImpData->maPrefMapMode = rPrefMapMode;
180 mpImpData->mbPrefMapModeValid = true;
183 bool GfxLink::IsPrefMapModeValid()
185 return mpImpData->mbPrefMapModeValid;
188 sal_Bool GfxLink::LoadNative( Graphic& rGraphic )
190 sal_Bool bRet = sal_False;
192 if( IsNative() && mnBufSize )
194 const sal_uInt8* pData = GetData();
196 if( pData )
198 SvMemoryStream aMemStm;
199 sal_uLong nCvtType;
201 aMemStm.SetBuffer( (char*) pData, mnBufSize, sal_False, mnBufSize );
203 switch( meType )
205 case( GFX_LINK_TYPE_NATIVE_GIF ): nCvtType = CVT_GIF; break;
206 case( GFX_LINK_TYPE_NATIVE_JPG ): nCvtType = CVT_JPG; break;
207 case( GFX_LINK_TYPE_NATIVE_PNG ): nCvtType = CVT_PNG; break;
208 case( GFX_LINK_TYPE_NATIVE_TIF ): nCvtType = CVT_TIF; break;
209 case( GFX_LINK_TYPE_NATIVE_WMF ): nCvtType = CVT_WMF; break;
210 case( GFX_LINK_TYPE_NATIVE_MET ): nCvtType = CVT_MET; break;
211 case( GFX_LINK_TYPE_NATIVE_PCT ): nCvtType = CVT_PCT; break;
212 case( GFX_LINK_TYPE_NATIVE_SVG ): nCvtType = CVT_SVG; break;
214 default: nCvtType = CVT_UNKNOWN; break;
217 if( nCvtType && ( GraphicConverter::Import( aMemStm, rGraphic, nCvtType ) == ERRCODE_NONE ) )
218 bRet = sal_True;
222 return bRet;
225 void GfxLink::SwapOut()
227 if( !IsSwappedOut() && mpBuf )
229 mpSwap = new ImpSwap( mpBuf->mpBuffer, mnBufSize );
231 if( !mpSwap->IsSwapped() )
233 delete mpSwap;
234 mpSwap = NULL;
236 else
238 if( !( --mpBuf->mnRefCount ) )
239 delete mpBuf;
241 mpBuf = NULL;
246 void GfxLink::SwapIn()
248 if( IsSwappedOut() )
250 mpBuf = new ImpBuffer( mpSwap->GetData() );
252 if( !( --mpSwap->mnRefCount ) )
253 delete mpSwap;
255 mpSwap = NULL;
259 sal_Bool GfxLink::ExportNative( SvStream& rOStream ) const
261 if( GetDataSize() )
263 if( IsSwappedOut() )
264 mpSwap->WriteTo( rOStream );
265 else if( GetData() )
266 rOStream.Write( GetData(), GetDataSize() );
269 return ( rOStream.GetError() == ERRCODE_NONE );
272 SvStream& operator<<( SvStream& rOStream, const GfxLink& rGfxLink )
274 VersionCompat* pCompat = new VersionCompat( rOStream, STREAM_WRITE, 2 );
276 // Version 1
277 rOStream << (sal_uInt16) rGfxLink.GetType() << rGfxLink.GetDataSize() << rGfxLink.GetUserId();
279 // Version 2
280 rOStream << rGfxLink.GetPrefSize() << rGfxLink.GetPrefMapMode();
282 delete pCompat;
284 if( rGfxLink.GetDataSize() )
286 if( rGfxLink.IsSwappedOut() )
287 rGfxLink.mpSwap->WriteTo( rOStream );
288 else if( rGfxLink.GetData() )
289 rOStream.Write( rGfxLink.GetData(), rGfxLink.GetDataSize() );
292 return rOStream;
295 SvStream& operator>>( SvStream& rIStream, GfxLink& rGfxLink)
297 Size aSize;
298 MapMode aMapMode;
299 sal_uInt32 nSize;
300 sal_uInt32 nUserId;
301 sal_uInt16 nType;
302 sal_uInt8* pBuf;
303 bool bMapAndSizeValid( false );
304 VersionCompat* pCompat = new VersionCompat( rIStream, STREAM_READ );
306 // Version 1
307 rIStream >> nType >> nSize >> nUserId;
309 if( pCompat->GetVersion() >= 2 )
311 rIStream >> aSize >> aMapMode;
312 bMapAndSizeValid = true;
315 delete pCompat;
317 pBuf = new sal_uInt8[ nSize ];
318 rIStream.Read( pBuf, nSize );
320 rGfxLink = GfxLink( pBuf, nSize, (GfxLinkType) nType, sal_True );
321 rGfxLink.SetUserId( nUserId );
323 if( bMapAndSizeValid )
325 rGfxLink.SetPrefSize( aSize );
326 rGfxLink.SetPrefMapMode( aMapMode );
329 return rIStream;
332 ImpSwap::ImpSwap( sal_uInt8* pData, sal_uLong nDataSize ) :
333 mnDataSize( nDataSize ),
334 mnRefCount( 1UL )
336 if( pData && mnDataSize )
338 ::utl::TempFile aTempFile;
340 maURL = aTempFile.GetURL();
341 if( !maURL.isEmpty() )
343 SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( maURL, STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
344 if( pOStm )
346 pOStm->Write( pData, mnDataSize );
347 bool bError = ( ERRCODE_NONE != pOStm->GetError() );
348 delete pOStm;
350 if( bError )
352 osl_removeFile( maURL.pData );
353 maURL = "";
360 ImpSwap::~ImpSwap()
362 if( IsSwapped() )
363 osl_removeFile( maURL.pData );
366 sal_uInt8* ImpSwap::GetData() const
368 sal_uInt8* pData;
370 if( IsSwapped() )
372 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( maURL, STREAM_READWRITE );
373 if( pIStm )
375 pData = new sal_uInt8[ mnDataSize ];
376 pIStm->Read( pData, mnDataSize );
377 bool bError = ( ERRCODE_NONE != pIStm->GetError() );
378 sal_Size nActReadSize = pIStm->Tell();
379 if (nActReadSize != mnDataSize)
381 bError = true;
383 delete pIStm;
385 if( bError )
386 delete[] pData, pData = NULL;
388 else
389 pData = NULL;
391 else
392 pData = NULL;
394 return pData;
397 void ImpSwap::WriteTo( SvStream& rOStm ) const
399 sal_uInt8* pData = GetData();
401 if( pData )
403 rOStm.Write( pData, mnDataSize );
404 delete[] pData;
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */