summaryrefslogtreecommitdiff
path: root/sfx2/source/doc/graphhelp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/doc/graphhelp.cxx')
-rw-r--r--sfx2/source/doc/graphhelp.cxx529
1 files changed, 529 insertions, 0 deletions
diff --git a/sfx2/source/doc/graphhelp.cxx b/sfx2/source/doc/graphhelp.cxx
new file mode 100644
index 000000000000..388d85cefc25
--- /dev/null
+++ b/sfx2/source/doc/graphhelp.cxx
@@ -0,0 +1,529 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#ifdef WNT
+
+#undef WB_LEFT
+#undef WB_RIGHT
+
+#define UINT64 USE_WIN_UINT64
+#define INT64 USE_WIN_INT64
+#define UINT32 USE_WIN_UINT32
+#define INT32 USE_WIN_INT32
+
+#include <tools/presys.h>
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <tools/postsys.h>
+
+#undef UINT64
+#undef INT64
+#undef UINT32
+#undef INT32
+
+#endif
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/io/XStream.hpp>
+
+
+#include <osl/thread.h>
+#include <vcl/gdimtf.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/salbtype.hxx>
+
+#include <tools/stream.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/streamwrap.hxx>
+#include <comphelper/processfactory.hxx>
+
+
+#include "sfxresid.hxx"
+#include "graphhelp.hxx"
+#include "doc.hrc"
+
+using namespace ::com::sun::star;
+
+#define THUMBNAIL_RESOLUTION 256
+
+//---------------------------------------------------------------
+// static
+SvMemoryStream* GraphicHelper::getFormatStrFromGDI_Impl( const GDIMetaFile* pGDIMeta, sal_uInt32 nFormat )
+{
+ SvMemoryStream* pResult = NULL;
+ if ( pGDIMeta )
+ {
+ SvMemoryStream* pStream = new SvMemoryStream( 65535, 65535 );
+ if ( pStream )
+ {
+ Graphic aGraph( *pGDIMeta );
+ if ( GraphicConverter::Export( *pStream, aGraph, nFormat ) == 0 )
+ pResult = pStream;
+ else
+ delete pStream;
+ }
+ }
+
+ return pResult;
+}
+
+//---------------------------------------------------------------
+// static
+void* GraphicHelper::getEnhMetaFileFromGDI_Impl( const GDIMetaFile* pGDIMeta )
+{
+ (void)pGDIMeta; // unused
+ void* pResult = NULL;
+
+#ifdef WNT
+ if ( pGDIMeta )
+ {
+ String aStr = ::rtl::OUString::createFromAscii( ".emf" );
+ ::utl::TempFile aTempFile( ::rtl::OUString(),
+ &aStr,
+ NULL,
+ sal_False );
+
+ ::rtl::OUString aMetaFile = aTempFile.GetFileName();
+ ::rtl::OUString aMetaURL = aTempFile.GetURL();
+ ::rtl::OString aWinFile = ::rtl::OUStringToOString( aMetaFile, osl_getThreadTextEncoding() );
+
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMetaURL, STREAM_STD_READWRITE );
+ if ( pStream )
+ {
+ Graphic aGraph( *pGDIMeta );
+ sal_Bool bFailed = (sal_Bool)GraphicConverter::Export( *pStream, aGraph, CVT_EMF );
+ pStream->Flush();
+ delete pStream;
+
+ if ( !bFailed )
+ pResult = GetEnhMetaFileA( aWinFile.getStr() );
+ }
+ }
+#endif
+
+ return pResult;
+}
+
+//---------------------------------------------------------------
+// static
+void* GraphicHelper::getWinMetaFileFromGDI_Impl( const GDIMetaFile* pGDIMeta, const Size& aMetaSize )
+{
+ (void)pGDIMeta; // unused
+ (void)aMetaSize; // unused
+ void* pResult = NULL;
+
+#ifdef WNT
+ if ( pGDIMeta )
+ {
+ SvMemoryStream* pStream = new SvMemoryStream( 65535, 65535 );
+ if ( pStream )
+ {
+ Graphic aGraph( *pGDIMeta );
+ sal_Bool bFailed = (sal_Bool)GraphicConverter::Export( *pStream, aGraph, CVT_WMF );
+ pStream->Flush();
+ if ( !bFailed )
+ {
+ sal_Int32 nLength = pStream->Seek( STREAM_SEEK_TO_END );
+ if ( nLength > 22 )
+ {
+ HMETAFILE hMeta = SetMetaFileBitsEx( nLength - 22,
+ ( reinterpret_cast< const sal_uChar*>( pStream->GetData() ) ) + 22 );
+
+ if ( hMeta )
+ {
+ HGLOBAL hMemory = GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, sizeof( METAFILEPICT ) );
+
+ if ( hMemory )
+ {
+ METAFILEPICT* pMF = (METAFILEPICT*)GlobalLock( hMemory );
+
+ pMF->hMF = hMeta;
+ pMF->mm = MM_ANISOTROPIC;
+
+ MapMode aMetaMode = pGDIMeta->GetPrefMapMode();
+ MapMode aWinMode( MAP_100TH_MM );
+
+ if ( aWinMode == pGDIMeta->GetPrefMapMode() )
+ {
+ pMF->xExt = aMetaSize.Width();
+ pMF->yExt = aMetaSize.Height();
+ }
+ else
+ {
+ Size aWinSize = OutputDevice::LogicToLogic( Size( aMetaSize.Width(), aMetaSize.Height() ),
+ pGDIMeta->GetPrefMapMode(),
+ aWinMode );
+ pMF->xExt = aWinSize.Width();
+ pMF->yExt = aWinSize.Height();
+ }
+
+ GlobalUnlock( hMemory );
+ pResult = (void*)hMemory;
+ }
+ else
+ DeleteMetaFile( hMeta );
+ }
+ }
+ }
+
+ delete pStream;
+ }
+ }
+
+#endif
+
+
+ return pResult;
+}
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::supportsMetaFileHandle_Impl()
+{
+#ifdef WNT
+ return sal_True;
+#else
+ return sal_False;
+#endif
+}
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::mergeBitmaps_Impl( const BitmapEx& rBmpEx, const BitmapEx& rOverlay,
+ const Rectangle& rOverlayRect, BitmapEx& rReturn )
+{
+ // the implementation is provided by KA
+
+ Point aNullPt;
+ Rectangle aBmpRect( aNullPt, rBmpEx.GetSizePixel() );
+ VirtualDevice aVDev;
+
+ if( !rReturn.IsEmpty() )
+ rReturn.SetEmpty();
+
+ if( !rBmpEx.IsEmpty() && aVDev.SetOutputSizePixel( aBmpRect.GetSize() ) )
+ {
+ Rectangle aOverlayRect( rOverlayRect );
+
+ aOverlayRect.Intersection( aBmpRect );
+
+ if( rOverlay.IsEmpty() || rOverlayRect.IsEmpty() )
+ rReturn = rBmpEx;
+ else
+ {
+ aVDev.DrawBitmap( aNullPt, aVDev.GetOutputSizePixel(), rBmpEx.GetBitmap() );
+ aVDev.DrawBitmapEx( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), rOverlay );
+
+ Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
+ aBmp.Convert( BMP_CONVERSION_24BIT );
+
+ if( !rBmpEx.IsTransparent() )
+ rReturn = aBmp;
+ else
+ {
+ aVDev.DrawBitmap( aNullPt, aVDev.GetOutputSizePixel(), rBmpEx.GetMask() );
+ Bitmap aOverlayMergeBmp( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ) );
+
+ if( rOverlay.IsTransparent() )
+ aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), rOverlay.GetMask() );
+ else
+ {
+ aVDev.SetLineColor( COL_BLACK );
+ aVDev.SetFillColor( COL_BLACK );
+ aVDev.DrawRect( aOverlayRect);
+ }
+
+ aOverlayMergeBmp.CombineSimple( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ), BMP_COMBINE_AND );
+ aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), aOverlayMergeBmp );
+ rReturn = BitmapEx( aBmp, aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
+ }
+ }
+ }
+
+ return !rReturn.IsEmpty();
+}
+
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::createThumb_Impl( const GDIMetaFile& rMtf,
+ sal_uInt32 nMaximumExtent,
+ BitmapEx& rBmpEx,
+ const BitmapEx* pOverlay,
+ const Rectangle* pOverlayRect )
+{
+ // the implementation is provided by KA
+
+ // initialization seems to be complicated but is used to avoid rounding errors
+ VirtualDevice aVDev;
+ const Point aNullPt;
+ const Point aTLPix( aVDev.LogicToPixel( aNullPt, rMtf.GetPrefMapMode() ) );
+ const Point aBRPix( aVDev.LogicToPixel( Point( rMtf.GetPrefSize().Width() - 1, rMtf.GetPrefSize().Height() - 1 ), rMtf.GetPrefMapMode() ) );
+ Size aDrawSize( aVDev.LogicToPixel( rMtf.GetPrefSize(), rMtf.GetPrefMapMode() ) );
+ Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 );
+ Point aPosPix;
+
+ if ( !rBmpEx.IsEmpty() )
+ rBmpEx.SetEmpty();
+
+ // determine size that has the same aspect ratio as image size and
+ // fits into the rectangle determined by nMaximumExtent
+ if ( aSizePix.Width() && aSizePix.Height() &&
+ ( sal::static_int_cast<sal_uInt32>(aSizePix.Width()) > nMaximumExtent ||
+ sal::static_int_cast<sal_uInt32>(aSizePix.Height()) > nMaximumExtent ) )
+ {
+ const Size aOldSizePix( aSizePix );
+ double fWH = static_cast< double >( aSizePix.Width() ) / aSizePix.Height();
+
+ if ( fWH <= 1.0 )
+ {
+ aSizePix.Width() = FRound( nMaximumExtent * fWH );
+ aSizePix.Height() = nMaximumExtent;
+ }
+ else
+ {
+ aSizePix.Width() = nMaximumExtent;
+ aSizePix.Height() = FRound( nMaximumExtent / fWH );
+ }
+
+ aDrawSize.Width() = FRound( ( static_cast< double >( aDrawSize.Width() ) * aSizePix.Width() ) / aOldSizePix.Width() );
+ aDrawSize.Height() = FRound( ( static_cast< double >( aDrawSize.Height() ) * aSizePix.Height() ) / aOldSizePix.Height() );
+ }
+
+ Size aFullSize;
+ Point aBackPosPix;
+ Rectangle aOverlayRect;
+
+ // calculate addigtional positions and sizes if an overlay image is used
+ if ( pOverlay )
+ {
+ aFullSize = Size( nMaximumExtent, nMaximumExtent );
+ aOverlayRect = Rectangle( aNullPt, aFullSize );
+
+ aOverlayRect.Intersection( pOverlayRect ? *pOverlayRect : Rectangle( aNullPt, pOverlay->GetSizePixel() ) );
+
+ if ( !aOverlayRect.IsEmpty() )
+ aBackPosPix = Point( ( nMaximumExtent - aSizePix.Width() ) >> 1, ( nMaximumExtent - aSizePix.Height() ) >> 1 );
+ else
+ pOverlay = NULL;
+ }
+ else
+ {
+ aFullSize = aSizePix;
+ pOverlay = NULL;
+ }
+
+ // draw image(s) into VDev and get resulting image
+ if ( aVDev.SetOutputSizePixel( aFullSize ) )
+ {
+ // draw metafile into VDev
+ const_cast< GDIMetaFile& >( rMtf ).WindStart();
+ const_cast< GDIMetaFile& >( rMtf ).Play( &aVDev, aBackPosPix, aDrawSize );
+
+ // draw overlay if neccessary
+ if ( pOverlay )
+ aVDev.DrawBitmapEx( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), *pOverlay );
+
+ // get paint bitmap
+ Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
+
+ // assure that we have a true color image
+ if ( aBmp.GetBitCount() != 24 )
+ aBmp.Convert( BMP_CONVERSION_24BIT );
+
+ rBmpEx = BitmapEx( aBmp );
+ }
+
+ return !rBmpEx.IsEmpty();
+}
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::getThumbnailFormatFromGDI_Impl( GDIMetaFile* pMetaFile,
+ sal_Bool bSigned,
+ const uno::Reference< io::XStream >& xStream )
+{
+ sal_Bool bResult = sal_False;
+ SvStream* pStream = NULL;
+
+ if ( xStream.is() )
+ pStream = ::utl::UcbStreamHelper::CreateStream( xStream );
+
+ if ( pMetaFile && pStream && !pStream->GetError() )
+ {
+ BitmapEx aResultBitmap;
+ BitmapEx* pSignatureBitmap = NULL;
+
+ if ( bSigned )
+ pSignatureBitmap = new BitmapEx( SfxResId( BMP_SIGNATURE ) );
+
+ bResult = createThumb_Impl( *pMetaFile,
+ THUMBNAIL_RESOLUTION,
+ aResultBitmap,
+ pSignatureBitmap );
+ if ( bResult )
+ bResult = ( !aResultBitmap.IsEmpty()
+ && GraphicConverter::Export( *pStream, aResultBitmap, CVT_PNG ) == 0
+ && ( pStream->Flush(), !pStream->GetError() ) );
+
+ if ( pSignatureBitmap )
+ delete pSignatureBitmap;
+
+ delete pStream;
+ }
+
+ return bResult;
+}
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::getSignedThumbnailFormatFromBitmap_Impl( const BitmapEx& aBitmap,
+ const uno::Reference< io::XStream >& xStream )
+{
+ sal_Bool bResult = sal_False;
+ SvStream* pStream = NULL;
+
+ if ( xStream.is() )
+ pStream = ::utl::UcbStreamHelper::CreateStream( xStream );
+
+ if ( pStream && !pStream->GetError() )
+ {
+ BitmapEx aResultBitmap;
+ BitmapEx aSignatureBitmap( SfxResId( BMP_SIGNATURE ) );
+
+ bResult = mergeBitmaps_Impl( aBitmap,
+ aSignatureBitmap,
+ Rectangle( Point(), aBitmap.GetSizePixel() ),
+ aResultBitmap );
+
+ if ( bResult )
+ {
+ bResult = ( !aResultBitmap.IsEmpty()
+ && GraphicConverter::Export( *pStream, aResultBitmap, CVT_PNG ) == 0
+ && ( pStream->Flush(), !pStream->GetError() ) );
+ }
+
+ delete pStream;
+ }
+
+ return bResult;
+}
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::getThumbnailReplacement_Impl( sal_Int32 nResID, const uno::Reference< io::XStream >& xStream )
+{
+ sal_Bool bResult = sal_False;
+ if ( nResID && xStream.is() )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+ if ( xServiceManager.is() )
+ {
+ try
+ {
+ uno::Reference< graphic::XGraphicProvider > xGraphProvider(
+ xServiceManager->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ) ),
+ uno::UNO_QUERY );
+ if ( xGraphProvider.is() )
+ {
+ ::rtl::OUString aURL = ::rtl::OUString::createFromAscii( "private:resource/sfx/bitmapex/" );
+ aURL += ::rtl::OUString::valueOf( nResID );
+
+ uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
+ aMediaProps[0].Name = ::rtl::OUString::createFromAscii( "URL" );
+ aMediaProps[0].Value <<= aURL;
+
+ uno::Reference< graphic::XGraphic > xGraphic = xGraphProvider->queryGraphic( aMediaProps );
+ if ( xGraphic.is() )
+ {
+ uno::Sequence< beans::PropertyValue > aStoreProps( 2 );
+ aStoreProps[0].Name = ::rtl::OUString::createFromAscii( "OutputStream" );
+ aStoreProps[0].Value <<= xStream;
+ aStoreProps[1].Name = ::rtl::OUString::createFromAscii( "MimeType" );
+ aStoreProps[1].Value <<= ::rtl::OUString::createFromAscii( "image/png" );
+
+ xGraphProvider->storeGraphic( xGraphic, aStoreProps );
+ bResult = sal_True;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ return bResult;
+}
+
+//---------------------------------------------------------------
+// static
+sal_uInt16 GraphicHelper::getThumbnailReplacementIDByFactoryName_Impl( const ::rtl::OUString& aFactoryShortName, sal_Bool /*bIsTemplate*/ )
+{
+ sal_uInt16 nResult = 0;
+
+ if ( aFactoryShortName.equalsAscii( "scalc" ) )
+ {
+ nResult = BMP_128X128_CALC_DOC;
+ }
+ else if ( aFactoryShortName.equalsAscii( "sdraw" ) )
+ {
+ nResult = BMP_128X128_DRAW_DOC;
+ }
+ else if ( aFactoryShortName.equalsAscii( "simpress" ) )
+ {
+ nResult = BMP_128X128_IMPRESS_DOC;
+ }
+ else if ( aFactoryShortName.equalsAscii( "smath" ) )
+ {
+ nResult = BMP_128X128_MATH_DOC;
+ }
+ else if ( aFactoryShortName.equalsAscii( "swriter" ) || aFactoryShortName.compareToAscii( "swriter/", 8 ) == 0 )
+ {
+ nResult = BMP_128X128_WRITER_DOC;
+ }
+
+ return nResult;
+}
+