update dev300-m58
[ooovba.git] / sfx2 / source / doc / graphhelp.cxx
blobe531af74f359d0b5a3a7bbcf8e60e5b3c2e7dab0
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: graphhelp.cxx,v $
10 * $Revision: 1.12 $
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_sfx2.hxx"
34 #ifdef WNT
36 #undef WB_LEFT
37 #undef WB_RIGHT
39 #define UINT64 USE_WIN_UINT64
40 #define INT64 USE_WIN_INT64
41 #define UINT32 USE_WIN_UINT32
42 #define INT32 USE_WIN_INT32
44 #include <tools/presys.h>
45 #if defined _MSC_VER
46 #pragma warning(push, 1)
47 #endif
48 #include <windows.h>
49 #if defined _MSC_VER
50 #pragma warning(pop)
51 #endif
52 #include <tools/postsys.h>
54 #undef UINT64
55 #undef INT64
56 #undef UINT32
57 #undef INT32
59 #endif
60 #include <com/sun/star/uno/Exception.hpp>
61 #include <com/sun/star/datatransfer/XTransferable.hpp>
62 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
63 #include <com/sun/star/graphic/XGraphicProvider.hpp>
64 #include <com/sun/star/graphic/XGraphic.hpp>
65 #include <com/sun/star/io/XStream.hpp>
68 #include <osl/thread.h>
69 #include <vcl/gdimtf.hxx>
70 #include <vcl/graph.hxx>
71 #include <vcl/cvtgrf.hxx>
72 #include <vcl/outdev.hxx>
73 #include <vcl/virdev.hxx>
74 #include <vcl/bitmapex.hxx>
75 #include <vcl/salbtype.hxx>
77 #include <tools/stream.hxx>
78 #include <unotools/tempfile.hxx>
79 #include <unotools/ucbstreamhelper.hxx>
80 #include <unotools/streamwrap.hxx>
81 #include <comphelper/processfactory.hxx>
84 #include "sfxresid.hxx"
85 #include "graphhelp.hxx"
86 #include "doc.hrc"
88 using namespace ::com::sun::star;
90 #define THUMBNAIL_RESOLUTION 256
92 //---------------------------------------------------------------
93 // static
94 SvMemoryStream* GraphicHelper::getFormatStrFromGDI_Impl( const GDIMetaFile* pGDIMeta, sal_uInt32 nFormat )
96 SvMemoryStream* pResult = NULL;
97 if ( pGDIMeta )
99 SvMemoryStream* pStream = new SvMemoryStream( 65535, 65535 );
100 if ( pStream )
102 Graphic aGraph( *pGDIMeta );
103 if ( GraphicConverter::Export( *pStream, aGraph, nFormat ) == 0 )
104 pResult = pStream;
105 else
106 delete pStream;
110 return pResult;
113 //---------------------------------------------------------------
114 // static
115 void* GraphicHelper::getEnhMetaFileFromGDI_Impl( const GDIMetaFile* pGDIMeta )
117 (void)pGDIMeta; // unused
118 void* pResult = NULL;
120 #ifdef WNT
121 if ( pGDIMeta )
123 String aStr = ::rtl::OUString::createFromAscii( ".emf" );
124 ::utl::TempFile aTempFile( ::rtl::OUString(),
125 &aStr,
126 NULL,
127 sal_False );
129 ::rtl::OUString aMetaFile = aTempFile.GetFileName();
130 ::rtl::OUString aMetaURL = aTempFile.GetURL();
131 ::rtl::OString aWinFile = ::rtl::OUStringToOString( aMetaFile, osl_getThreadTextEncoding() );
133 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMetaURL, STREAM_STD_READWRITE );
134 if ( pStream )
136 Graphic aGraph( *pGDIMeta );
137 sal_Bool bFailed = (sal_Bool)GraphicConverter::Export( *pStream, aGraph, CVT_EMF );
138 pStream->Flush();
139 delete pStream;
141 if ( !bFailed )
142 pResult = GetEnhMetaFileA( aWinFile.getStr() );
145 #endif
147 return pResult;
150 //---------------------------------------------------------------
151 // static
152 void* GraphicHelper::getWinMetaFileFromGDI_Impl( const GDIMetaFile* pGDIMeta, const Size& aMetaSize )
154 (void)pGDIMeta; // unused
155 (void)aMetaSize; // unused
156 void* pResult = NULL;
158 #ifdef WNT
159 if ( pGDIMeta )
161 SvMemoryStream* pStream = new SvMemoryStream( 65535, 65535 );
162 if ( pStream )
164 Graphic aGraph( *pGDIMeta );
165 sal_Bool bFailed = (sal_Bool)GraphicConverter::Export( *pStream, aGraph, CVT_WMF );
166 pStream->Flush();
167 if ( !bFailed )
169 sal_Int32 nLength = pStream->Seek( STREAM_SEEK_TO_END );
170 if ( nLength > 22 )
172 HMETAFILE hMeta = SetMetaFileBitsEx( nLength - 22,
173 ( reinterpret_cast< const sal_uChar*>( pStream->GetData() ) ) + 22 );
175 if ( hMeta )
177 HGLOBAL hMemory = GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, sizeof( METAFILEPICT ) );
179 if ( hMemory )
181 METAFILEPICT* pMF = (METAFILEPICT*)GlobalLock( hMemory );
183 pMF->hMF = hMeta;
184 pMF->mm = MM_ANISOTROPIC;
186 MapMode aMetaMode = pGDIMeta->GetPrefMapMode();
187 MapMode aWinMode( MAP_100TH_MM );
189 if ( aWinMode == pGDIMeta->GetPrefMapMode() )
191 pMF->xExt = aMetaSize.Width();
192 pMF->yExt = aMetaSize.Height();
194 else
196 Size aWinSize = OutputDevice::LogicToLogic( Size( aMetaSize.Width(), aMetaSize.Height() ),
197 pGDIMeta->GetPrefMapMode(),
198 aWinMode );
199 pMF->xExt = aWinSize.Width();
200 pMF->yExt = aWinSize.Height();
203 GlobalUnlock( hMemory );
204 pResult = (void*)hMemory;
206 else
207 DeleteMetaFile( hMeta );
212 delete pStream;
216 #endif
219 return pResult;
222 //---------------------------------------------------------------
223 // static
224 sal_Bool GraphicHelper::supportsMetaFileHandle_Impl()
226 #ifdef WNT
227 return sal_True;
228 #else
229 return sal_False;
230 #endif
233 //---------------------------------------------------------------
234 // static
235 sal_Bool GraphicHelper::mergeBitmaps_Impl( const BitmapEx& rBmpEx, const BitmapEx& rOverlay,
236 const Rectangle& rOverlayRect, BitmapEx& rReturn )
238 // the implementation is provided by KA
240 Point aNullPt;
241 Rectangle aBmpRect( aNullPt, rBmpEx.GetSizePixel() );
242 VirtualDevice aVDev;
244 if( !rReturn.IsEmpty() )
245 rReturn.SetEmpty();
247 if( !rBmpEx.IsEmpty() && aVDev.SetOutputSizePixel( aBmpRect.GetSize() ) )
249 Rectangle aOverlayRect( rOverlayRect );
251 aOverlayRect.Intersection( aBmpRect );
253 if( rOverlay.IsEmpty() || rOverlayRect.IsEmpty() )
254 rReturn = rBmpEx;
255 else
257 aVDev.DrawBitmap( aNullPt, aVDev.GetOutputSizePixel(), rBmpEx.GetBitmap() );
258 aVDev.DrawBitmapEx( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), rOverlay );
260 Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
261 aBmp.Convert( BMP_CONVERSION_24BIT );
263 if( !rBmpEx.IsTransparent() )
264 rReturn = aBmp;
265 else
267 aVDev.DrawBitmap( aNullPt, aVDev.GetOutputSizePixel(), rBmpEx.GetMask() );
268 Bitmap aOverlayMergeBmp( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ) );
270 if( rOverlay.IsTransparent() )
271 aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), rOverlay.GetMask() );
272 else
274 aVDev.SetLineColor( COL_BLACK );
275 aVDev.SetFillColor( COL_BLACK );
276 aVDev.DrawRect( aOverlayRect);
279 aOverlayMergeBmp.CombineSimple( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ), BMP_COMBINE_AND );
280 aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), aOverlayMergeBmp );
281 rReturn = BitmapEx( aBmp, aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
286 return !rReturn.IsEmpty();
290 //---------------------------------------------------------------
291 // static
292 sal_Bool GraphicHelper::createThumb_Impl( const GDIMetaFile& rMtf,
293 sal_uInt32 nMaximumExtent,
294 BitmapEx& rBmpEx,
295 const BitmapEx* pOverlay,
296 const Rectangle* pOverlayRect )
298 // the implementation is provided by KA
300 // initialization seems to be complicated but is used to avoid rounding errors
301 VirtualDevice aVDev;
302 const Point aNullPt;
303 const Point aTLPix( aVDev.LogicToPixel( aNullPt, rMtf.GetPrefMapMode() ) );
304 const Point aBRPix( aVDev.LogicToPixel( Point( rMtf.GetPrefSize().Width() - 1, rMtf.GetPrefSize().Height() - 1 ), rMtf.GetPrefMapMode() ) );
305 Size aDrawSize( aVDev.LogicToPixel( rMtf.GetPrefSize(), rMtf.GetPrefMapMode() ) );
306 Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 );
307 Point aPosPix;
309 if ( !rBmpEx.IsEmpty() )
310 rBmpEx.SetEmpty();
312 // determine size that has the same aspect ratio as image size and
313 // fits into the rectangle determined by nMaximumExtent
314 if ( aSizePix.Width() && aSizePix.Height() &&
315 ( sal::static_int_cast<sal_uInt32>(aSizePix.Width()) > nMaximumExtent ||
316 sal::static_int_cast<sal_uInt32>(aSizePix.Height()) > nMaximumExtent ) )
318 const Size aOldSizePix( aSizePix );
319 double fWH = static_cast< double >( aSizePix.Width() ) / aSizePix.Height();
321 if ( fWH <= 1.0 )
323 aSizePix.Width() = FRound( nMaximumExtent * fWH );
324 aSizePix.Height() = nMaximumExtent;
326 else
328 aSizePix.Width() = nMaximumExtent;
329 aSizePix.Height() = FRound( nMaximumExtent / fWH );
332 aDrawSize.Width() = FRound( ( static_cast< double >( aDrawSize.Width() ) * aSizePix.Width() ) / aOldSizePix.Width() );
333 aDrawSize.Height() = FRound( ( static_cast< double >( aDrawSize.Height() ) * aSizePix.Height() ) / aOldSizePix.Height() );
336 Size aFullSize;
337 Point aBackPosPix;
338 Rectangle aOverlayRect;
340 // calculate addigtional positions and sizes if an overlay image is used
341 if ( pOverlay )
343 aFullSize = Size( nMaximumExtent, nMaximumExtent );
344 aOverlayRect = Rectangle( aNullPt, aFullSize );
346 aOverlayRect.Intersection( pOverlayRect ? *pOverlayRect : Rectangle( aNullPt, pOverlay->GetSizePixel() ) );
348 if ( !aOverlayRect.IsEmpty() )
349 aBackPosPix = Point( ( nMaximumExtent - aSizePix.Width() ) >> 1, ( nMaximumExtent - aSizePix.Height() ) >> 1 );
350 else
351 pOverlay = NULL;
353 else
355 aFullSize = aSizePix;
356 pOverlay = NULL;
359 // draw image(s) into VDev and get resulting image
360 if ( aVDev.SetOutputSizePixel( aFullSize ) )
362 // draw metafile into VDev
363 const_cast< GDIMetaFile& >( rMtf ).WindStart();
364 const_cast< GDIMetaFile& >( rMtf ).Play( &aVDev, aBackPosPix, aDrawSize );
366 // draw overlay if neccessary
367 if ( pOverlay )
368 aVDev.DrawBitmapEx( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), *pOverlay );
370 // get paint bitmap
371 Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
373 // assure that we have a true color image
374 if ( aBmp.GetBitCount() != 24 )
375 aBmp.Convert( BMP_CONVERSION_24BIT );
377 // create resulting mask bitmap with metafile output set to black
378 GDIMetaFile aMonchromeMtf( rMtf.GetMonochromeMtf( COL_BLACK ) );
379 aVDev.DrawWallpaper( Rectangle( aNullPt, aSizePix ), Wallpaper( Color( COL_WHITE ) ) );
380 aMonchromeMtf.WindStart();
381 aMonchromeMtf.Play( &aVDev, aBackPosPix, aDrawSize );
383 // watch for overlay mask
384 if ( pOverlay )
386 Bitmap aOverlayMergeBmp( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ) );
388 // create ANDed resulting mask at overlay area
389 if ( pOverlay->IsTransparent() )
390 aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), pOverlay->GetMask() );
391 else
393 aVDev.SetLineColor( COL_BLACK );
394 aVDev.SetFillColor( COL_BLACK );
395 aVDev.DrawRect( aOverlayRect);
398 aOverlayMergeBmp.CombineSimple( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ), BMP_COMBINE_AND );
399 aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), aOverlayMergeBmp );
402 rBmpEx = BitmapEx( aBmp, aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
405 return !rBmpEx.IsEmpty();
408 //---------------------------------------------------------------
409 // static
410 sal_Bool GraphicHelper::getThumbnailFormatFromGDI_Impl( GDIMetaFile* pMetaFile,
411 sal_Bool bSigned,
412 const uno::Reference< io::XStream >& xStream )
414 sal_Bool bResult = sal_False;
415 SvStream* pStream = NULL;
417 if ( xStream.is() )
418 pStream = ::utl::UcbStreamHelper::CreateStream( xStream );
420 if ( pMetaFile && pStream && !pStream->GetError() )
422 BitmapEx aResultBitmap;
423 BitmapEx* pSignatureBitmap = NULL;
425 if ( bSigned )
426 pSignatureBitmap = new BitmapEx( SfxResId( BMP_SIGNATURE ) );
428 bResult = createThumb_Impl( *pMetaFile,
429 THUMBNAIL_RESOLUTION,
430 aResultBitmap,
431 pSignatureBitmap );
432 if ( bResult )
433 bResult = ( !aResultBitmap.IsEmpty()
434 && GraphicConverter::Export( *pStream, aResultBitmap, CVT_PNG ) == 0
435 && ( pStream->Flush(), !pStream->GetError() ) );
437 if ( pSignatureBitmap )
438 delete pSignatureBitmap;
440 delete pStream;
443 return bResult;
446 //---------------------------------------------------------------
447 // static
448 sal_Bool GraphicHelper::getSignedThumbnailFormatFromBitmap_Impl( const BitmapEx& aBitmap,
449 const uno::Reference< io::XStream >& xStream )
451 sal_Bool bResult = sal_False;
452 SvStream* pStream = NULL;
454 if ( xStream.is() )
455 pStream = ::utl::UcbStreamHelper::CreateStream( xStream );
457 if ( pStream && !pStream->GetError() )
459 BitmapEx aResultBitmap;
460 BitmapEx aSignatureBitmap( SfxResId( BMP_SIGNATURE ) );
462 bResult = mergeBitmaps_Impl( aBitmap,
463 aSignatureBitmap,
464 Rectangle( Point(), aBitmap.GetSizePixel() ),
465 aResultBitmap );
467 if ( bResult )
469 bResult = ( !aResultBitmap.IsEmpty()
470 && GraphicConverter::Export( *pStream, aResultBitmap, CVT_PNG ) == 0
471 && ( pStream->Flush(), !pStream->GetError() ) );
474 delete pStream;
477 return bResult;
480 //---------------------------------------------------------------
481 // static
482 sal_Bool GraphicHelper::getThumbnailReplacement_Impl( sal_Int32 nResID, const uno::Reference< io::XStream >& xStream )
484 sal_Bool bResult = sal_False;
485 if ( nResID && xStream.is() )
487 uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
488 if ( xServiceManager.is() )
492 uno::Reference< graphic::XGraphicProvider > xGraphProvider(
493 xServiceManager->createInstance(
494 ::rtl::OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ) ),
495 uno::UNO_QUERY );
496 if ( xGraphProvider.is() )
498 ::rtl::OUString aURL = ::rtl::OUString::createFromAscii( "private:resource/sfx/bitmapex/" );
499 aURL += ::rtl::OUString::valueOf( nResID );
501 uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
502 aMediaProps[0].Name = ::rtl::OUString::createFromAscii( "URL" );
503 aMediaProps[0].Value <<= aURL;
505 uno::Reference< graphic::XGraphic > xGraphic = xGraphProvider->queryGraphic( aMediaProps );
506 if ( xGraphic.is() )
508 uno::Sequence< beans::PropertyValue > aStoreProps( 2 );
509 aStoreProps[0].Name = ::rtl::OUString::createFromAscii( "OutputStream" );
510 aStoreProps[0].Value <<= xStream;
511 aStoreProps[1].Name = ::rtl::OUString::createFromAscii( "MimeType" );
512 aStoreProps[1].Value <<= ::rtl::OUString::createFromAscii( "image/png" );
514 xGraphProvider->storeGraphic( xGraphic, aStoreProps );
515 bResult = sal_True;
519 catch( uno::Exception& )
525 return bResult;
528 //---------------------------------------------------------------
529 // static
530 sal_uInt16 GraphicHelper::getThumbnailReplacementIDByFactoryName_Impl( const ::rtl::OUString& aFactoryShortName, sal_Bool /*bIsTemplate*/ )
532 sal_uInt16 nResult = 0;
534 if ( aFactoryShortName.equalsAscii( "scalc" ) )
536 nResult = BMP_128X128_CALC_DOC;
538 else if ( aFactoryShortName.equalsAscii( "sdraw" ) )
540 nResult = BMP_128X128_DRAW_DOC;
542 else if ( aFactoryShortName.equalsAscii( "simpress" ) )
544 nResult = BMP_128X128_IMPRESS_DOC;
546 else if ( aFactoryShortName.equalsAscii( "smath" ) )
548 nResult = BMP_128X128_MATH_DOC;
550 else if ( aFactoryShortName.equalsAscii( "swriter" ) || aFactoryShortName.compareToAscii( "swriter/", 8 ) == 0 )
552 nResult = BMP_128X128_WRITER_DOC;
555 return nResult;