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