update emoji autocorrect entries from po-files
[LibreOffice.git] / vcl / source / gdi / gfxlink.cxx
blob75fd45c356edf15bc540f194743abfe295e942af
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 .
20 #include <osl/file.h>
21 #include <tools/vcompat.hxx>
22 #include <tools/debug.hxx>
23 #include <unotools/ucbstreamhelper.hxx>
24 #include <unotools/tempfile.hxx>
25 #include <ucbhelper/content.hxx>
26 #include <vcl/graph.hxx>
27 #include <vcl/gfxlink.hxx>
28 #include <vcl/cvtgrf.hxx>
29 #include <com/sun/star/ucb/CommandAbortedException.hpp>
30 #include <memory>
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, 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 bool GfxLink::IsEqual( const GfxLink& rGfxLink ) const
99 bool bIsEqual = 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 = 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++;
134 bool GfxLink::IsNative() const
136 return( meType >= GFX_LINK_FIRST_NATIVE_ID && meType <= GFX_LINK_LAST_NATIVE_ID );
140 const sal_uInt8* GfxLink::GetData() const
142 if( IsSwappedOut() )
143 const_cast<GfxLink*>(this)->SwapIn();
145 return( mpBuf ? mpBuf->mpBuffer : NULL );
149 void GfxLink::SetPrefSize( const Size& rPrefSize )
151 mpImpData->maPrefSize = rPrefSize;
152 mpImpData->mbPrefSizeValid = true;
157 void GfxLink::SetPrefMapMode( const MapMode& rPrefMapMode )
159 mpImpData->maPrefMapMode = rPrefMapMode;
160 mpImpData->mbPrefMapModeValid = true;
164 bool GfxLink::LoadNative( Graphic& rGraphic )
166 bool bRet = false;
168 if( IsNative() && mnBufSize )
170 const sal_uInt8* pData = GetData();
172 if( pData )
174 SvMemoryStream aMemStm;
175 sal_uLong nCvtType;
177 aMemStm.SetBuffer( const_cast<sal_uInt8*>(pData), mnBufSize, false, mnBufSize );
179 switch( meType )
181 case( GFX_LINK_TYPE_NATIVE_GIF ): nCvtType = CVT_GIF; break;
183 // #i15508# added BMP type for better exports (reload when swapped - checked, works)
184 case( GFX_LINK_TYPE_NATIVE_BMP ): nCvtType = CVT_BMP; break;
186 case( GFX_LINK_TYPE_NATIVE_JPG ): nCvtType = CVT_JPG; break;
187 case( GFX_LINK_TYPE_NATIVE_PNG ): nCvtType = CVT_PNG; break;
188 case( GFX_LINK_TYPE_NATIVE_TIF ): nCvtType = CVT_TIF; break;
189 case( GFX_LINK_TYPE_NATIVE_WMF ): nCvtType = CVT_WMF; break;
190 case( GFX_LINK_TYPE_NATIVE_MET ): nCvtType = CVT_MET; break;
191 case( GFX_LINK_TYPE_NATIVE_PCT ): nCvtType = CVT_PCT; break;
192 case( GFX_LINK_TYPE_NATIVE_SVG ): nCvtType = CVT_SVG; break;
194 default: nCvtType = CVT_UNKNOWN; break;
197 if( nCvtType && ( GraphicConverter::Import( aMemStm, rGraphic, nCvtType ) == ERRCODE_NONE ) )
198 bRet = true;
202 return bRet;
205 void GfxLink::SwapOut()
207 if( !IsSwappedOut() && mpBuf )
209 mpSwap = new ImpSwap( mpBuf->mpBuffer, mnBufSize );
211 if( !mpSwap->IsSwapped() )
213 delete mpSwap;
214 mpSwap = NULL;
216 else
218 if( !( --mpBuf->mnRefCount ) )
219 delete mpBuf;
221 mpBuf = NULL;
226 void GfxLink::SwapIn()
228 if( IsSwappedOut() )
230 mpBuf = new ImpBuffer( mpSwap->GetData() );
232 if( !( --mpSwap->mnRefCount ) )
233 delete mpSwap;
235 mpSwap = NULL;
239 bool GfxLink::ExportNative( SvStream& rOStream ) const
241 if( GetDataSize() )
243 if( IsSwappedOut() )
244 mpSwap->WriteTo( rOStream );
245 else if( GetData() )
246 rOStream.Write( GetData(), GetDataSize() );
249 return ( rOStream.GetError() == ERRCODE_NONE );
252 SvStream& WriteGfxLink( SvStream& rOStream, const GfxLink& rGfxLink )
254 VersionCompat* pCompat = new VersionCompat( rOStream, StreamMode::WRITE, 2 );
256 // Version 1
257 rOStream.WriteUInt16( rGfxLink.GetType() ).WriteUInt32( rGfxLink.GetDataSize() ).WriteUInt32( rGfxLink.GetUserId() );
259 // Version 2
260 WritePair( rOStream, rGfxLink.GetPrefSize() );
261 WriteMapMode( rOStream, rGfxLink.GetPrefMapMode() );
263 delete pCompat;
265 if( rGfxLink.GetDataSize() )
267 if( rGfxLink.IsSwappedOut() )
268 rGfxLink.mpSwap->WriteTo( rOStream );
269 else if( rGfxLink.GetData() )
270 rOStream.Write( rGfxLink.GetData(), rGfxLink.GetDataSize() );
273 return rOStream;
276 SvStream& ReadGfxLink( SvStream& rIStream, GfxLink& rGfxLink)
278 Size aSize;
279 MapMode aMapMode;
280 sal_uInt32 nSize;
281 sal_uInt32 nUserId;
282 sal_uInt16 nType;
283 sal_uInt8* pBuf;
284 bool bMapAndSizeValid( false );
285 VersionCompat* pCompat = new VersionCompat( rIStream, StreamMode::READ );
287 // Version 1
288 rIStream.ReadUInt16( nType ).ReadUInt32( nSize ).ReadUInt32( nUserId );
290 if( pCompat->GetVersion() >= 2 )
292 ReadPair( rIStream, aSize );
293 ReadMapMode( rIStream, aMapMode );
294 bMapAndSizeValid = true;
297 delete pCompat;
299 pBuf = new sal_uInt8[ nSize ];
300 rIStream.Read( pBuf, nSize );
302 rGfxLink = GfxLink( pBuf, nSize, (GfxLinkType) nType, true );
303 rGfxLink.SetUserId( nUserId );
305 if( bMapAndSizeValid )
307 rGfxLink.SetPrefSize( aSize );
308 rGfxLink.SetPrefMapMode( aMapMode );
311 return rIStream;
314 ImpSwap::ImpSwap( sal_uInt8* pData, sal_uLong nDataSize ) :
315 mnDataSize( nDataSize ),
316 mnRefCount( 1UL )
318 if( pData && mnDataSize )
320 ::utl::TempFile aTempFile;
322 maURL = aTempFile.GetURL();
323 if( !maURL.isEmpty() )
325 std::unique_ptr<SvStream> xOStm(::utl::UcbStreamHelper::CreateStream( maURL, STREAM_READWRITE | StreamMode::SHARE_DENYWRITE ));
326 if( xOStm )
328 xOStm->Write( pData, mnDataSize );
329 bool bError = ( ERRCODE_NONE != xOStm->GetError() );
330 xOStm.reset();
332 if( bError )
334 osl_removeFile( maURL.pData );
335 maURL.clear();
342 ImpSwap::~ImpSwap()
344 if( IsSwapped() )
345 osl_removeFile( maURL.pData );
348 sal_uInt8* ImpSwap::GetData() const
350 sal_uInt8* pData;
352 if( IsSwapped() )
354 std::unique_ptr<SvStream> xIStm(::utl::UcbStreamHelper::CreateStream( maURL, STREAM_READWRITE ));
355 if( xIStm )
357 pData = new sal_uInt8[ mnDataSize ];
358 xIStm->Read( pData, mnDataSize );
359 bool bError = ( ERRCODE_NONE != xIStm->GetError() );
360 sal_Size nActReadSize = xIStm->Tell();
361 if (nActReadSize != mnDataSize)
363 bError = true;
365 xIStm.reset();
367 if( bError )
368 delete[] pData, pData = NULL;
370 else
371 pData = NULL;
373 else
374 pData = NULL;
376 return pData;
379 void ImpSwap::WriteTo( SvStream& rOStm ) const
381 sal_uInt8* pData = GetData();
383 if( pData )
385 rOStm.Write( pData, mnDataSize );
386 delete[] pData;
390 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */