1*25ea7f45SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*25ea7f45SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*25ea7f45SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*25ea7f45SAndrew Rist * distributed with this work for additional information 6*25ea7f45SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*25ea7f45SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*25ea7f45SAndrew Rist * "License"); you may not use this file except in compliance 9*25ea7f45SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*25ea7f45SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*25ea7f45SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*25ea7f45SAndrew Rist * software distributed under the License is distributed on an 15*25ea7f45SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*25ea7f45SAndrew Rist * KIND, either express or implied. See the License for the 17*25ea7f45SAndrew Rist * specific language governing permissions and limitations 18*25ea7f45SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*25ea7f45SAndrew Rist *************************************************************/ 21*25ea7f45SAndrew Rist 22*25ea7f45SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_canvas.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <ctype.h> // don't ask. msdev breaks otherwise... 28cdf0e10cSrcweir #include <canvas/debug.hxx> 29cdf0e10cSrcweir #include <canvas/verbosetrace.hxx> 30cdf0e10cSrcweir #include <canvas/canvastools.hxx> 31cdf0e10cSrcweir #include <tools/diagnose_ex.h> 32cdf0e10cSrcweir 33cdf0e10cSrcweir #include <osl/mutex.hxx> 34cdf0e10cSrcweir 35cdf0e10cSrcweir #include <com/sun/star/awt/XWindow.hpp> 36cdf0e10cSrcweir #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp> 37cdf0e10cSrcweir #include <com/sun/star/registry/XRegistryKey.hpp> 38cdf0e10cSrcweir #include <com/sun/star/lang/XSingleServiceFactory.hpp> 39cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp> 40cdf0e10cSrcweir #include <com/sun/star/lang/NoSupportException.hpp> 41cdf0e10cSrcweir 42cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx> 43cdf0e10cSrcweir #include <cppuhelper/factory.hxx> 44cdf0e10cSrcweir #include <cppuhelper/implementationentry.hxx> 45cdf0e10cSrcweir #include <comphelper/servicedecl.hxx> 46cdf0e10cSrcweir 47cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx> 48cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx> 49cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx> 50cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx> 51cdf0e10cSrcweir 52cdf0e10cSrcweir #include "dx_graphicsprovider.hxx" 53cdf0e10cSrcweir #include "dx_winstuff.hxx" 54cdf0e10cSrcweir #include "dx_canvas.hxx" 55cdf0e10cSrcweir 56cdf0e10cSrcweir #include <vcl/sysdata.hxx> 57cdf0e10cSrcweir 58cdf0e10cSrcweir #define CANVAS_TECH "GDI+" 59cdf0e10cSrcweir #define CANVAS_SERVICE_NAME "com.sun.star.rendering.Canvas." CANVAS_TECH 60cdf0e10cSrcweir #define CANVAS_IMPLEMENTATION_NAME "com.sun.star.comp.rendering.Canvas." CANVAS_TECH 61cdf0e10cSrcweir #define BITMAPCANVAS_SERVICE_NAME "com.sun.star.rendering.BitmapCanvas." CANVAS_TECH 62cdf0e10cSrcweir #define BITMAPCANVAS_IMPLEMENTATION_NAME "com.sun.star.comp.rendering.BitmapCanvas." CANVAS_TECH 63cdf0e10cSrcweir 64cdf0e10cSrcweir 65cdf0e10cSrcweir using namespace ::com::sun::star; 66cdf0e10cSrcweir 67cdf0e10cSrcweir namespace dxcanvas 68cdf0e10cSrcweir { 69cdf0e10cSrcweir /// Actual canonical implementation of the GraphicsProvider interface 70cdf0e10cSrcweir class GraphicsProviderImpl : public GraphicsProvider 71cdf0e10cSrcweir { 72cdf0e10cSrcweir GraphicsSharedPtr mpGraphics; 73cdf0e10cSrcweir public: GraphicsProviderImpl(Gdiplus::Graphics * pGraphics)74cdf0e10cSrcweir explicit GraphicsProviderImpl( Gdiplus::Graphics* pGraphics ) : mpGraphics( pGraphics ) {} getGraphics()75cdf0e10cSrcweir virtual GraphicsSharedPtr getGraphics() { return mpGraphics; } 76cdf0e10cSrcweir }; 77cdf0e10cSrcweir Canvas(const uno::Sequence<uno::Any> & aArguments,const uno::Reference<uno::XComponentContext> & rxContext)78cdf0e10cSrcweir Canvas::Canvas( const uno::Sequence< uno::Any >& aArguments, 79cdf0e10cSrcweir const uno::Reference< uno::XComponentContext >& rxContext ) : 80cdf0e10cSrcweir maArguments(aArguments), 81cdf0e10cSrcweir mxComponentContext( rxContext ) 82cdf0e10cSrcweir { 83cdf0e10cSrcweir } 84cdf0e10cSrcweir initialize()85cdf0e10cSrcweir void Canvas::initialize() 86cdf0e10cSrcweir { 87cdf0e10cSrcweir // #i64742# Only perform initialization when not in probe mode 88cdf0e10cSrcweir if( maArguments.getLength() == 0 ) 89cdf0e10cSrcweir return; 90cdf0e10cSrcweir 91cdf0e10cSrcweir VERBOSE_TRACE( "Canvas::initialize called" ); 92cdf0e10cSrcweir 93cdf0e10cSrcweir // At index 1, we expect a HWND handle here, containing a 94cdf0e10cSrcweir // pointer to a valid window, on which to output 95cdf0e10cSrcweir // At index 2, we expect the current window bound rect 96cdf0e10cSrcweir ENSURE_ARG_OR_THROW( maArguments.getLength() >= 6 && 97cdf0e10cSrcweir maArguments[5].getValueTypeClass() == uno::TypeClass_SEQUENCE, 98cdf0e10cSrcweir "SpriteCanvas::initialize: wrong number of arguments, or wrong types" ); 99cdf0e10cSrcweir 100cdf0e10cSrcweir uno::Sequence<sal_Int8> aSeq; 101cdf0e10cSrcweir maArguments[5] >>= aSeq; 102cdf0e10cSrcweir 103cdf0e10cSrcweir const SystemGraphicsData* pSysData=reinterpret_cast<const SystemGraphicsData*>(aSeq.getConstArray()); 104cdf0e10cSrcweir if( !pSysData || !pSysData->hDC ) 105cdf0e10cSrcweir throw lang::NoSupportException( 106cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 107cdf0e10cSrcweir "Passed SystemGraphicsData or HDC invalid!")), 108cdf0e10cSrcweir NULL); 109cdf0e10cSrcweir 110cdf0e10cSrcweir // setup helper 111cdf0e10cSrcweir maDeviceHelper.init( pSysData->hDC, 112cdf0e10cSrcweir *this ); 113cdf0e10cSrcweir maCanvasHelper.setDevice( *this ); 114cdf0e10cSrcweir maCanvasHelper.setTarget( 115cdf0e10cSrcweir GraphicsProviderSharedPtr( 116cdf0e10cSrcweir new GraphicsProviderImpl( 117cdf0e10cSrcweir Gdiplus::Graphics::FromHDC(pSysData->hDC)))); 118cdf0e10cSrcweir 119cdf0e10cSrcweir maArguments.realloc(0); 120cdf0e10cSrcweir } 121cdf0e10cSrcweir disposing()122cdf0e10cSrcweir void SAL_CALL Canvas::disposing() 123cdf0e10cSrcweir { 124cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 125cdf0e10cSrcweir 126cdf0e10cSrcweir mxComponentContext.clear(); 127cdf0e10cSrcweir 128cdf0e10cSrcweir // forward to parent 129cdf0e10cSrcweir CanvasBaseT::disposing(); 130cdf0e10cSrcweir } 131cdf0e10cSrcweir getServiceName()132cdf0e10cSrcweir ::rtl::OUString SAL_CALL Canvas::getServiceName( ) throw (uno::RuntimeException) 133cdf0e10cSrcweir { 134cdf0e10cSrcweir return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CANVAS_SERVICE_NAME ) ); 135cdf0e10cSrcweir } 136cdf0e10cSrcweir BitmapCanvas(const uno::Sequence<uno::Any> & aArguments,const uno::Reference<uno::XComponentContext> & rxContext)137cdf0e10cSrcweir BitmapCanvas::BitmapCanvas( const uno::Sequence< uno::Any >& aArguments, 138cdf0e10cSrcweir const uno::Reference< uno::XComponentContext >& rxContext ) : 139cdf0e10cSrcweir maArguments(aArguments), 140cdf0e10cSrcweir mxComponentContext( rxContext ), 141cdf0e10cSrcweir mpTarget() 142cdf0e10cSrcweir { 143cdf0e10cSrcweir } 144cdf0e10cSrcweir initialize()145cdf0e10cSrcweir void BitmapCanvas::initialize() 146cdf0e10cSrcweir { 147cdf0e10cSrcweir // #i64742# Only perform initialization when not in probe mode 148cdf0e10cSrcweir if( maArguments.getLength() == 0 ) 149cdf0e10cSrcweir return; 150cdf0e10cSrcweir 151cdf0e10cSrcweir VERBOSE_TRACE( "BitmapCanvas::initialize called" ); 152cdf0e10cSrcweir 153cdf0e10cSrcweir // At index 1, we expect a HWND handle here, containing a 154cdf0e10cSrcweir // pointer to a valid window, on which to output 155cdf0e10cSrcweir // At index 2, we expect the current window bound rect 156cdf0e10cSrcweir ENSURE_ARG_OR_THROW( maArguments.getLength() >= 6 && 157cdf0e10cSrcweir maArguments[5].getValueTypeClass() == uno::TypeClass_SEQUENCE, 158cdf0e10cSrcweir "SpriteCanvas::initialize: wrong number of arguments, or wrong types" ); 159cdf0e10cSrcweir 160cdf0e10cSrcweir uno::Sequence<sal_Int8> aSeq; 161cdf0e10cSrcweir maArguments[5] >>= aSeq; 162cdf0e10cSrcweir 163cdf0e10cSrcweir const SystemGraphicsData* pSysData=reinterpret_cast<const SystemGraphicsData*>(aSeq.getConstArray()); 164cdf0e10cSrcweir if( !pSysData || !pSysData->hDC ) 165cdf0e10cSrcweir throw lang::NoSupportException( 166cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 167cdf0e10cSrcweir "Passed SystemGraphicsData or HDC invalid!")), 168cdf0e10cSrcweir NULL); 169cdf0e10cSrcweir 170cdf0e10cSrcweir // setup helper 171cdf0e10cSrcweir maDeviceHelper.init( pSysData->hDC, 172cdf0e10cSrcweir *this ); 173cdf0e10cSrcweir maCanvasHelper.setDevice( *this ); 174cdf0e10cSrcweir 175cdf0e10cSrcweir // check whether we can actually provide a BitmapCanvas 176cdf0e10cSrcweir // here. for this, check whether the HDC has a bitmap 177cdf0e10cSrcweir // selected. 178cdf0e10cSrcweir HBITMAP hBmp; 179cdf0e10cSrcweir hBmp=(HBITMAP)GetCurrentObject(pSysData->hDC, OBJ_BITMAP); 180cdf0e10cSrcweir if( !hBmp || GetObjectType(pSysData->hDC) != OBJ_MEMDC ) 181cdf0e10cSrcweir { 182cdf0e10cSrcweir throw lang::NoSupportException( 183cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 184cdf0e10cSrcweir "Passed HDC is no mem DC/has no bitmap selected!")), 185cdf0e10cSrcweir NULL); 186cdf0e10cSrcweir } 187cdf0e10cSrcweir 188cdf0e10cSrcweir mpTarget.reset( new DXBitmap( 189cdf0e10cSrcweir BitmapSharedPtr( 190cdf0e10cSrcweir Gdiplus::Bitmap::FromHBITMAP( 191cdf0e10cSrcweir hBmp, 0) ), 192cdf0e10cSrcweir false )); 193cdf0e10cSrcweir 194cdf0e10cSrcweir maCanvasHelper.setTarget( mpTarget ); 195cdf0e10cSrcweir 196cdf0e10cSrcweir maArguments.realloc(0); 197cdf0e10cSrcweir } 198cdf0e10cSrcweir disposing()199cdf0e10cSrcweir void SAL_CALL BitmapCanvas::disposing() 200cdf0e10cSrcweir { 201cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 202cdf0e10cSrcweir 203cdf0e10cSrcweir mpTarget.reset(); 204cdf0e10cSrcweir mxComponentContext.clear(); 205cdf0e10cSrcweir 206cdf0e10cSrcweir // forward to parent 207cdf0e10cSrcweir BitmapCanvasBaseT::disposing(); 208cdf0e10cSrcweir } 209cdf0e10cSrcweir getServiceName()210cdf0e10cSrcweir ::rtl::OUString SAL_CALL BitmapCanvas::getServiceName( ) throw (uno::RuntimeException) 211cdf0e10cSrcweir { 212cdf0e10cSrcweir return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( BITMAPCANVAS_SERVICE_NAME ) ); 213cdf0e10cSrcweir } 214cdf0e10cSrcweir getBitmap() const215cdf0e10cSrcweir IBitmapSharedPtr BitmapCanvas::getBitmap() const 216cdf0e10cSrcweir { 217cdf0e10cSrcweir return mpTarget; 218cdf0e10cSrcweir } 219cdf0e10cSrcweir initCanvas(Canvas * pCanvas)220cdf0e10cSrcweir static uno::Reference<uno::XInterface> initCanvas( Canvas* pCanvas ) 221cdf0e10cSrcweir { 222cdf0e10cSrcweir uno::Reference<uno::XInterface> xRet(static_cast<cppu::OWeakObject*>(pCanvas)); 223cdf0e10cSrcweir pCanvas->initialize(); 224cdf0e10cSrcweir return xRet; 225cdf0e10cSrcweir } 226cdf0e10cSrcweir 227cdf0e10cSrcweir namespace sdecl = comphelper::service_decl; 228cdf0e10cSrcweir sdecl::class_<Canvas, sdecl::with_args<true> > serviceImpl1(&initCanvas); 229cdf0e10cSrcweir const sdecl::ServiceDecl dxCanvasDecl( 230cdf0e10cSrcweir serviceImpl1, 231cdf0e10cSrcweir CANVAS_IMPLEMENTATION_NAME, 232cdf0e10cSrcweir CANVAS_SERVICE_NAME ); 233cdf0e10cSrcweir initBitmapCanvas(BitmapCanvas * pCanvas)234cdf0e10cSrcweir static uno::Reference<uno::XInterface> initBitmapCanvas( BitmapCanvas* pCanvas ) 235cdf0e10cSrcweir { 236cdf0e10cSrcweir uno::Reference<uno::XInterface> xRet(static_cast<cppu::OWeakObject*>(pCanvas)); 237cdf0e10cSrcweir pCanvas->initialize(); 238cdf0e10cSrcweir return xRet; 239cdf0e10cSrcweir } 240cdf0e10cSrcweir 241cdf0e10cSrcweir namespace sdecl = comphelper::service_decl; 242cdf0e10cSrcweir sdecl::class_<BitmapCanvas, sdecl::with_args<true> > serviceImpl2(&initBitmapCanvas); 243cdf0e10cSrcweir const sdecl::ServiceDecl dxBitmapCanvasDecl( 244cdf0e10cSrcweir serviceImpl2, 245cdf0e10cSrcweir BITMAPCANVAS_IMPLEMENTATION_NAME, 246cdf0e10cSrcweir BITMAPCANVAS_SERVICE_NAME ); 247cdf0e10cSrcweir } 248cdf0e10cSrcweir 249cdf0e10cSrcweir // The C shared lib entry points 250cdf0e10cSrcweir COMPHELPER_SERVICEDECL_EXPORTS2(dxcanvas::dxCanvasDecl, 251cdf0e10cSrcweir dxcanvas::dxBitmapCanvasDecl); 252